Merge branch 'u-boot-samsung/master' into 'u-boot-arm/master'

Conflicts:
	spl/Makefile
This commit is contained in:
Albert ARIBAUD 2013-06-19 12:53:59 +02:00
commit 69f14dc2fd
42 changed files with 1360 additions and 471 deletions

View File

@ -22,7 +22,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).o
COBJS += clock.o power.o soc.o system.o pinmux.o
COBJS += clock.o power.o soc.o system.o pinmux.o tzpc.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))

View File

@ -116,10 +116,8 @@ static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
/* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */
fout = (m + k / 1024) * (freq / (p * (1 << s)));
} else {
if (s < 1)
s = 1;
/* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */
fout = m * (freq / (p * (1 << (s - 1))));
/* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
fout = m * (freq / (p * (1 << s)));
}
return fout;
@ -613,7 +611,7 @@ static unsigned long exynos4_get_mmc_clk(int dev_index)
(struct exynos4_clock *)samsung_get_base_clock();
unsigned long uclk, sclk;
unsigned int sel, ratio, pre_ratio;
int shift;
int shift = 0;
sel = readl(&clk->src_fsys);
sel = (sel >> (dev_index << 2)) & 0xf;
@ -662,7 +660,7 @@ static unsigned long exynos5_get_mmc_clk(int dev_index)
(struct exynos5_clock *)samsung_get_base_clock();
unsigned long uclk, sclk;
unsigned int sel, ratio, pre_ratio;
int shift;
int shift = 0;
sel = readl(&clk->src_fsys);
sel = (sel >> (dev_index << 2)) & 0xf;

View File

@ -22,27 +22,36 @@
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/arch/tzpc.h>
#include"setup.h"
#include <asm/io.h>
/* Setting TZPC[TrustZone Protection Controller] */
void tzpc_init(void)
{
struct exynos_tzpc *tzpc;
unsigned int addr;
unsigned int addr, start = 0, end = 0;
for (addr = TZPC0_BASE; addr <= TZPC9_BASE; addr += TZPC_BASE_OFFSET) {
start = samsung_get_base_tzpc();
if (cpu_is_exynos5())
end = start + ((EXYNOS5_NR_TZPC_BANKS - 1) * TZPC_BASE_OFFSET);
else if (cpu_is_exynos4())
end = start + ((EXYNOS4_NR_TZPC_BANKS - 1) * TZPC_BASE_OFFSET);
for (addr = start; addr <= end; addr += TZPC_BASE_OFFSET) {
tzpc = (struct exynos_tzpc *)addr;
if (addr == TZPC0_BASE)
if (addr == start)
writel(R0SIZE, &tzpc->r0size);
writel(DECPROTXSET, &tzpc->decprot0set);
writel(DECPROTXSET, &tzpc->decprot1set);
if (addr != TZPC9_BASE) {
writel(DECPROTXSET, &tzpc->decprot2set);
writel(DECPROTXSET, &tzpc->decprot3set);
}
if (cpu_is_exynos5() && (addr == end))
break;
writel(DECPROTXSET, &tzpc->decprot2set);
writel(DECPROTXSET, &tzpc->decprot3set);
}
}

View File

@ -26,9 +26,11 @@ include $(TOPDIR)/config.mk
LIB = $(obj)libs5p-common.o
COBJS-y += cpu_info.o
ifndef CONFIG_SPL_BUILD
COBJS-y += timer.o
COBJS-y += sromc.o
COBJS-$(CONFIG_PWM) += pwm.o
endif
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS))

View File

@ -169,4 +169,37 @@
#address-cells = <1>;
#size-cells = <1>;
};
mmc@12200000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "samsung,exynos5250-dwmmc";
reg = <0x12200000 0x1000>;
interrupts = <0 75 0>;
};
mmc@12210000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "samsung,exynos5250-dwmmc";
reg = <0x12210000 0x1000>;
interrupts = <0 76 0>;
};
mmc@12220000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "samsung,exynos5250-dwmmc";
reg = <0x12220000 0x1000>;
interrupts = <0 77 0>;
};
mmc@12230000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "samsung,exynos5250-dwmmc";
reg = <0x12230000 0x1000>;
interrupts = <0 78 0>;
};
};

View File

@ -38,6 +38,7 @@
#define EXYNOS4_CLOCK_BASE 0x10030000
#define EXYNOS4_SYSTIMER_BASE 0x10050000
#define EXYNOS4_WATCHDOG_BASE 0x10060000
#define EXYNOS4_TZPC_BASE 0x10110000
#define EXYNOS4_MIU_BASE 0x10600000
#define EXYNOS4_DMC0_BASE 0x10400000
#define EXYNOS4_DMC1_BASE 0x10410000
@ -74,6 +75,7 @@
#define EXYNOS4X12_CLOCK_BASE 0x10030000
#define EXYNOS4X12_SYSTIMER_BASE 0x10050000
#define EXYNOS4X12_WATCHDOG_BASE 0x10060000
#define EXYNOS4X12_TZPC_BASE 0x10110000
#define EXYNOS4X12_DMC0_BASE 0x10600000
#define EXYNOS4X12_DMC1_BASE 0x10610000
#define EXYNOS4X12_GPIO_PART4_BASE 0x106E0000
@ -107,6 +109,7 @@
#define EXYNOS5_POWER_BASE 0x10040000
#define EXYNOS5_SWRESET 0x10040400
#define EXYNOS5_SYSREG_BASE 0x10050000
#define EXYNOS5_TZPC_BASE 0x10100000
#define EXYNOS5_WATCHDOG_BASE 0x101D0000
#define EXYNOS5_ACE_SFR_BASE 0x10830000
#define EXYNOS5_DMC_PHY0_BASE 0x10C00000
@ -233,6 +236,7 @@ SAMSUNG_BASE(watchdog, WATCHDOG_BASE)
SAMSUNG_BASE(power, POWER_BASE)
SAMSUNG_BASE(spi, SPI_BASE)
SAMSUNG_BASE(spi_isp, SPI_ISP_BASE)
SAMSUNG_BASE(tzpc, TZPC_BASE)
#endif
#endif /* _EXYNOS4_CPU_H */

View File

@ -27,10 +27,7 @@
#define DWMCI_SET_DRV_CLK(x) ((x) << 16)
#define DWMCI_SET_DIV_RATIO(x) ((x) << 24)
int exynos_dwmci_init(u32 regbase, int bus_width, int index);
static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
{
unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
return exynos_dwmci_init(base, bus_width, index);
}
#ifdef CONFIG_OF_CONTROL
int exynos_dwmmc_init(const void *blob);
#endif
int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel);

View File

@ -21,38 +21,30 @@
#define __ASM_ARCH_TMU_H
struct exynos5_tmu_reg {
unsigned triminfo;
unsigned rsvd1;
unsigned rsvd2;
unsigned rsvd3;
unsigned rsvd4;
unsigned triminfo_control;
unsigned rsvd5;
unsigned rsvd6;
unsigned tmu_control;
unsigned rsvd7;
unsigned tmu_status;
unsigned sampling_internal;
unsigned counter_value0;
unsigned counter_value1;
unsigned rsvd8;
unsigned rsvd9;
unsigned current_temp;
unsigned rsvd10;
unsigned rsvd11;
unsigned rsvd12;
unsigned threshold_temp_rise;
unsigned threshold_temp_fall;
unsigned rsvd13;
unsigned rsvd14;
unsigned past_temp3_0;
unsigned past_temp7_4;
unsigned past_temp11_8;
unsigned past_temp15_12;
unsigned inten;
unsigned intstat;
unsigned intclear;
unsigned rsvd15;
unsigned emul_con;
u32 triminfo;
u32 rsvd1[4];
u32 triminfo_control;
u32 rsvd5[2];
u32 tmu_control;
u32 rsvd7;
u32 tmu_status;
u32 sampling_internal;
u32 counter_value0;
u32 counter_value1;
u32 rsvd8[2];
u32 current_temp;
u32 rsvd10[3];
u32 threshold_temp_rise;
u32 threshold_temp_fall;
u32 rsvd13[2];
u32 past_temp3_0;
u32 past_temp7_4;
u32 past_temp11_8;
u32 past_temp15_12;
u32 inten;
u32 intstat;
u32 intclear;
u32 rsvd15;
u32 emul_con;
};
#endif /* __ASM_ARCH_TMU_H */

View File

@ -47,6 +47,26 @@ struct exynos_tzpc {
unsigned int pcellid2;
unsigned int pcellid3;
};
#define EXYNOS4_NR_TZPC_BANKS 6
#define EXYNOS5_NR_TZPC_BANKS 10
/* TZPC : Register Offsets */
#define TZPC_BASE_OFFSET 0x10000
/*
* TZPC Register Value :
* R0SIZE: 0x0 : Size of secured ram
*/
#define R0SIZE 0x0
/*
* TZPC Decode Protection Register Value :
* DECPROTXSET: 0xFF : Set Decode region to non-secure
*/
#define DECPROTXSET 0xFF
void tzpc_init(void);
#endif
#endif

View File

@ -30,6 +30,10 @@
spi2 = "/spi@12d40000";
spi3 = "/spi@131a0000";
spi4 = "/spi@131b0000";
mmc0 = "/mmc@12200000";
mmc1 = "/mmc@12210000";
mmc2 = "/mmc@12220000";
mmc3 = "/mmc@12230000";
};
sromc@12250000 {
@ -119,4 +123,24 @@
samsung,ycbcr-coeff = <0>;
samsung,color-depth = <1>;
};
mmc@12200000 {
samsung,bus-width = <8>;
samsung,timing = <1 3 3>;
samsung,removable = <0>;
};
mmc@12210000 {
status = "disabled";
};
mmc@12220000 {
samsung,bus-width = <4>;
samsung,timing = <1 2 3>;
samsung,removable = <1>;
};
mmc@12230000 {
status = "disabled";
};
};

View File

@ -87,12 +87,14 @@ lowlevel_init:
1:
/* for UART */
bl uart_asm_init
bl arch_cpu_init
bl tzpc_init
pop {pc}
wakeup_reset:
bl system_clock_init
bl mem_ctrl_asm_init
bl arch_cpu_init
bl tzpc_init
exit_wakeup:
@ -353,45 +355,3 @@ uart_asm_init:
nop
nop
/* Setting TZPC[TrustZone Protection Controller] */
tzpc_init:
ldr r0, =TZPC0_BASE
mov r1, #R0SIZE
str r1, [r0]
mov r1, #DECPROTXSET
str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
ldr r0, =TZPC1_BASE
str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
ldr r0, =TZPC2_BASE
str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
ldr r0, =TZPC3_BASE
str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
ldr r0, =TZPC4_BASE
str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
ldr r0, =TZPC5_BASE
str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
mov pc, lr

View File

@ -121,19 +121,6 @@
#define UBRDIV_OFFSET 0x28
#define UFRACVAL_OFFSET 0x2C
/* TZPC : Register Offsets */
#define TZPC0_BASE 0x10110000
#define TZPC1_BASE 0x10120000
#define TZPC2_BASE 0x10130000
#define TZPC3_BASE 0x10140000
#define TZPC4_BASE 0x10150000
#define TZPC5_BASE 0x10160000
#define TZPC_DECPROT0SET_OFFSET 0x804
#define TZPC_DECPROT1SET_OFFSET 0x810
#define TZPC_DECPROT2SET_OFFSET 0x81C
#define TZPC_DECPROT3SET_OFFSET 0x828
/* CLK_SRC_CPU */
#define MUX_HPM_SEL_MOUTAPLL 0x0
#define MUX_HPM_SEL_SCLKMPLL 0x1
@ -617,16 +604,4 @@
* UBRFRACVAL = ((((800MHz*10/(115200*16) -10))%10)*16/10)
*/
#define UFRACVAL_VAL 0x4
/*
* TZPC Register Value :
* R0SIZE: 0x0 : Size of secured ram
*/
#define R0SIZE 0x0
/*
* TZPC Decode Protection Register Value :
* DECPROTXSET: 0xFF : Set Decode region to non-secure
*/
#define DECPROTXSET 0xFF
#endif

View File

@ -28,12 +28,15 @@ SOBJS := lowlevel_init.o
COBJS := clock_init.o
COBJS += dmc_common.o dmc_init_ddr3.o
COBJS += tzpc_init.o
COBJS += smdk5250_spl.o
ifndef CONFIG_SPL_BUILD
ifdef CONFIG_OF_CONTROL
COBJS += exynos5-dt.o
else
COBJS += smdk5250.o
endif
endif
ifdef CONFIG_SPL_BUILD
COBJS += spl_boot.o

View File

@ -28,10 +28,14 @@
#include <asm/arch/clk.h>
#include <asm/arch/clock.h>
#include <asm/arch/spl.h>
#include <asm/arch/dwmmc.h>
#include "clock_init.h"
#include "setup.h"
#define FSYS1_MMC0_DIV_MASK 0xff0f
#define FSYS1_MMC0_DIV_VAL 0x0701
DECLARE_GLOBAL_DATA_PTR;
struct arm_clk_ratios arm_clk_ratios[] = {
@ -664,3 +668,17 @@ void clock_init_dp_clock(void)
/* We run DP at 267 Mhz */
setbits_le32(&clk->div_disp1_0, CLK_DIV_DISP1_0_FIMD1);
}
/*
* Set clock divisor value for booting from EMMC.
* Set DWMMC channel-0 clk div to operate mmc0 device at 50MHz.
*/
void emmc_boot_clk_div_set(void)
{
struct exynos5_clock *clk = (struct exynos5_clock *)EXYNOS5_CLOCK_BASE;
unsigned int div_mmc;
div_mmc = readl((unsigned int) &clk->div_fsys1) & ~FSYS1_MMC0_DIV_MASK;
div_mmc |= FSYS1_MMC0_DIV_VAL;
writel(div_mmc, (unsigned int) &clk->div_fsys1);
}

View File

@ -146,4 +146,9 @@ struct mem_timings *clock_get_mem_timings(void);
* Initialize clock for the device
*/
void system_clock_init(void);
/*
* Set clock divisor value for booting from EMMC.
*/
void emmc_boot_clk_div_set(void);
#endif

View File

@ -0,0 +1,423 @@
/*
* Copyright (C) 2012 Samsung Electronics
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <fdtdec.h>
#include <asm/io.h>
#include <errno.h>
#include <i2c.h>
#include <netdev.h>
#include <spi.h>
#include <asm/arch/cpu.h>
#include <asm/arch/dwmmc.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mmc.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/power.h>
#include <asm/arch/sromc.h>
#include <power/pmic.h>
#include <power/max77686_pmic.h>
#include <tmu.h>
DECLARE_GLOBAL_DATA_PTR;
#if defined CONFIG_EXYNOS_TMU
/*
* Boot Time Thermal Analysis for SoC temperature threshold breach
*/
static void boot_temp_check(void)
{
int temp;
switch (tmu_monitor(&temp)) {
/* Status TRIPPED ans WARNING means corresponding threshold breach */
case TMU_STATUS_TRIPPED:
puts("EXYNOS_TMU: TRIPPING! Device power going down ...\n");
set_ps_hold_ctrl();
hang();
break;
case TMU_STATUS_WARNING:
puts("EXYNOS_TMU: WARNING! Temperature very high\n");
break;
/*
* TMU_STATUS_INIT means something is wrong with temperature sensing
* and TMU status was changed back from NORMAL to INIT.
*/
case TMU_STATUS_INIT:
default:
debug("EXYNOS_TMU: Unknown TMU state\n");
}
}
#endif
#ifdef CONFIG_USB_EHCI_EXYNOS
int board_usb_vbus_init(void)
{
struct exynos5_gpio_part1 *gpio1 = (struct exynos5_gpio_part1 *)
samsung_get_base_gpio_part1();
/* Enable VBUS power switch */
s5p_gpio_direction_output(&gpio1->x2, 6, 1);
/* VBUS turn ON time */
mdelay(3);
return 0;
}
#endif
#ifdef CONFIG_SOUND_MAX98095
static void board_enable_audio_codec(void)
{
struct exynos5_gpio_part1 *gpio1 = (struct exynos5_gpio_part1 *)
samsung_get_base_gpio_part1();
/* Enable MAX98095 Codec */
s5p_gpio_direction_output(&gpio1->x1, 7, 1);
s5p_gpio_set_pull(&gpio1->x1, 7, GPIO_PULL_NONE);
}
#endif
int board_init(void)
{
gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
#if defined CONFIG_EXYNOS_TMU
if (tmu_init(gd->fdt_blob) != TMU_STATUS_NORMAL) {
debug("%s: Failed to init TMU\n", __func__);
return -1;
}
boot_temp_check();
#endif
#ifdef CONFIG_EXYNOS_SPI
spi_init();
#endif
#ifdef CONFIG_USB_EHCI_EXYNOS
board_usb_vbus_init();
#endif
#ifdef CONFIG_SOUND_MAX98095
board_enable_audio_codec();
#endif
return 0;
}
int dram_init(void)
{
int i;
u32 addr;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE);
gd->ram_size += get_ram_size((long *)addr, SDRAM_BANK_SIZE);
}
return 0;
}
#if defined(CONFIG_POWER)
static int pmic_reg_update(struct pmic *p, int reg, uint regval)
{
u32 val;
int ret = 0;
ret = pmic_reg_read(p, reg, &val);
if (ret) {
debug("%s: PMIC %d register read failed\n", __func__, reg);
return -1;
}
val |= regval;
ret = pmic_reg_write(p, reg, val);
if (ret) {
debug("%s: PMIC %d register write failed\n", __func__, reg);
return -1;
}
return 0;
}
int power_init_board(void)
{
struct pmic *p;
set_ps_hold_ctrl();
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
if (pmic_init(I2C_PMIC))
return -1;
p = pmic_get("MAX77686_PMIC");
if (!p)
return -ENODEV;
if (pmic_probe(p))
return -1;
if (pmic_reg_update(p, MAX77686_REG_PMIC_32KHZ, MAX77686_32KHCP_EN))
return -1;
if (pmic_reg_update(p, MAX77686_REG_PMIC_BBAT,
MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V))
return -1;
/* VDD_MIF */
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK1OUT,
MAX77686_BUCK1OUT_1V)) {
debug("%s: PMIC %d register write failed\n", __func__,
MAX77686_REG_PMIC_BUCK1OUT);
return -1;
}
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK1CRTL,
MAX77686_BUCK1CTRL_EN))
return -1;
/* VDD_ARM */
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK2DVS1,
MAX77686_BUCK2DVS1_1_3V)) {
debug("%s: PMIC %d register write failed\n", __func__,
MAX77686_REG_PMIC_BUCK2DVS1);
return -1;
}
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK2CTRL1,
MAX77686_BUCK2CTRL_ON))
return -1;
/* VDD_INT */
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK3DVS1,
MAX77686_BUCK3DVS1_1_0125V)) {
debug("%s: PMIC %d register write failed\n", __func__,
MAX77686_REG_PMIC_BUCK3DVS1);
return -1;
}
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK3CTRL,
MAX77686_BUCK3CTRL_ON))
return -1;
/* VDD_G3D */
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK4DVS1,
MAX77686_BUCK4DVS1_1_2V)) {
debug("%s: PMIC %d register write failed\n", __func__,
MAX77686_REG_PMIC_BUCK4DVS1);
return -1;
}
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK4CTRL1,
MAX77686_BUCK3CTRL_ON))
return -1;
/* VDD_LDO2 */
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO2CTRL1,
MAX77686_LD02CTRL1_1_5V | EN_LDO))
return -1;
/* VDD_LDO3 */
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO3CTRL1,
MAX77686_LD03CTRL1_1_8V | EN_LDO))
return -1;
/* VDD_LDO5 */
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO5CTRL1,
MAX77686_LD05CTRL1_1_8V | EN_LDO))
return -1;
/* VDD_LDO10 */
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO10CTRL1,
MAX77686_LD10CTRL1_1_8V | EN_LDO))
return -1;
return 0;
}
#endif
void dram_init_banksize(void)
{
int i;
u32 addr, size;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE);
size = get_ram_size((long *)addr, SDRAM_BANK_SIZE);
gd->bd->bi_dram[i].start = addr;
gd->bd->bi_dram[i].size = size;
}
}
static int decode_sromc(const void *blob, struct fdt_sromc *config)
{
int err;
int node;
node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SROMC);
if (node < 0) {
debug("Could not find SROMC node\n");
return node;
}
config->bank = fdtdec_get_int(blob, node, "bank", 0);
config->width = fdtdec_get_int(blob, node, "width", 2);
err = fdtdec_get_int_array(blob, node, "srom-timing", config->timing,
FDT_SROM_TIMING_COUNT);
if (err < 0) {
debug("Could not decode SROMC configuration Error: %s\n",
fdt_strerror(err));
return -FDT_ERR_NOTFOUND;
}
return 0;
}
int board_eth_init(bd_t *bis)
{
#ifdef CONFIG_SMC911X
u32 smc_bw_conf, smc_bc_conf;
struct fdt_sromc config;
fdt_addr_t base_addr;
int node;
node = decode_sromc(gd->fdt_blob, &config);
if (node < 0) {
debug("%s: Could not find sromc configuration\n", __func__);
return 0;
}
node = fdtdec_next_compatible(gd->fdt_blob, node, COMPAT_SMSC_LAN9215);
if (node < 0) {
debug("%s: Could not find lan9215 configuration\n", __func__);
return 0;
}
/* We now have a node, so any problems from now on are errors */
base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
if (base_addr == FDT_ADDR_T_NONE) {
debug("%s: Could not find lan9215 address\n", __func__);
return -1;
}
/* Ethernet needs data bus width of 16 bits */
if (config.width != 2) {
debug("%s: Unsupported bus width %d\n", __func__,
config.width);
return -1;
}
smc_bw_conf = SROMC_DATA16_WIDTH(config.bank)
| SROMC_BYTE_ENABLE(config.bank);
smc_bc_conf = SROMC_BC_TACS(config.timing[FDT_SROM_TACS]) |
SROMC_BC_TCOS(config.timing[FDT_SROM_TCOS]) |
SROMC_BC_TACC(config.timing[FDT_SROM_TACC]) |
SROMC_BC_TCOH(config.timing[FDT_SROM_TCOH]) |
SROMC_BC_TAH(config.timing[FDT_SROM_TAH]) |
SROMC_BC_TACP(config.timing[FDT_SROM_TACP]) |
SROMC_BC_PMC(config.timing[FDT_SROM_PMC]);
/* Select and configure the SROMC bank */
exynos_pinmux_config(PERIPH_ID_SROMC, config.bank);
s5p_config_sromc(config.bank, smc_bw_conf, smc_bc_conf);
return smc911x_initialize(0, base_addr);
#endif
return 0;
}
#ifdef CONFIG_DISPLAY_BOARDINFO
int checkboard(void)
{
const char *board_name;
board_name = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
if (board_name == NULL)
printf("\nUnknown Board\n");
else
printf("\nBoard: %s\n", board_name);
return 0;
}
#endif
#ifdef CONFIG_GENERIC_MMC
int board_mmc_init(bd_t *bis)
{
int ret;
/* dwmmc initializattion for available channels */
ret = exynos_dwmmc_init(gd->fdt_blob);
if (ret)
debug("dwmmc init failed\n");
return ret;
}
#endif
static int board_uart_init(void)
{
int err, uart_id, ret = 0;
for (uart_id = PERIPH_ID_UART0; uart_id <= PERIPH_ID_UART3; uart_id++) {
err = exynos_pinmux_config(uart_id, PINMUX_FLAG_NONE);
if (err) {
debug("UART%d not configured\n",
(uart_id - PERIPH_ID_UART0));
ret |= err;
}
}
return ret;
}
#ifdef CONFIG_BOARD_EARLY_INIT_F
int board_early_init_f(void)
{
int err;
err = board_uart_init();
if (err) {
debug("UART init failed\n");
return err;
}
#ifdef CONFIG_SYS_I2C_INIT_BOARD
board_i2c_init(gd->fdt_blob);
#endif
return err;
}
#endif
#ifdef CONFIG_LCD
void exynos_cfg_lcd_gpio(void)
{
struct exynos5_gpio_part1 *gpio1 =
(struct exynos5_gpio_part1 *)samsung_get_base_gpio_part1();
/* For Backlight */
s5p_gpio_cfg_pin(&gpio1->b2, 0, GPIO_OUTPUT);
s5p_gpio_set_value(&gpio1->b2, 0, 1);
/* LCD power on */
s5p_gpio_cfg_pin(&gpio1->x1, 5, GPIO_OUTPUT);
s5p_gpio_set_value(&gpio1->x1, 5, 1);
/* Set Hotplug detect for DP */
s5p_gpio_cfg_pin(&gpio1->x0, 7, GPIO_FUNC(0x3));
}
void exynos_set_dp_phy(unsigned int onoff)
{
set_dp_phy_ctrl(onoff);
}
#endif

View File

@ -75,12 +75,14 @@ lowlevel_init:
bl mem_ctrl_init
1:
bl arch_cpu_init
bl tzpc_init
ldmia r13!, {ip,pc}
wakeup_reset:
bl system_clock_init
bl mem_ctrl_init
bl arch_cpu_init
bl tzpc_init
exit_wakeup:

View File

@ -28,18 +28,6 @@
#include <config.h>
#include <asm/arch/dmc.h>
/* TZPC : Register Offsets */
#define TZPC0_BASE 0x10100000
#define TZPC1_BASE 0x10110000
#define TZPC2_BASE 0x10120000
#define TZPC3_BASE 0x10130000
#define TZPC4_BASE 0x10140000
#define TZPC5_BASE 0x10150000
#define TZPC6_BASE 0x10160000
#define TZPC7_BASE 0x10170000
#define TZPC8_BASE 0x10180000
#define TZPC9_BASE 0x10190000
/* APLL_CON1 */
#define APLL_CON1_VAL (0x00203800)
@ -458,18 +446,6 @@
/* CLK_GATE_IP_DISP1 */
#define CLK_GATE_DP1_ALLOW (1 << 4)
/*
* TZPC Register Value :
* R0SIZE: 0x0 : Size of secured ram
*/
#define R0SIZE 0x0
/*
* TZPC Decode Protection Register Value :
* DECPROTXSET: 0xFF : Set Decode region to non-secure
*/
#define DECPROTXSET 0xFF
#define DDR3PHY_CTRL_PHY_RESET (1 << 0)
#define DDR3PHY_CTRL_PHY_RESET_OFF (0 << 0)
@ -590,5 +566,4 @@ void update_reset_dll(struct exynos5_dmc *, enum ddr_mode);
void sdelay(unsigned long);
void mem_ctrl_init(void);
void system_clock_init(void);
void tzpc_init(void);
#endif

View File

@ -29,6 +29,7 @@
#include <netdev.h>
#include <spi.h>
#include <asm/arch/cpu.h>
#include <asm/arch/dwmmc.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mmc.h>
#include <asm/arch/pinmux.h>
@ -37,39 +38,9 @@
#include <asm/arch/dp_info.h>
#include <power/pmic.h>
#include <power/max77686_pmic.h>
#include <tmu.h>
DECLARE_GLOBAL_DATA_PTR;
#if defined CONFIG_EXYNOS_TMU
/*
* Boot Time Thermal Analysis for SoC temperature threshold breach
*/
static void boot_temp_check(void)
{
int temp;
switch (tmu_monitor(&temp)) {
/* Status TRIPPED ans WARNING means corresponding threshold breach */
case TMU_STATUS_TRIPPED:
puts("EXYNOS_TMU: TRIPPING! Device power going down ...\n");
set_ps_hold_ctrl();
hang();
break;
case TMU_STATUS_WARNING:
puts("EXYNOS_TMU: WARNING! Temperature very high\n");
break;
/*
* TMU_STATUS_INIT means something is wrong with temperature sensing
* and TMU status was changed back from NORMAL to INIT.
*/
case TMU_STATUS_INIT:
default:
debug("EXYNOS_TMU: Unknown TMU state\n");
}
}
#endif
#ifdef CONFIG_USB_EHCI_EXYNOS
int board_usb_vbus_init(void)
{
@ -102,14 +73,6 @@ int board_init(void)
{
gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
#if defined CONFIG_EXYNOS_TMU
if (tmu_init(gd->fdt_blob) != TMU_STATUS_NORMAL) {
debug("%s: Failed to init TMU\n", __func__);
return -1;
}
boot_temp_check();
#endif
#ifdef CONFIG_EXYNOS_SPI
spi_init();
#endif
@ -124,14 +87,13 @@ int board_init(void)
int dram_init(void)
{
gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE)
+ get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE)
+ get_ram_size((long *)PHYS_SDRAM_3, PHYS_SDRAM_3_SIZE)
+ get_ram_size((long *)PHYS_SDRAM_4, PHYS_SDRAM_4_SIZE)
+ get_ram_size((long *)PHYS_SDRAM_5, PHYS_SDRAM_7_SIZE)
+ get_ram_size((long *)PHYS_SDRAM_6, PHYS_SDRAM_7_SIZE)
+ get_ram_size((long *)PHYS_SDRAM_7, PHYS_SDRAM_7_SIZE)
+ get_ram_size((long *)PHYS_SDRAM_8, PHYS_SDRAM_8_SIZE);
int i;
u32 addr;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE);
gd->ram_size += get_ram_size((long *)addr, SDRAM_BANK_SIZE);
}
return 0;
}
@ -254,57 +216,15 @@ int power_init_board(void)
void dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = get_ram_size((long *)PHYS_SDRAM_1,
PHYS_SDRAM_1_SIZE);
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
gd->bd->bi_dram[1].size = get_ram_size((long *)PHYS_SDRAM_2,
PHYS_SDRAM_2_SIZE);
gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
gd->bd->bi_dram[2].size = get_ram_size((long *)PHYS_SDRAM_3,
PHYS_SDRAM_3_SIZE);
gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
gd->bd->bi_dram[3].size = get_ram_size((long *)PHYS_SDRAM_4,
PHYS_SDRAM_4_SIZE);
gd->bd->bi_dram[4].start = PHYS_SDRAM_5;
gd->bd->bi_dram[4].size = get_ram_size((long *)PHYS_SDRAM_5,
PHYS_SDRAM_5_SIZE);
gd->bd->bi_dram[5].start = PHYS_SDRAM_6;
gd->bd->bi_dram[5].size = get_ram_size((long *)PHYS_SDRAM_6,
PHYS_SDRAM_6_SIZE);
gd->bd->bi_dram[6].start = PHYS_SDRAM_7;
gd->bd->bi_dram[6].size = get_ram_size((long *)PHYS_SDRAM_7,
PHYS_SDRAM_7_SIZE);
gd->bd->bi_dram[7].start = PHYS_SDRAM_8;
gd->bd->bi_dram[7].size = get_ram_size((long *)PHYS_SDRAM_8,
PHYS_SDRAM_8_SIZE);
}
#ifdef CONFIG_OF_CONTROL
static int decode_sromc(const void *blob, struct fdt_sromc *config)
{
int err;
int node;
node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SROMC);
if (node < 0) {
debug("Could not find SROMC node\n");
return node;
int i;
u32 addr, size;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE);
size = get_ram_size((long *)addr, SDRAM_BANK_SIZE);
gd->bd->bi_dram[i].start = addr;
gd->bd->bi_dram[i].size = size;
}
config->bank = fdtdec_get_int(blob, node, "bank", 0);
config->width = fdtdec_get_int(blob, node, "width", 2);
err = fdtdec_get_int_array(blob, node, "srom-timing", config->timing,
FDT_SROM_TIMING_COUNT);
if (err < 0) {
debug("Could not decode SROMC configuration\n");
return -FDT_ERR_NOTFOUND;
}
return 0;
}
#endif
int board_eth_init(bd_t *bis)
{
@ -313,27 +233,6 @@ int board_eth_init(bd_t *bis)
struct fdt_sromc config;
fdt_addr_t base_addr;
#ifdef CONFIG_OF_CONTROL
int node;
node = decode_sromc(gd->fdt_blob, &config);
if (node < 0) {
debug("%s: Could not find sromc configuration\n", __func__);
return 0;
}
node = fdtdec_next_compatible(gd->fdt_blob, node, COMPAT_SMSC_LAN9215);
if (node < 0) {
debug("%s: Could not find lan9215 configuration\n", __func__);
return 0;
}
/* We now have a node, so any problems from now on are errors */
base_addr = fdtdec_get_addr(gd->fdt_blob, node, "reg");
if (base_addr == FDT_ADDR_T_NONE) {
debug("%s: Could not find lan9215 address\n", __func__);
return -1;
}
#else
/* Non-FDT configuration - bank number and timing parameters*/
config.bank = CONFIG_ENV_SROM_BANK;
config.width = 2;
@ -346,7 +245,6 @@ int board_eth_init(bd_t *bis)
config.timing[FDT_SROM_TACP] = 0x09;
config.timing[FDT_SROM_PMC] = 0x01;
base_addr = CONFIG_SMC911X_BASE;
#endif
/* Ethernet needs data bus width of 16 bits */
if (config.width != 2) {
@ -376,17 +274,7 @@ int board_eth_init(bd_t *bis)
#ifdef CONFIG_DISPLAY_BOARDINFO
int checkboard(void)
{
#ifdef CONFIG_OF_CONTROL
const char *board_name;
board_name = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
if (board_name == NULL)
printf("\nUnknown Board\n");
else
printf("\nBoard: %s\n", board_name);
#else
printf("\nBoard: SMDK5250\n");
#endif
return 0;
}
#endif
@ -394,48 +282,54 @@ int checkboard(void)
#ifdef CONFIG_GENERIC_MMC
int board_mmc_init(bd_t *bis)
{
int err;
int err, ret = 0, index, bus_width;
u32 base;
err = exynos_pinmux_config(PERIPH_ID_SDMMC0, PINMUX_FLAG_8BIT_MODE);
if (err) {
if (err)
debug("SDMMC0 not configured\n");
return err;
}
ret |= err;
err = s5p_mmc_init(0, 8);
return err;
/*EMMC: dwmmc Channel-0 with 8 bit bus width */
index = 0;
base = samsung_get_base_mmc() + (0x10000 * index);
bus_width = 8;
err = exynos_dwmci_add_port(index, base, bus_width, (u32)NULL);
if (err)
debug("dwmmc Channel-0 init failed\n");
ret |= err;
err = exynos_pinmux_config(PERIPH_ID_SDMMC2, PINMUX_FLAG_NONE);
if (err)
debug("SDMMC2 not configured\n");
ret |= err;
/*SD: dwmmc Channel-2 with 4 bit bus width */
index = 2;
base = samsung_get_base_mmc() + (0x10000 * index);
bus_width = 4;
err = exynos_dwmci_add_port(index, base, bus_width, (u32)NULL);
if (err)
debug("dwmmc Channel-2 init failed\n");
ret |= err;
return ret;
}
#endif
static int board_uart_init(void)
{
int err;
int err, uart_id, ret = 0;
err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE);
if (err) {
debug("UART0 not configured\n");
return err;
for (uart_id = PERIPH_ID_UART0; uart_id <= PERIPH_ID_UART3; uart_id++) {
err = exynos_pinmux_config(uart_id, PINMUX_FLAG_NONE);
if (err) {
debug("UART%d not configured\n",
(uart_id - PERIPH_ID_UART0));
ret |= err;
}
}
err = exynos_pinmux_config(PERIPH_ID_UART1, PINMUX_FLAG_NONE);
if (err) {
debug("UART1 not configured\n");
return err;
}
err = exynos_pinmux_config(PERIPH_ID_UART2, PINMUX_FLAG_NONE);
if (err) {
debug("UART2 not configured\n");
return err;
}
err = exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
if (err) {
debug("UART3 not configured\n");
return err;
}
return 0;
return ret;
}
#ifdef CONFIG_BOARD_EARLY_INIT_F
@ -448,7 +342,7 @@ int board_early_init_f(void)
return err;
}
#ifdef CONFIG_SYS_I2C_INIT_BOARD
board_i2c_init(gd->fdt_blob);
board_i2c_init(NULL);
#endif
return err;
}
@ -477,7 +371,6 @@ void exynos_set_dp_phy(unsigned int onoff)
set_dp_phy_ctrl(onoff);
}
#ifndef CONFIG_OF_CONTROL
vidinfo_t panel_info = {
.vl_freq = 60,
.vl_col = 2560,
@ -543,13 +436,9 @@ static struct exynos_dp_platform_data dp_platform_data = {
.edp_dev_info = &edp_info,
};
#endif
void init_panel_info(vidinfo_t *vid)
{
#ifndef CONFIG_OF_CONTROL
vid->rgb_mode = MODE_RGB_P,
vid->rgb_mode = MODE_RGB_P;
exynos_set_dp_platform_data(&dp_platform_data);
#endif
}
#endif

View File

@ -23,16 +23,44 @@
#include<common.h>
#include<config.h>
#include <asm/arch-exynos/dmc.h>
#include <asm/arch/clock.h>
#include <asm/arch/clk.h>
#include "clock_init.h"
/* Index into irom ptr table */
enum index {
MMC_INDEX,
EMMC44_INDEX,
EMMC44_END_INDEX,
SPI_INDEX,
USB_INDEX,
};
/* IROM Function Pointers Table */
u32 irom_ptr_table[] = {
[MMC_INDEX] = 0x02020030, /* iROM Function Pointer-SDMMC boot */
[EMMC44_INDEX] = 0x02020044, /* iROM Function Pointer-EMMC4.4 boot*/
[EMMC44_END_INDEX] = 0x02020048,/* iROM Function Pointer
-EMMC4.4 end boot operation */
[SPI_INDEX] = 0x02020058, /* iROM Function Pointer-SPI boot */
[USB_INDEX] = 0x02020070, /* iROM Function Pointer-USB boot*/
};
enum boot_mode {
BOOT_MODE_MMC = 4,
BOOT_MODE_SERIAL = 20,
BOOT_MODE_EMMC = 8, /* EMMC4.4 */
/* Boot based on Operating Mode pin settings */
BOOT_MODE_OM = 32,
BOOT_MODE_USB, /* Boot using USB download */
};
typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst);
typedef u32 (*usb_copy_func_t)(void);
void *get_irom_func(int index)
{
return (void *)*(u32 *)irom_ptr_table[index];
}
/*
* Set/clear program flow prediction and return the previous state.
@ -55,13 +83,15 @@ static int config_branch_prediction(int set_cr_z)
*/
void copy_uboot_to_ram(void)
{
spi_copy_func_t spi_copy;
usb_copy_func_t usb_copy;
int is_cr_z_set;
unsigned int sec_boot_check;
enum boot_mode bootmode = BOOT_MODE_OM;
u32 (*copy_bl2)(u32, u32, u32);
u32 (*spi_copy)(u32 offset, u32 nblock, u32 dst);
u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst);
u32 (*copy_bl2_from_emmc)(u32 nblock, u32 dst);
void (*end_bootop_from_emmc)(void);
u32 (*usb_copy)(void);
/* Read iRAM location to check for secondary USB boot mode */
sec_boot_check = readl(EXYNOS_IRAM_SECONDARY_BASE);
@ -73,14 +103,24 @@ void copy_uboot_to_ram(void)
switch (bootmode) {
case BOOT_MODE_SERIAL:
spi_copy = *(spi_copy_func_t *)EXYNOS_COPY_SPI_FNPTR_ADDR;
spi_copy = get_irom_func(SPI_INDEX);
spi_copy(SPI_FLASH_UBOOT_POS, CONFIG_BL2_SIZE,
CONFIG_SYS_TEXT_BASE);
CONFIG_SYS_TEXT_BASE);
break;
case BOOT_MODE_MMC:
copy_bl2 = (void *) *(u32 *)COPY_BL2_FNPTR_ADDR;
copy_bl2 = get_irom_func(MMC_INDEX);
copy_bl2(BL2_START_OFFSET, BL2_SIZE_BLOC_COUNT,
CONFIG_SYS_TEXT_BASE);
CONFIG_SYS_TEXT_BASE);
break;
case BOOT_MODE_EMMC:
/* Set the FSYS1 clock divisor value for EMMC boot */
emmc_boot_clk_div_set();
copy_bl2_from_emmc = get_irom_func(EMMC44_INDEX);
end_bootop_from_emmc = get_irom_func(EMMC44_END_INDEX);
copy_bl2_from_emmc(BL2_SIZE_BLOC_COUNT, CONFIG_SYS_TEXT_BASE);
end_bootop_from_emmc();
break;
case BOOT_MODE_USB:
/*
@ -88,8 +128,7 @@ void copy_uboot_to_ram(void)
* before copy from USB device to RAM
*/
is_cr_z_set = config_branch_prediction(0);
usb_copy = *(usb_copy_func_t *)
EXYNOS_COPY_USB_FNPTR_ADDR;
usb_copy = get_irom_func(USB_INDEX);
usb_copy();
config_branch_prediction(is_cr_z_set);
break;
@ -117,5 +156,4 @@ void board_init_r(gd_t *id, ulong dest_addr)
while (1)
;
}
void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {}

View File

@ -85,12 +85,14 @@ lowlevel_init:
1:
/* for UART */
bl uart_asm_init
bl arch_cpu_init
bl tzpc_init
pop {pc}
wakeup_reset:
bl system_clock_init
bl mem_ctrl_asm_init
bl arch_cpu_init
bl tzpc_init
exit_wakeup:
@ -410,61 +412,3 @@ uart_asm_init:
nop
nop
nop
/* Setting TZPC[TrustZone Protection Controller] */
tzpc_init:
ldr r0, =0x10110000
mov r1, #0x0
str r1, [r0]
mov r1, #0xff
str r1, [r0, #0x0804]
str r1, [r0, #0x0810]
str r1, [r0, #0x081C]
str r1, [r0, #0x0828]
ldr r0, =0x10120000
mov r1, #0x0
str r1, [r0]
mov r1, #0xff
str r1, [r0, #0x0804]
str r1, [r0, #0x0810]
str r1, [r0, #0x081C]
str r1, [r0, #0x0828]
ldr r0, =0x10130000
mov r1, #0x0
str r1, [r0]
mov r1, #0xff
str r1, [r0, #0x0804]
str r1, [r0, #0x0810]
str r1, [r0, #0x081C]
str r1, [r0, #0x0828]
ldr r0, =0x10140000
mov r1, #0x0
str r1, [r0]
mov r1, #0xff
str r1, [r0, #0x0804]
str r1, [r0, #0x0810]
str r1, [r0, #0x081C]
str r1, [r0, #0x0828]
ldr r0, =0x10150000
mov r1, #0x0
str r1, [r0]
mov r1, #0xff
str r1, [r0, #0x0804]
str r1, [r0, #0x0810]
str r1, [r0, #0x081C]
str r1, [r0, #0x0828]
ldr r0, =0x10160000
mov r1, #0x0
str r1, [r0]
mov r1, #0xff
str r1, [r0, #0x0804]
str r1, [r0, #0x0810]
str r1, [r0, #0x081C]
str r1, [r0, #0x0828]
mov pc, lr

View File

@ -147,6 +147,36 @@ U_BOOT_CMD(
"- display info of the current MMC device"
);
#ifdef CONFIG_SUPPORT_EMMC_BOOT
static int boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
{
int err;
err = mmc_boot_part_access(mmc, ack, part_num, access);
if ((err == 0) && (access != 0)) {
printf("\t\t\t!!!Notice!!!\n");
printf("!You must close EMMC boot Partition");
printf("after all images are written\n");
printf("!EMMC boot partition has continuity");
printf("at image writing time.\n");
printf("!So, do not close the boot partition");
printf("before all images are written.\n");
return 0;
} else if ((err == 0) && (access == 0))
return 0;
else if ((err != 0) && (access != 0)) {
printf("EMMC boot partition-%d OPEN Failed.\n", part_num);
return 1;
} else {
printf("EMMC boot partition-%d CLOSE Failed.\n", part_num);
return 1;
}
}
#endif
static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
enum mmc_state state;
@ -258,8 +288,74 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
curr_device, mmc->part_num);
return 0;
}
#ifdef CONFIG_SUPPORT_EMMC_BOOT
} else if ((strcmp(argv[1], "open") == 0) ||
(strcmp(argv[1], "close") == 0)) {
int dev;
struct mmc *mmc;
u8 part_num, access = 0;
if (argc == 4) {
dev = simple_strtoul(argv[2], NULL, 10);
part_num = simple_strtoul(argv[3], NULL, 10);
} else {
return CMD_RET_USAGE;
}
mmc = find_mmc_device(dev);
if (!mmc) {
printf("no mmc device at slot %x\n", dev);
return 1;
}
if (IS_SD(mmc)) {
printf("SD device cannot be opened/closed\n");
return 1;
}
if ((part_num <= 0) || (part_num > MMC_NUM_BOOT_PARTITION)) {
printf("Invalid boot partition number:\n");
printf("Boot partition number cannot be <= 0\n");
printf("EMMC44 supports only 2 boot partitions\n");
return 1;
}
if (strcmp(argv[1], "open") == 0)
access = part_num; /* enable R/W access to boot part*/
else
access = 0; /* No access to boot partition */
/* acknowledge to be sent during boot operation */
return boot_part_access(mmc, 1, part_num, access);
} else if (strcmp(argv[1], "bootpart") == 0) {
int dev;
dev = simple_strtoul(argv[2], NULL, 10);
u32 bootsize = simple_strtoul(argv[3], NULL, 10);
u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);
struct mmc *mmc = find_mmc_device(dev);
if (!mmc) {
printf("no mmc device at slot %x\n", dev);
return 1;
}
if (IS_SD(mmc)) {
printf("It is not a EMMC device\n");
return 1;
}
if (0 == mmc_boot_partition_size_change(mmc,
bootsize, rpmbsize)) {
printf("EMMC boot partition Size %d MB\n", bootsize);
printf("EMMC RPMB partition Size %d MB\n", rpmbsize);
return 0;
} else {
printf("EMMC boot partition Size change Failed.\n");
return 1;
}
#endif /* CONFIG_SUPPORT_EMMC_BOOT */
}
state = MMC_INVALID;
if (argc == 5 && strcmp(argv[1], "read") == 0)
state = MMC_READ;
@ -334,5 +430,14 @@ U_BOOT_CMD(
"mmc rescan\n"
"mmc part - lists available partition on current mmc device\n"
"mmc dev [dev] [part] - show or set current mmc device [partition]\n"
"mmc list - lists available devices");
"mmc list - lists available devices\n"
#ifdef CONFIG_SUPPORT_EMMC_BOOT
"mmc open <dev> <boot_partition>\n"
" - Enable boot_part for booting and enable R/W access of boot_part\n"
"mmc close <dev> <boot_partition>\n"
" - Enable boot_part for booting and disable access to boot_part\n"
"mmc bootpart <device num> <boot part size MB> <RPMB part size MB>\n"
" - change sizes of boot and RPMB partions of specified device\n"
#endif
);
#endif /* !CONFIG_GENERIC_MMC */

View File

@ -0,0 +1,54 @@
* Exynos 5250 DWC_mobile_storage
The Exynos 5250 provides DWC_mobile_storage interface which supports
. Embedded Multimedia Cards (EMMC-version 4.5)
. Secure Digital memory (SD mem-version 2.0)
. Secure Digital I/O (SDIO-version 3.0)
. Consumer Electronics Advanced Transport Architecture (CE-ATA-version 1.1)
The Exynos 5250 DWC_mobile_storage provides four channels.
SOC specific and Board specific properties are channel specific.
Required SoC Specific Properties:
- compatible: should be
- samsung,exynos5250-dwmmc: for exynos5250 platforms
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: The interrupt number to the cpu.
Required Board Specific Properties:
- #address-cells: should be 1.
- #size-cells: should be 0.
- samsung,bus-width: The width of the bus used to interface the devices
supported by DWC_mobile_storage (SD-MMC/EMMC/SDIO).
. Typically the bus width is 4 or 8.
- samsung,timing: The timing values to be written into the
Drv/sample clock selection register of corresponding channel.
. It is comprised of 3 values corresponding to the 3 fileds
'SelClk_sample', 'SelClk_drv' and 'DIVRATIO' of CLKSEL register.
. SelClk_sample: Select sample clock among 8 shifted clocks.
. SelClk_drv: Select drv clock among 8 shifted clocks.
. DIVRATIO: Clock Divide ratio select.
. The above 3 values are used by the clock phase shifter.
Example:
mmc@12200000 {
samsung,bus-width = <8>;
samsung,timing = <1 3 3>;
samsung,removable = <1>;
}
In the above example,
. The bus width is 8
. Timing is comprised of 3 values as explained below
1 - SelClk_sample
3 - SelClk_drv
3 - DIVRATIO
. The 'removable' flag indicates whether the the particilar device
cannot be removed (always present) or it is a removable device.
1 - Indicates that the device is removable.
0 - Indicates that the device cannot be removed.

View File

@ -129,13 +129,13 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
unsigned int timeout = 100000;
u32 retry = 10000;
u32 mask, ctrl;
ulong start = get_timer(0);
while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
if (timeout == 0) {
if (get_timer(start) > timeout) {
printf("Timeout on data busy\n");
return TIMEOUT;
}
timeout--;
}
dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
@ -143,7 +143,6 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
if (data)
dwmci_prepare_data(host, data);
dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg);
if (data)
@ -231,9 +230,8 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
int timeout = 10000;
unsigned long sclk;
if (freq == host->clock)
if ((freq == host->clock) || (freq == 0))
return 0;
/*
* If host->mmc_clk didn't define,
* then assume that host->bus_hz is source clock value.
@ -314,7 +312,7 @@ static void dwmci_set_ios(struct mmc *mmc)
static int dwmci_init(struct mmc *mmc)
{
struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
u32 fifo_size, fifoth_val;
u32 fifo_size;
dwmci_writel(host, DWMCI_PWREN, 1);
@ -323,6 +321,9 @@ static int dwmci_init(struct mmc *mmc)
return -1;
}
/* Enumerate at 400KHz */
dwmci_setup_bus(host, mmc->f_min);
dwmci_writel(host, DWMCI_RINTSTS, 0xFFFFFFFF);
dwmci_writel(host, DWMCI_INTMASK, 0);
@ -331,13 +332,13 @@ static int dwmci_init(struct mmc *mmc)
dwmci_writel(host, DWMCI_IDINTEN, 0);
dwmci_writel(host, DWMCI_BMOD, 1);
fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
if (host->fifoth_val)
fifoth_val = host->fifoth_val;
else
fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size/2 -1) |
TX_WMARK(fifo_size/2);
dwmci_writel(host, DWMCI_FIFOTH, fifoth_val);
if (!host->fifoth_val) {
fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) |
TX_WMARK(fifo_size / 2);
}
dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
dwmci_writel(host, DWMCI_CLKENA, 0);
dwmci_writel(host, DWMCI_CLKSRC, 0);

View File

@ -19,39 +19,146 @@
*/
#include <common.h>
#include <malloc.h>
#include <dwmmc.h>
#include <fdtdec.h>
#include <libfdt.h>
#include <malloc.h>
#include <asm/arch/dwmmc.h>
#include <asm/arch/clk.h>
#include <asm/arch/pinmux.h>
static char *EXYNOS_NAME = "EXYNOS DWMMC";
#define DWMMC_MAX_CH_NUM 4
#define DWMMC_MAX_FREQ 52000000
#define DWMMC_MIN_FREQ 400000
#define DWMMC_MMC0_CLKSEL_VAL 0x03030001
#define DWMMC_MMC2_CLKSEL_VAL 0x03020001
/*
* Function used as callback function to initialise the
* CLKSEL register for every mmc channel.
*/
static void exynos_dwmci_clksel(struct dwmci_host *host)
{
u32 val;
val = DWMCI_SET_SAMPLE_CLK(DWMCI_SHIFT_0) |
DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) | DWMCI_SET_DIV_RATIO(0);
dwmci_writel(host, DWMCI_CLKSEL, val);
dwmci_writel(host, DWMCI_CLKSEL, host->clksel_val);
}
int exynos_dwmci_init(u32 regbase, int bus_width, int index)
unsigned int exynos_dwmci_get_clk(int dev_index)
{
return get_mmc_clk(dev_index);
}
/*
* This function adds the mmc channel to be registered with mmc core.
* index - mmc channel number.
* regbase - register base address of mmc channel specified in 'index'.
* bus_width - operating bus width of mmc channel specified in 'index'.
* clksel - value to be written into CLKSEL register in case of FDT.
* NULL in case od non-FDT.
*/
int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
{
struct dwmci_host *host = NULL;
unsigned int div;
unsigned long freq, sclk;
host = malloc(sizeof(struct dwmci_host));
if (!host) {
printf("dwmci_host malloc fail!\n");
return 1;
}
/* request mmc clock vlaue of 52MHz. */
freq = 52000000;
sclk = get_mmc_clk(index);
div = DIV_ROUND_UP(sclk, freq);
/* set the clock divisor for mmc */
set_mmc_clk(index, div);
host->name = EXYNOS_NAME;
host->name = "EXYNOS DWMMC";
host->ioaddr = (void *)regbase;
host->buswidth = bus_width;
if (clksel) {
host->clksel_val = clksel;
} else {
if (0 == index)
host->clksel_val = DWMMC_MMC0_CLKSEL_VAL;
if (2 == index)
host->clksel_val = DWMMC_MMC2_CLKSEL_VAL;
}
host->clksel = exynos_dwmci_clksel;
host->dev_index = index;
add_dwmci(host, 52000000, 400000);
host->mmc_clk = exynos_dwmci_get_clk;
/* Add the mmc channel to be registered with mmc core */
if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ)) {
debug("dwmmc%d registration failed\n", index);
return -1;
}
return 0;
}
#ifdef CONFIG_OF_CONTROL
int exynos_dwmmc_init(const void *blob)
{
int index, bus_width;
int node_list[DWMMC_MAX_CH_NUM];
int err = 0, dev_id, flag, count, i;
u32 clksel_val, base, timing[3];
count = fdtdec_find_aliases_for_id(blob, "mmc",
COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list,
DWMMC_MAX_CH_NUM);
for (i = 0; i < count; i++) {
int node = node_list[i];
if (node <= 0)
continue;
/* Extract device id for each mmc channel */
dev_id = pinmux_decode_periph_id(blob, node);
/* Get the bus width from the device node */
bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
if (bus_width <= 0) {
debug("DWMMC: Can't get bus-width\n");
return -1;
}
if (8 == bus_width)
flag = PINMUX_FLAG_8BIT_MODE;
else
flag = PINMUX_FLAG_NONE;
/* config pinmux for each mmc channel */
err = exynos_pinmux_config(dev_id, flag);
if (err) {
debug("DWMMC not configured\n");
return err;
}
index = dev_id - PERIPH_ID_SDMMC0;
/* Get the base address from the device node */
base = fdtdec_get_addr(blob, node, "reg");
if (!base) {
debug("DWMMC: Can't get base address\n");
return -1;
}
/* Extract the timing info from the node */
err = fdtdec_get_int_array(blob, node, "samsung,timing",
timing, 3);
if (err) {
debug("Can't get sdr-timings for divider\n");
return -1;
}
clksel_val = (DWMCI_SET_SAMPLE_CLK(timing[0]) |
DWMCI_SET_DRV_CLK(timing[1]) |
DWMCI_SET_DIV_RATIO(timing[2]));
/* Initialise each mmc channel */
err = exynos_dwmci_add_port(index, base, bus_width, clksel_val);
if (err)
debug("dwmmc Channel-%d init failed\n", index);
}
return 0;
}
#endif

View File

@ -1447,3 +1447,137 @@ int mmc_initialize(bd_t *bis)
do_preinit();
return 0;
}
#ifdef CONFIG_SUPPORT_EMMC_BOOT
/*
* This function changes the size of boot partition and the size of rpmb
* partition present on EMMC devices.
*
* Input Parameters:
* struct *mmc: pointer for the mmc device strcuture
* bootsize: size of boot partition
* rpmbsize: size of rpmb partition
*
* Returns 0 on success.
*/
int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
unsigned long rpmbsize)
{
int err;
struct mmc_cmd cmd;
/* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
cmd.cmdidx = MMC_CMD_RES_MAN;
cmd.resp_type = MMC_RSP_R1b;
cmd.cmdarg = MMC_CMD62_ARG1;
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err) {
debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
return err;
}
/* Boot partition changing mode */
cmd.cmdidx = MMC_CMD_RES_MAN;
cmd.resp_type = MMC_RSP_R1b;
cmd.cmdarg = MMC_CMD62_ARG2;
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err) {
debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
return err;
}
/* boot partition size is multiple of 128KB */
bootsize = (bootsize * 1024) / 128;
/* Arg: boot partition size */
cmd.cmdidx = MMC_CMD_RES_MAN;
cmd.resp_type = MMC_RSP_R1b;
cmd.cmdarg = bootsize;
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err) {
debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
return err;
}
/* RPMB partition size is multiple of 128KB */
rpmbsize = (rpmbsize * 1024) / 128;
/* Arg: RPMB partition size */
cmd.cmdidx = MMC_CMD_RES_MAN;
cmd.resp_type = MMC_RSP_R1b;
cmd.cmdarg = rpmbsize;
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err) {
debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
return err;
}
return 0;
}
/*
* This function shall form and send the commands to open / close the
* boot partition specified by user.
*
* Input Parameters:
* ack: 0x0 - No boot acknowledge sent (default)
* 0x1 - Boot acknowledge sent during boot operation
* part_num: User selects boot data that will be sent to master
* 0x0 - Device not boot enabled (default)
* 0x1 - Boot partition 1 enabled for boot
* 0x2 - Boot partition 2 enabled for boot
* access: User selects partitions to access
* 0x0 : No access to boot partition (default)
* 0x1 : R/W boot partition 1
* 0x2 : R/W boot partition 2
* 0x3 : R/W Replay Protected Memory Block (RPMB)
*
* Returns 0 on success.
*/
int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
{
int err;
struct mmc_cmd cmd;
/* Boot ack enable, boot partition enable , boot partition access */
cmd.cmdidx = MMC_CMD_SWITCH;
cmd.resp_type = MMC_RSP_R1b;
cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
(EXT_CSD_PART_CONF << 16) |
((EXT_CSD_BOOT_ACK(ack) |
EXT_CSD_BOOT_PART_NUM(part_num) |
EXT_CSD_PARTITION_ACCESS(access)) << 8);
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err) {
if (access) {
debug("mmc boot partition#%d open fail:Error1 = %d\n",
part_num, err);
} else {
debug("mmc boot partition#%d close fail:Error = %d\n",
part_num, err);
}
return err;
}
if (access) {
/* 4bit transfer mode at booting time. */
cmd.cmdidx = MMC_CMD_SWITCH;
cmd.resp_type = MMC_RSP_R1b;
cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
(EXT_CSD_BOOT_BUS_WIDTH << 16) |
((1 << 0) << 8);
err = mmc_send_cmd(mmc, &cmd, NULL);
if (err) {
debug("mmc boot partition#%d open fail:Error2 = %d\n",
part_num, err);
return err;
}
}
return 0;
}
#endif

View File

@ -32,6 +32,7 @@ endif
COBJS-$(CONFIG_SPI_FLASH) += spi_flash.o
COBJS-$(CONFIG_SPI_FLASH_ATMEL) += atmel.o
COBJS-$(CONFIG_SPI_FLASH_EON) += eon.o
COBJS-$(CONFIG_SPI_FLASH_GIGADEVICE) += gigadevice.o
COBJS-$(CONFIG_SPI_FLASH_MACRONIX) += macronix.o
COBJS-$(CONFIG_SPI_FLASH_SPANSION) += spansion.o
COBJS-$(CONFIG_SPI_FLASH_SST) += sst.o

View File

@ -0,0 +1,81 @@
/*
* Gigadevice SPI flash driver
* Copyright 2013, Samsung Electronics Co., Ltd.
* Author: Banajit Goswami <banajit.g@samsung.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <malloc.h>
#include <spi_flash.h>
#include "spi_flash_internal.h"
struct gigadevice_spi_flash_params {
uint16_t id;
uint16_t nr_blocks;
const char *name;
};
static const struct gigadevice_spi_flash_params gigadevice_spi_flash_table[] = {
{
.id = 0x6016,
.nr_blocks = 64,
.name = "GD25LQ",
},
{
.id = 0x4017,
.nr_blocks = 128,
.name = "GD25Q64B",
},
};
struct spi_flash *spi_flash_probe_gigadevice(struct spi_slave *spi, u8 *idcode)
{
const struct gigadevice_spi_flash_params *params;
struct spi_flash *flash;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(gigadevice_spi_flash_table); i++) {
params = &gigadevice_spi_flash_table[i];
if (params->id == ((idcode[1] << 8) | idcode[2]))
break;
}
if (i == ARRAY_SIZE(gigadevice_spi_flash_table)) {
debug("SF: Unsupported Gigadevice ID %02x%02x\n",
idcode[1], idcode[2]);
return NULL;
}
flash = spi_flash_alloc_base(spi, params->name);
if (!flash) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
/* page_size */
flash->page_size = 256;
/* sector_size = page_size * pages_per_sector */
flash->sector_size = flash->page_size * 16;
/* size = sector_size * sector_per_block * number of blocks */
flash->size = flash->sector_size * 16 * params->nr_blocks;
return flash;
}

View File

@ -346,6 +346,9 @@ static const struct {
#ifdef CONFIG_SPI_FLASH_EON
{ 0, 0x1c, spi_flash_probe_eon, },
#endif
#ifdef CONFIG_SPI_FLASH_GIGADEVICE
{ 0, 0xc8, spi_flash_probe_gigadevice, },
#endif
#ifdef CONFIG_SPI_FLASH_MACRONIX
{ 0, 0xc2, spi_flash_probe_macronix, },
#endif

View File

@ -106,3 +106,4 @@ struct spi_flash *spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode);
struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 *idcode);
struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode);
struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode);
struct spi_flash *spi_flash_probe_gigadevice(struct spi_slave *spi, u8 *idcode);

View File

@ -50,15 +50,15 @@
/* Tmeperature threshold values for various thermal events */
struct temperature_params {
/* minimum value in temperature code range */
unsigned int min_val;
unsigned min_val;
/* maximum value in temperature code range */
unsigned int max_val;
unsigned max_val;
/* temperature threshold to start warning */
unsigned int start_warning;
unsigned start_warning;
/* temperature threshold CPU tripping */
unsigned int start_tripping;
unsigned start_tripping;
/* temperature threshold for HW tripping */
unsigned int hardware_tripping;
unsigned hardware_tripping;
};
/* Pre-defined values and thresholds for calibration of current temperature */
@ -66,25 +66,27 @@ struct tmu_data {
/* pre-defined temperature thresholds */
struct temperature_params ts;
/* pre-defined efuse range minimum value */
unsigned int efuse_min_value;
unsigned efuse_min_value;
/* pre-defined efuse value for temperature calibration */
unsigned int efuse_value;
unsigned efuse_value;
/* pre-defined efuse range maximum value */
unsigned int efuse_max_value;
unsigned efuse_max_value;
/* current temperature sensing slope */
unsigned int slope;
unsigned slope;
};
/* TMU device specific details and status */
struct tmu_info {
/* base Address for the TMU */
unsigned tmu_base;
struct exynos5_tmu_reg *tmu_base;
/* mux Address for the TMU */
int tmu_mux;
/* pre-defined values for calibration and thresholds */
struct tmu_data data;
/* value required for triminfo_25 calibration */
unsigned int te1;
unsigned te1;
/* value required for triminfo_85 calibration */
unsigned int te2;
unsigned te2;
/* Value for measured data calibration */
int dc_value;
/* enum value indicating status of the TMU */
@ -103,17 +105,24 @@ static struct tmu_info gbl_info;
*/
static int get_cur_temp(struct tmu_info *info)
{
int cur_temp;
struct exynos5_tmu_reg *reg = (struct exynos5_tmu_reg *)info->tmu_base;
struct exynos5_tmu_reg *reg = info->tmu_base;
ulong start;
int cur_temp = 0;
/*
* Temperature code range between min 25 and max 125.
* May run more than once for first call as initial sensing
* has not yet happened.
*/
do {
cur_temp = readl(&reg->current_temp) & 0xff;
} while (cur_temp == 0 && info->tmu_state == TMU_STATUS_NORMAL);
if (info->tmu_state == TMU_STATUS_NORMAL) {
start = get_timer(0);
do {
cur_temp = readl(&reg->current_temp) & 0xff;
} while ((cur_temp == 0) || (get_timer(start) > 100));
}
if (cur_temp == 0)
return cur_temp;
/* Calibrate current temperature */
cur_temp = cur_temp - info->te1 + info->dc_value;
@ -137,23 +146,29 @@ enum tmu_status_t tmu_monitor(int *temp)
/* Read current temperature of the SOC */
cur_temp = get_cur_temp(&gbl_info);
if (!cur_temp)
goto out;
*temp = cur_temp;
/* Temperature code lies between min 25 and max 125 */
if (cur_temp >= data->ts.start_tripping &&
cur_temp <= data->ts.max_val) {
if ((cur_temp >= data->ts.start_tripping) &&
(cur_temp <= data->ts.max_val))
return TMU_STATUS_TRIPPED;
} else if (cur_temp >= data->ts.start_warning) {
if (cur_temp >= data->ts.start_warning)
return TMU_STATUS_WARNING;
} else if (cur_temp < data->ts.start_warning &&
cur_temp >= data->ts.min_val) {
if ((cur_temp < data->ts.start_warning) &&
(cur_temp >= data->ts.min_val))
return TMU_STATUS_NORMAL;
} else {
/* Temperature code does not lie between min 25 and max 125 */
gbl_info.tmu_state = TMU_STATUS_INIT;
debug("EXYNOS_TMU: Thermal reading failed\n");
return TMU_STATUS_INIT;
}
out:
/* Temperature code does not lie between min 25 and max 125 */
gbl_info.tmu_state = TMU_STATUS_INIT;
debug("EXYNOS_TMU: Thermal reading failed\n");
return TMU_STATUS_INIT;
}
/*
@ -166,6 +181,7 @@ enum tmu_status_t tmu_monitor(int *temp)
static int get_tmu_fdt_values(struct tmu_info *info, const void *blob)
{
#ifdef CONFIG_OF_CONTROL
fdt_addr_t addr;
int node;
int error = 0;
@ -183,46 +199,58 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob)
* miscalculation of register values in tmu_setup_parameters
* may result in misleading current temperature.
*/
info->tmu_base = fdtdec_get_addr(blob, node, "reg");
if (info->tmu_base == FDT_ADDR_T_NONE) {
addr = fdtdec_get_addr(blob, node, "reg");
if (addr == FDT_ADDR_T_NONE) {
debug("%s: Missing tmu-base\n", __func__);
return -1;
}
info->tmu_base = (struct exynos5_tmu_reg *)addr;
/* Optional field. */
info->tmu_mux = fdtdec_get_int(blob,
node, "samsung,mux", -1);
/* Take default value as per the user manual b(110) */
if (info->tmu_mux == -1)
info->tmu_mux = 0x6;
info->data.ts.min_val = fdtdec_get_int(blob,
node, "samsung,min-temp", -1);
error |= info->data.ts.min_val;
error |= (info->data.ts.min_val == -1);
info->data.ts.max_val = fdtdec_get_int(blob,
node, "samsung,max-temp", -1);
error |= info->data.ts.max_val;
error |= (info->data.ts.max_val == -1);
info->data.ts.start_warning = fdtdec_get_int(blob,
node, "samsung,start-warning", -1);
error |= info->data.ts.start_warning;
error |= (info->data.ts.start_warning == -1);
info->data.ts.start_tripping = fdtdec_get_int(blob,
node, "samsung,start-tripping", -1);
error |= info->data.ts.start_tripping;
error |= (info->data.ts.start_tripping == -1);
info->data.ts.hardware_tripping = fdtdec_get_int(blob,
node, "samsung,hw-tripping", -1);
error |= info->data.ts.hardware_tripping;
error |= (info->data.ts.hardware_tripping == -1);
info->data.efuse_min_value = fdtdec_get_int(blob,
node, "samsung,efuse-min-value", -1);
error |= info->data.efuse_min_value;
error |= (info->data.efuse_min_value == -1);
info->data.efuse_value = fdtdec_get_int(blob,
node, "samsung,efuse-value", -1);
error |= info->data.efuse_value;
error |= (info->data.efuse_value == -1);
info->data.efuse_max_value = fdtdec_get_int(blob,
node, "samsung,efuse-max-value", -1);
error |= info->data.efuse_max_value;
error |= (info->data.efuse_max_value == -1);
info->data.slope = fdtdec_get_int(blob,
node, "samsung,slope", -1);
error |= info->data.slope;
error |= (info->data.slope == -1);
info->dc_value = fdtdec_get_int(blob,
node, "samsung,dc-value", -1);
error |= info->dc_value;
error |= (info->dc_value == -1);
if (error == -1) {
if (error) {
debug("fail to get tmu node properties\n");
return -1;
}
#else
/* Non DT support may never be added. Just in case */
return -1;
#endif
return 0;
@ -236,12 +264,12 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob)
*/
static void tmu_setup_parameters(struct tmu_info *info)
{
unsigned int te_code, con;
unsigned int warning_code, trip_code, hwtrip_code;
unsigned int cooling_temp;
unsigned int rising_value;
unsigned te_code, con;
unsigned warning_code, trip_code, hwtrip_code;
unsigned cooling_temp;
unsigned rising_value;
struct tmu_data *data = &info->data;
struct exynos5_tmu_reg *reg = (struct exynos5_tmu_reg *)info->tmu_base;
struct exynos5_tmu_reg *reg = info->tmu_base;
/* Must reload for reading efuse value from triminfo register */
writel(TRIMINFO_RELOAD, &reg->triminfo_control);
@ -288,7 +316,7 @@ static void tmu_setup_parameters(struct tmu_info *info)
/* TMU core enable */
con = readl(&reg->tmu_control);
con |= THERM_TRIP_EN | CORE_EN;
con |= THERM_TRIP_EN | CORE_EN | (info->tmu_mux << 20);
writel(con, &reg->tmu_control);
@ -314,6 +342,5 @@ int tmu_init(const void *blob)
tmu_setup_parameters(&gbl_info);
gbl_info.tmu_state = TMU_STATUS_NORMAL;
ret:
return gbl_info.tmu_state;
}

View File

@ -30,6 +30,10 @@
DECLARE_GLOBAL_DATA_PTR;
#define RX_FIFO_COUNT_MASK 0xff
#define RX_FIFO_FULL_MASK (1 << 8)
#define TX_FIFO_FULL_MASK (1 << 24)
static inline struct s5p_uart *s5p_get_base_uart(int dev_index)
{
u32 offset = dev_index * sizeof(struct s5p_uart);
@ -87,8 +91,8 @@ int serial_init_dev(const int dev_index)
{
struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
/* reset and enable FIFOs, set triggers to the maximum */
writel(0, &uart->ufcon);
/* enable FIFOs */
writel(0x1, &uart->ufcon);
writel(0, &uart->umcon);
/* 8N1 */
writel(0x3, &uart->ulcon);
@ -130,7 +134,8 @@ int serial_getc_dev(const int dev_index)
struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
/* wait for character to arrive */
while (!(readl(&uart->utrstat) & 0x1)) {
while (!(readl(&uart->ufstat) & (RX_FIFO_COUNT_MASK |
RX_FIFO_FULL_MASK))) {
if (serial_err_check(dev_index, 0))
return 0;
}
@ -146,7 +151,7 @@ void serial_putc_dev(const char c, const int dev_index)
struct s5p_uart *const uart = s5p_get_base_uart(dev_index);
/* wait for room in the tx FIFO */
while (!(readl(&uart->utrstat) & 0x2)) {
while ((readl(&uart->ufstat) & TX_FIFO_FULL_MASK)) {
if (serial_err_check(dev_index, 1))
return;
}

View File

@ -319,10 +319,10 @@ void lcd_ctrl_init(void *lcdbase)
#ifdef CONFIG_OF_CONTROL
if (exynos_fimd_parse_dt(gd->fdt_blob))
debug("Can't get proper panel info\n");
#endif
#else
/* initialize parameters which is specific to panel. */
init_panel_info(&panel_info);
#endif
panel_width = panel_info.vl_width;
panel_height = panel_info.vl_height;

View File

@ -93,13 +93,15 @@
#define CONFIG_EXTRA_ENV_SETTINGS \
EXYNOS_DEVICE_SETTINGS
#define TZPC_BASE_OFFSET 0x10000
/* SD/MMC configuration */
#define CONFIG_GENERIC_MMC
#define CONFIG_MMC
#define CONFIG_SDHCI
#define CONFIG_S5P_SDHCI
#define CONFIG_DWMMC
#define CONFIG_EXYNOS_DWMMC
#define CONFIG_SUPPORT_EMMC_BOOT
#define CONFIG_BOARD_EARLY_INIT_F
@ -232,6 +234,10 @@
#define SPI_FLASH_UBOOT_POS (CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE)
#define CONFIG_DOS_PARTITION
#define CONFIG_EFI_PARTITION
#define CONFIG_CMD_PART
#define CONFIG_PARTITION_UUIDS
#define CONFIG_IRAM_STACK 0x02050000
@ -262,6 +268,7 @@
#define CONFIG_CMD_SF
#define CONFIG_CMD_SPI
#define CONFIG_SPI_FLASH_WINBOND
#define CONFIG_SPI_FLASH_GIGADEVICE
#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
#define CONFIG_SF_DEFAULT_SPEED 50000000
#define EXYNOS5_SPI_NUM_CONTROLLERS 5

View File

@ -96,6 +96,8 @@
#define CONFIG_SPL
#define COPY_BL2_FNPTR_ADDR 0x02020030
#define CONFIG_SPL_TEXT_BASE 0x02021410
#define CONFIG_BOOTCOMMAND "fatload mmc 0 40007000 uImage; bootm 40007000"
/* Miscellaneous configurable options */

View File

@ -95,6 +95,8 @@
#define CONFIG_SPL
#define COPY_BL2_FNPTR_ADDR 0x00002488
#define CONFIG_SPL_TEXT_BASE 0x02021410
#define CONFIG_BOOTCOMMAND "fatload mmc 0 40007000 uImage; bootm 40007000"
/* Miscellaneous configurable options */

View File

@ -146,7 +146,8 @@
#define CONFIG_DFU_ALT \
"u-boot mmc 80 400;" \
"uImage ext4 0 2\0" \
"uImage ext4 0 2;" \
"exynos4210-trats.dtb ext4 0 2\0"
#define CONFIG_ENV_OVERWRITE
#define CONFIG_SYS_CONSOLE_INFO_QUIET
@ -154,7 +155,7 @@
#define CONFIG_EXTRA_ENV_SETTINGS \
"bootk=" \
"run loaduimage; bootm 0x40007FC0\0" \
"run loaddtb; run loaduimage; bootm 0x40007FC0 - ${fdtaddr}\0" \
"updatemmc=" \
"mmc boot 0 1 1 1; mmc write 0 0x42008000 0 0x200;" \
"mmc boot 0 1 1 0\0" \
@ -177,7 +178,7 @@
"mmcboot=" \
"setenv bootargs root=/dev/mmcblk${mmcdev}p${mmcrootpart} " \
"${lpj} rootwait ${console} ${meminfo} ${opts} ${lcdinfo}; " \
"run loaduimage; bootm 0x40007FC0\0" \
"run loaddtb; run loaduimage; bootm 0x40007FC0 - ${fdtaddr}\0" \
"bootchart=setenv opts init=/sbin/bootchartd; run bootcmd\0" \
"boottrace=setenv opts initcall_debug; run bootcmd\0" \
"mmcoops=mmc read 0 0x40000000 0x40 8; md 0x40000000 0x400\0" \
@ -188,6 +189,8 @@
"nfsroot=/nfsroot/arm\0" \
"bootblock=" CONFIG_BOOTBLOCK "\0" \
"loaduimage=ext4load mmc ${mmcdev}:${mmcbootpart} 0x40007FC0 uImage\0" \
"loaddtb=ext4load mmc ${mmcdev}:${mmcbootpart} ${fdtaddr}" \
"${fdtfile}\0" \
"mmcdev=0\0" \
"mmcbootpart=2\0" \
"mmcrootpart=5\0" \
@ -212,7 +215,10 @@
" /${splfile} ${spl_imgaddr} ${spl_imgsize};" \
"setenv spl_imgsize;" \
"setenv spl_imgaddr;" \
"setenv spl_addr_tmp;\0"
"setenv spl_addr_tmp;\0" \
"fdtaddr=40800000\0" \
"fdtfile=exynos4210-trats.dtb\0"
/* Miscellaneous configurable options */
#define CONFIG_SYS_LONGHELP /* undef to save memory */
@ -322,4 +328,7 @@
#define CONFIG_USB_GADGET_MASS_STORAGE
#endif
/* Pass open firmware flat tree */
#define CONFIG_OF_LIBFDT 1
#endif /* __CONFIG_H */

View File

@ -123,6 +123,8 @@
#define MSIZE(x) ((x) << 28)
#define RX_WMARK(x) ((x) << 16)
#define TX_WMARK(x) (x)
#define RX_WMARK_SHIFT 16
#define RX_WMARK_MASK (0xfff << RX_WMARK_SHIFT)
#define DWMCI_IDMAC_OWN (1 << 31)
#define DWMCI_IDMAC_CH (1 << 4)
@ -144,6 +146,7 @@ struct dwmci_host {
unsigned int bus_hz;
int dev_index;
int buswidth;
u32 clksel_val;
u32 fifoth_val;
struct mmc *mmc;

View File

@ -89,6 +89,7 @@ enum fdt_compat_id {
COMPAT_SAMSUNG_EXYNOS_TMU, /* Exynos TMU */
COMPAT_SAMSUNG_EXYNOS_FIMD, /* Exynos Display controller */
COMPAT_SAMSUNG_EXYNOS5_DP, /* Exynos Display port controller */
COMPAT_SAMSUNG_EXYNOS5_DWMMC, /* Exynos5 DWMMC controller */
COMPAT_MAXIM_MAX77686_PMIC, /* MAX77686 PMIC */
COMPAT_GENERIC_SPI_FLASH, /* Generic SPI Flash chip */
COMPAT_MAXIM_98095_CODEC, /* MAX98095 Codec */

View File

@ -93,6 +93,11 @@
#define MMC_CMD_APP_CMD 55
#define MMC_CMD_SPI_READ_OCR 58
#define MMC_CMD_SPI_CRC_ON_OFF 59
#define MMC_CMD_RES_MAN 62
#define MMC_CMD62_ARG1 0xefac62ec
#define MMC_CMD62_ARG2 0xcbaea7
#define SD_CMD_SEND_RELATIVE_ADDR 3
#define SD_CMD_SWITCH_FUNC 6
@ -160,6 +165,7 @@
*/
#define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
#define EXT_CSD_BOOT_BUS_WIDTH 177
#define EXT_CSD_PART_CONF 179 /* R/W */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_HS_TIMING 185 /* R/W */
@ -184,6 +190,16 @@
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
#define EXT_CSD_BOOT_ACK_ENABLE (1 << 6)
#define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3)
#define EXT_CSD_PARTITION_ACCESS_ENABLE (1 << 0)
#define EXT_CSD_PARTITION_ACCESS_DISABLE (0 << 0)
#define EXT_CSD_BOOT_ACK(x) (x << 6)
#define EXT_CSD_BOOT_PART_NUM(x) (x << 3)
#define EXT_CSD_PARTITION_ACCESS(x) (x << 0)
#define R1_ILLEGAL_COMMAND (1 << 22)
#define R1_APP_CMD (1 << 5)
@ -211,6 +227,11 @@
/* Maximum block size for MMC */
#define MMC_MAX_BLOCK_LEN 512
/* The number of MMC physical partitions. These consist of:
* boot partitions (2), general purpose partitions (4) in MMC v4.4.
*/
#define MMC_NUM_BOOT_PARTITION 2
struct mmc_cid {
unsigned long psn;
unsigned short oid;
@ -291,6 +312,11 @@ int mmc_switch_part(int dev_num, unsigned int part_num);
int mmc_getcd(struct mmc *mmc);
int mmc_getwp(struct mmc *mmc);
void spl_mmc_load(void) __noreturn;
/* Function to change the size of boot partition and rpmb partitions */
int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
unsigned long rpmbsize);
/* Function to send commands to open/close the specified boot partition */
int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access);
/**
* Start device initialization and return immediately; it does not block on

View File

@ -62,6 +62,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"),
COMPAT(SAMSUNG_EXYNOS_FIMD, "samsung,exynos-fimd"),
COMPAT(SAMSUNG_EXYNOS5_DP, "samsung,exynos5-dp"),
COMPAT(SAMSUNG_EXYNOS5_DWMMC, "samsung,exynos5250-dwmmc"),
COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"),

View File

@ -98,6 +98,14 @@ LIBS-y += arch/$(ARCH)/cpu/tegra-common/libcputegra-common.o
LIBS-y += $(CPUDIR)/tegra-common/libtegra-common.o
endif
ifneq ($(CONFIG_MX23)$(CONFIG_MX35),)
LIBS-y += arch/$(ARCH)/imx-common/libimx-common.o
endif
ifeq ($(SOC),exynos)
LIBS-y += $(CPUDIR)/s5p-common/libs5p-common.o
endif
# Add GCC lib
ifeq ("$(USE_PRIVATE_LIBGCC)", "yes")
PLATFORM_LIBGCC = $(SPLTREE)/arch/$(ARCH)/lib/libgcc.o