diff options
| author | Tom Rini <trini@ti.com> | 2013-06-22 07:38:12 -0400 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2013-06-22 07:38:12 -0400 | 
| commit | 348e47f766ac228fb02d1af562b2e9a4c69355db (patch) | |
| tree | 778ffb90bb670f45fa7a0dae78010c8128c4d84d | |
| parent | 5707233880090f785c33df32c04549ea1aeef61e (diff) | |
| parent | fbf87b1823dd5ebc2a384711ea2c677543019ece (diff) | |
| download | olio-uboot-2014.01-348e47f766ac228fb02d1af562b2e9a4c69355db.tar.xz olio-uboot-2014.01-348e47f766ac228fb02d1af562b2e9a4c69355db.zip | |
Merge branch 'master' of git://git.denx.de/u-boot-arm
82 files changed, 1897 insertions, 781 deletions
| @@ -743,6 +743,13 @@ tools: $(VERSION_FILE) $(TIMESTAMP_FILE)  	$(MAKE) -C $@ all  endif	# config.mk +# ARM relocations should all be R_ARM_RELATIVE. +checkarmreloc: $(obj)u-boot +	@if test "R_ARM_RELATIVE" != \ +		"`readelf -r $< | cut -d ' ' -f 4 | grep R_ARM | sort -u`"; \ +		then echo "$< contains relocations other than \ +		R_ARM_RELATIVE"; false; fi +  $(VERSION_FILE):  		@mkdir -p $(dir $(VERSION_FILE))  		@( localvers='$(shell $(TOPDIR)/tools/setlocalversion $(TOPDIR))' ; \ diff --git a/arch/arm/config.mk b/arch/arm/config.mk index dc6416078..e80e1ed1a 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -109,3 +109,8 @@ ifeq ($(GAS_BUG_12532),y)  PLATFORM_RELFLAGS += -fno-optimize-sibling-calls  endif  endif + +# check that only R_ARM_RELATIVE relocations are generated +ifneq ($(CONFIG_SPL_BUILD),y) +ALL-y	+= checkarmreloc +endif diff --git a/arch/arm/cpu/arm920t/ep93xx/u-boot.lds b/arch/arm/cpu/arm920t/ep93xx/u-boot.lds index cf55bf7d4..367c805e3 100644 --- a/arch/arm/cpu/arm920t/ep93xx/u-boot.lds +++ b/arch/arm/cpu/arm920t/ep93xx/u-boot.lds @@ -31,6 +31,7 @@ SECTIONS  	. = ALIGN(4);  	.text      :  	{ +		*(.__image_copy_start)  	  arch/arm/cpu/arm920t/start.o	(.text*)  		/* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */  	  . = 0x1000; @@ -56,7 +57,10 @@ SECTIONS  	. = ALIGN(4); -	__image_copy_end = .; +	.image_copy_end : +	{ +		*(.__image_copy_end) +	}  	__bss_start = .;  	.bss : { *(.bss*) } diff --git a/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds b/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds index 673c725ab..f4e7525f1 100644 --- a/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds +++ b/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds @@ -57,11 +57,6 @@ SECTIONS  		__rel_dyn_end = .;  	} -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) -	} -  	.bss : {  		. = ALIGN(4);  		__bss_start = .; diff --git a/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds b/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds index 967a135b3..446d09501 100644 --- a/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds +++ b/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds @@ -57,11 +57,6 @@ SECTIONS  		__rel_dyn_end = .;  	} -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) -	} -  	.bss : {  		. = ALIGN(4);  		__bss_start = .; diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index 885fb2d20..b935a29a3 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -149,3 +149,43 @@ int arch_misc_init(void)  #endif  	return 0;  } + +#ifdef CONFIG_SPL_BUILD +void rtc32k_enable(void) +{ +	struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE; + +	/* +	 * Unlock the RTC's registers.  For more details please see the +	 * RTC_SS section of the TRM.  In order to unlock we need to +	 * write these specific values (keys) in this order. +	 */ +	writel(0x83e70b13, &rtc->kick0r); +	writel(0x95a4f1e0, &rtc->kick1r); + +	/* Enable the RTC 32K OSC by setting bits 3 and 6. */ +	writel((1 << 3) | (1 << 6), &rtc->osc); +} + +#define UART_RESET		(0x1 << 1) +#define UART_CLK_RUNNING_MASK	0x1 +#define UART_SMART_IDLE_EN	(0x1 << 0x3) + +void uart_soft_reset(void) +{ +	struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE; +	u32 regval; + +	regval = readl(&uart_base->uartsyscfg); +	regval |= UART_RESET; +	writel(regval, &uart_base->uartsyscfg); +	while ((readl(&uart_base->uartsyssts) & +		UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK) +		; + +	/* Disable smart idle */ +	regval = readl(&uart_base->uartsyscfg); +	regval |= UART_SMART_IDLE_EN; +	writel(regval, &uart_base->uartsyscfg); +} +#endif diff --git a/arch/arm/cpu/armv7/am33xx/clock_am33xx.c b/arch/arm/cpu/armv7/am33xx/clock_am33xx.c index a1efc7520..9c4d0b439 100644 --- a/arch/arm/cpu/armv7/am33xx/clock_am33xx.c +++ b/arch/arm/cpu/armv7/am33xx/clock_am33xx.c @@ -246,7 +246,7 @@ static void enable_per_clocks(void)  		;  } -static void mpu_pll_config(void) +void mpu_pll_config_val(int mpull_m)  {  	u32 clkmode, clksel, div_m2; @@ -260,7 +260,7 @@ static void mpu_pll_config(void)  		;  	clksel = clksel & (~CLK_SEL_MASK); -	clksel = clksel | ((MPUPLL_M << CLK_SEL_SHIFT) | MPUPLL_N); +	clksel = clksel | ((mpull_m << CLK_SEL_SHIFT) | MPUPLL_N);  	writel(clksel, &cmwkup->clkseldpllmpu);  	div_m2 = div_m2 & ~CLK_DIV_MASK; @@ -274,6 +274,11 @@ static void mpu_pll_config(void)  		;  } +static void mpu_pll_config(void) +{ +	mpu_pll_config_val(CONFIG_SYS_MPUCLK); +} +  static void core_pll_config(void)  {  	u32 clkmode, clksel, div_m4, div_m5, div_m6; diff --git a/arch/arm/cpu/armv7/exynos/Makefile b/arch/arm/cpu/armv7/exynos/Makefile index 9119961d9..b2f9152e1 100644 --- a/arch/arm/cpu/armv7/exynos/Makefile +++ b/arch/arm/cpu/armv7/exynos/Makefile @@ -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)) diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 223660aab..e1c42462e 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -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; diff --git a/board/samsung/smdk5250/tzpc_init.c b/arch/arm/cpu/armv7/exynos/tzpc.c index c833541fd..f5e8e9c47 100644 --- a/board/samsung/smdk5250/tzpc_init.c +++ b/arch/arm/cpu/armv7/exynos/tzpc.c @@ -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);  	}  } diff --git a/arch/arm/cpu/armv7/s5p-common/Makefile b/arch/arm/cpu/armv7/s5p-common/Makefile index 17053995b..0c38bd0d2 100644 --- a/arch/arm/cpu/armv7/s5p-common/Makefile +++ b/arch/arm/cpu/armv7/s5p-common/Makefile @@ -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)) diff --git a/arch/arm/cpu/ixp/u-boot.lds b/arch/arm/cpu/ixp/u-boot.lds index 553589ca6..54bafda32 100644 --- a/arch/arm/cpu/ixp/u-boot.lds +++ b/arch/arm/cpu/ixp/u-boot.lds @@ -31,6 +31,7 @@ SECTIONS  	. = ALIGN(4);  	.text :  	{ +		*(.__image_copy_start)  		arch/arm/cpu/ixp/start.o(.text*)  		*(.text*)  	} @@ -54,17 +55,23 @@ SECTIONS  	. = ALIGN(4); -	__image_copy_end = .; +	.image_copy_end : +	{ +		*(.__image_copy_end) +	} + +	.rel_dyn_start : +	{ +		*(.__rel_dyn_start) +	}  	.rel.dyn : { -		__rel_dyn_start = .;  		*(.rel*) -		__rel_dyn_end = .;  	} -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) +	.rel_dyn_end : +	{ +		*(.__rel_dyn_end)  	}  	_end = .; @@ -88,6 +95,7 @@ SECTIONS  		KEEP(*(.__bss_end));  	} +	/DISCARD/ : { *(.dynsym) }  	/DISCARD/ : { *(.dynstr*) }  	/DISCARD/ : { *(.dynamic*) }  	/DISCARD/ : { *(.plt*) } diff --git a/arch/arm/cpu/u-boot-spl.lds b/arch/arm/cpu/u-boot-spl.lds index 1408f03b2..b6ed25f7d 100644 --- a/arch/arm/cpu/u-boot-spl.lds +++ b/arch/arm/cpu/u-boot-spl.lds @@ -58,11 +58,6 @@ SECTIONS  		__rel_dyn_end = .;  	} -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) -	} -  	_end = .;  	.bss __rel_dyn_start (OVERLAY) : { @@ -72,6 +67,7 @@ SECTIONS  		__bss_end = .;  	} +	/DISCARD/ : { *(.dynsym) }  	/DISCARD/ : { *(.dynstr*) }  	/DISCARD/ : { *(.dynamic*) }  	/DISCARD/ : { *(.plt*) } diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index d9bbee3b2..3037885b1 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -33,7 +33,7 @@ SECTIONS  	. = ALIGN(4);  	.text :  	{ -		__image_copy_start = .; +		*(.__image_copy_start)  		CPUDIR/start.o (.text*)  		*(.text*)  	} @@ -57,17 +57,23 @@ SECTIONS  	. = ALIGN(4); -	__image_copy_end = .; +	.image_copy_end : +	{ +		*(.__image_copy_end) +	} + +	.rel_dyn_start : +	{ +		*(.__rel_dyn_start) +	}  	.rel.dyn : { -		__rel_dyn_start = .;  		*(.rel*) -		__rel_dyn_end = .;  	} -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) +	.rel_dyn_end : +	{ +		*(.__rel_dyn_end)  	}  	_end = .; @@ -101,6 +107,7 @@ SECTIONS  		KEEP(*(.__bss_end));  	} +	/DISCARD/ : { *(.dynsym) }  	/DISCARD/ : { *(.dynstr*) }  	/DISCARD/ : { *(.dynamic*) }  	/DISCARD/ : { *(.plt*) } diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi index df4b231cf..cee4fe82c 100644 --- a/arch/arm/dts/exynos5250.dtsi +++ b/arch/arm/dts/exynos5250.dtsi @@ -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>; +	}; +  }; diff --git a/arch/arm/include/asm/arch-am33xx/sys_proto.h b/arch/arm/include/asm/arch-am33xx/sys_proto.h index fedc67403..307ac2824 100644 --- a/arch/arm/include/asm/arch-am33xx/sys_proto.h +++ b/arch/arm/include/asm/arch-am33xx/sys_proto.h @@ -32,6 +32,7 @@ extern struct ctrl_stat *cstat;  u32 get_device_type(void);  void save_omap_boot_params(void);  void setup_clocks_for_console(void); +void mpu_pll_config_val(int mpull_m);  void ddr_pll_config(unsigned int ddrpll_M);  void sdelay(unsigned long); @@ -41,4 +42,7 @@ void gpmc_init(void);  void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,  			u32 size);  void omap_nand_switch_ecc(uint32_t, uint32_t); + +void rtc32k_enable(void); +void uart_soft_reset(void);  #endif diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h index f76e4897e..36b98c83e 100644 --- a/arch/arm/include/asm/arch-exynos/cpu.h +++ b/arch/arm/include/asm/arch-exynos/cpu.h @@ -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 */ diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h b/arch/arm/include/asm/arch-exynos/dwmmc.h index 8acdf9b72..3b147b86e 100644 --- a/arch/arm/include/asm/arch-exynos/dwmmc.h +++ b/arch/arm/include/asm/arch-exynos/dwmmc.h @@ -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); diff --git a/arch/arm/include/asm/arch-exynos/tmu.h b/arch/arm/include/asm/arch-exynos/tmu.h index 7e0158efb..cad35694f 100644 --- a/arch/arm/include/asm/arch-exynos/tmu.h +++ b/arch/arm/include/asm/arch-exynos/tmu.h @@ -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 */ diff --git a/arch/arm/include/asm/arch-exynos/tzpc.h b/arch/arm/include/asm/arch-exynos/tzpc.h index c5eb4b1cc..4d9c3a32f 100644 --- a/arch/arm/include/asm/arch-exynos/tzpc.h +++ b/arch/arm/include/asm/arch-exynos/tzpc.h @@ -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 diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 8ad9f66a5..9ecafb272 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -43,7 +43,7 @@ SOBJS-y += relocate.o  ifndef CONFIG_SYS_GENERIC_BOARD  COBJS-y	+= board.o  endif -COBJS-y += bss.o +COBJS-y += sections.o  COBJS-y	+= bootm.o  COBJS-$(CONFIG_OF_LIBFDT) += bootm-fdt.o diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S index 4446da94c..949b9e802 100644 --- a/arch/arm/lib/relocate.S +++ b/arch/arm/lib/relocate.S @@ -37,56 +37,34 @@   */  ENTRY(relocate_code) -	mov	r6, r0	/* save addr of destination */ - -	ldr	r0, =_start		/* r0 <- SRC &_start */ -	subs	r9, r6, r0		/* r9 <- relocation offset */ +	ldr	r1, =__image_copy_start	/* r1 <- SRC &__image_copy_start */ +	subs	r9, r0, r1		/* r9 <- relocation offset */  	beq	relocate_done		/* skip relocation */ -	mov	r1, r6			/* r1 <- scratch for copy loop */ -	adr	r7, relocate_code	/* r7 <- SRC &relocate_code */ -	ldr	r3, _image_copy_end_ofs	/* r3 <- __image_copy_end local ofs */ -	add	r2, r7, r3		/* r2 <- SRC &__image_copy_end */ +	ldr	r2, =__image_copy_end	/* r2 <- SRC &__image_copy_end */  copy_loop: -	ldmia	r0!, {r10-r11}		/* copy from source address [r0]    */ -	stmia	r1!, {r10-r11}		/* copy to   target address [r1]    */ -	cmp	r0, r2			/* until source end address [r2]    */ +	ldmia	r1!, {r10-r11}		/* copy from source address [r1]    */ +	stmia	r0!, {r10-r11}		/* copy to   target address [r0]    */ +	cmp	r1, r2			/* until source end address [r2]    */  	blo	copy_loop  	/*  	 * fix .rel.dyn relocations  	 */ -	ldr	r10, _dynsym_start_ofs	/* r10 <- __dynsym_start local ofs */ -	add	r10, r10, r7		/* r10 <- SRC &__dynsym_start */ -	ldr	r2, _rel_dyn_start_ofs	/* r2 <- __rel_dyn_start local ofs */ -	add	r2, r2, r7		/* r2 <- SRC &__rel_dyn_start */ -	ldr	r3, _rel_dyn_end_ofs	/* r3 <- __rel_dyn_end local ofs */ -	add	r3, r3, r7		/* r3 <- SRC &__rel_dyn_end */ +	ldr	r2, =__rel_dyn_start	/* r2 <- SRC &__rel_dyn_start */ +	ldr	r3, =__rel_dyn_end	/* r3 <- SRC &__rel_dyn_end */  fixloop: -	ldr	r0, [r2]		/* r0 <- SRC location to fix up */ -	add	r0, r0, r9		/* r0 <- DST location to fix up */ -	ldr	r1, [r2, #4] -	and	r7, r1, #0xff -	cmp	r7, #23			/* relative fixup? */ -	beq	fixrel -	cmp	r7, #2			/* absolute fixup? */ -	beq	fixabs -	/* ignore unknown type of fixup */ -	b	fixnext -fixabs: -	/* absolute fix: set location to (offset) symbol value */ -	mov	r1, r1, LSR #4		/* r1 <- symbol index in .dynsym */ -	add	r1, r10, r1		/* r1 <- address of symbol in table */ -	ldr	r1, [r1, #4]		/* r1 <- symbol value */ -	add	r1, r1, r9		/* r1 <- relocated sym addr */ -	b	fixnext -fixrel: +	ldmia	r2!, {r0-r1}		/* (r0,r1) <- (SRC location,fixup) */ +	and	r1, r1, #0xff +	cmp	r1, #23			/* relative fixup? */ +	bne	fixnext +  	/* relative fix: increase location by offset */ +	add	r0, r0, r9  	ldr	r1, [r0]  	add	r1, r1, r9 -fixnext:  	str	r1, [r0] -	add	r2, r2, #8		/* each rel.dyn entry is 8 bytes */ +fixnext:  	cmp	r2, r3  	blo	fixloop @@ -100,13 +78,4 @@ relocate_done:          bx        lr  #endif -_image_copy_end_ofs: -	.word __image_copy_end - relocate_code -_rel_dyn_start_ofs: -	.word __rel_dyn_start - relocate_code -_rel_dyn_end_ofs: -	.word __rel_dyn_end - relocate_code -_dynsym_start_ofs: -	.word __dynsym_start - relocate_code -  ENDPROC(relocate_code) diff --git a/arch/arm/lib/bss.c b/arch/arm/lib/sections.c index 99eda5913..5921dd8d6 100644 --- a/arch/arm/lib/bss.c +++ b/arch/arm/lib/sections.c @@ -35,5 +35,9 @@   * aliasing warnings.   */ -char __bss_start[0] __attribute__((used, section(".__bss_start"))); -char __bss_end[0] __attribute__((used, section(".__bss_end"))); +char __bss_start[0] __attribute__((section(".__bss_start"))); +char __bss_end[0] __attribute__((section(".__bss_end"))); +char __image_copy_start[0] __attribute__((section(".__image_copy_start"))); +char __image_copy_end[0] __attribute__((section(".__image_copy_end"))); +char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); +char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); diff --git a/board/LaCie/common/cpld-gpio-bus.c b/board/LaCie/common/cpld-gpio-bus.c new file mode 100644 index 000000000..fb9bf8d5d --- /dev/null +++ b/board/LaCie/common/cpld-gpio-bus.c @@ -0,0 +1,50 @@ +/* + * cpld-gpio-bus.c: provides support for the CPLD GPIO bus found on some LaCie + * boards (as the 2Big/5Big Network v2 and the 2Big NAS). This parallel GPIO + * bus exposes two registers (address and data). Each of this register is made + * up of several dedicated GPIOs. An extra GPIO is used to notify the CPLD that + * the registers have been updated. + * + * Mostly this bus is used to configure the LEDs on LaCie boards. + * + * Copyright (C) 2013 Simon Guinot <simon.guinot@sequanux.org> + * + * 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. + */ + +#include <asm/arch/gpio.h> +#include "cpld-gpio-bus.h" + +static void cpld_gpio_bus_set_addr(struct cpld_gpio_bus *bus, unsigned addr) +{ +	int pin; + +	for (pin = 0; pin < bus->num_addr; pin++) +		kw_gpio_set_value(bus->addr[pin], (addr >> pin) & 1); +} + +static void cpld_gpio_bus_set_data(struct cpld_gpio_bus *bus, unsigned data) +{ +	int pin; + +	for (pin = 0; pin < bus->num_data; pin++) +		kw_gpio_set_value(bus->data[pin], (data >> pin) & 1); +} + +static void cpld_gpio_bus_enable_select(struct cpld_gpio_bus *bus) +{ +	/* The transfer is enabled on the raising edge. */ +	kw_gpio_set_value(bus->enable, 0); +	kw_gpio_set_value(bus->enable, 1); +} + +void cpld_gpio_bus_write(struct cpld_gpio_bus *bus, +			 unsigned addr, unsigned value) +{ +	cpld_gpio_bus_set_addr(bus, addr); +	cpld_gpio_bus_set_data(bus, value); +	cpld_gpio_bus_enable_select(bus); +} diff --git a/board/LaCie/common/cpld-gpio-bus.h b/board/LaCie/common/cpld-gpio-bus.h new file mode 100644 index 000000000..e9e9b9604 --- /dev/null +++ b/board/LaCie/common/cpld-gpio-bus.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2013 Simon Guinot <simon.guinot@sequanux.org> + * + * 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. + */ + +#ifndef _LACIE_CPLD_GPI0_BUS_H +#define _LACIE_CPLD_GPI0_BUS_H + +struct cpld_gpio_bus { +	unsigned *addr; +	unsigned num_addr; +	unsigned *data; +	unsigned num_data; +	unsigned enable; +}; + +void cpld_gpio_bus_write(struct cpld_gpio_bus *cpld_gpio_bus, +			 unsigned addr, unsigned value); + +#endif /* _LACIE_CPLD_GPI0_BUS_H */ diff --git a/board/LaCie/net2big_v2/Makefile b/board/LaCie/net2big_v2/Makefile index fbae48ef2..9a6dfb619 100644 --- a/board/LaCie/net2big_v2/Makefile +++ b/board/LaCie/net2big_v2/Makefile @@ -28,6 +28,9 @@ endif  LIB	= $(obj)lib$(BOARD).o  COBJS	:= $(BOARD).o ../common/common.o +ifneq ($(and $(CONFIG_KIRKWOOD_GPIO),$(CONFIG_NET2BIG_V2)),) +COBJS	+= ../common/cpld-gpio-bus.o +endif  SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(COBJS)) diff --git a/board/LaCie/net2big_v2/net2big_v2.c b/board/LaCie/net2big_v2/net2big_v2.c index e524f3511..b133f7cb3 100644 --- a/board/LaCie/net2big_v2/net2big_v2.c +++ b/board/LaCie/net2big_v2/net2big_v2.c @@ -22,6 +22,7 @@  #include <common.h>  #include <command.h> +#include <i2c.h>  #include <asm/arch/cpu.h>  #include <asm/arch/kirkwood.h>  #include <asm/arch/mpp.h> @@ -29,6 +30,7 @@  #include "net2big_v2.h"  #include "../common/common.h" +#include "../common/cpld-gpio-bus.h"  DECLARE_GLOBAL_DATA_PTR; @@ -60,18 +62,18 @@ int board_early_init_f(void)  		MPP24_GPIO,		/* USB mode select */  		MPP26_GPIO,		/* USB device vbus */  		MPP28_GPIO,		/* USB enable host vbus */ -		MPP29_GPIO,		/* GPIO extension ALE */ +		MPP29_GPIO,		/* CPLD GPIO bus ALE */  		MPP34_GPIO,		/* Rear Push button 0=on 1=off */  		MPP35_GPIO,		/* Inhibit switch power-off */  		MPP36_GPIO,		/* SATA HDD1 presence */  		MPP37_GPIO,		/* SATA HDD2 presence */  		MPP40_GPIO,		/* eSATA presence */ -		MPP44_GPIO,		/* GPIO extension (data 0) */ -		MPP45_GPIO,		/* GPIO extension (data 1) */ -		MPP46_GPIO,		/* GPIO extension (data 2) */ -		MPP47_GPIO,		/* GPIO extension (addr 0) */ -		MPP48_GPIO,		/* GPIO extension (addr 1) */ -		MPP49_GPIO,		/* GPIO extension (addr 2) */ +		MPP44_GPIO,		/* CPLD GPIO bus (data 0) */ +		MPP45_GPIO,		/* CPLD GPIO bus (data 1) */ +		MPP46_GPIO,		/* CPLD GPIO bus (data 2) */ +		MPP47_GPIO,		/* CPLD GPIO bus (addr 0) */ +		MPP48_GPIO,		/* CPLD GPIO bus (addr 1) */ +		MPP49_GPIO,		/* CPLD GPIO bus (addr 2) */  		0  	}; @@ -92,8 +94,142 @@ int board_init(void)  }  #if defined(CONFIG_MISC_INIT_R) + +#if defined(CONFIG_CMD_I2C) && defined(CONFIG_SYS_I2C_G762_ADDR) +/* + * Start I2C fan (GMT G762 controller) + */ +static void init_fan(void) +{ +	u8 data; + +	i2c_set_bus_num(0); + +	/* Enable open-loop and PWM modes */ +	data = 0x20; +	if (i2c_write(CONFIG_SYS_I2C_G762_ADDR, +		      G762_REG_FAN_CMD1, 1, &data, 1) != 0) +		goto err; +	data = 0; +	if (i2c_write(CONFIG_SYS_I2C_G762_ADDR, +		      G762_REG_SET_CNT, 1, &data, 1) != 0) +		goto err; +	/* +	 * RPM to PWM (set_out register) fan speed conversion array: +	 * 0    0x00 +	 * 1500	0x04 +	 * 2800	0x08 +	 * 3400	0x0C +	 * 3700	0x10 +	 * 4400	0x20 +	 * 4700	0x30 +	 * 4800	0x50 +	 * 5200	0x80 +	 * 5400	0xC0 +	 * 5500	0xFF +	 * +	 * Start fan at low speed (2800 RPM): +	 */ +	data = 0x08; +	if (i2c_write(CONFIG_SYS_I2C_G762_ADDR, +		      G762_REG_SET_OUT, 1, &data, 1) != 0) +		goto err; + +	return; +err: +	printf("Error: failed to start I2C fan @%02x\n", +	       CONFIG_SYS_I2C_G762_ADDR); +} +#else +static void init_fan(void) {} +#endif /* CONFIG_CMD_I2C && CONFIG_SYS_I2C_G762_ADDR */ + +#if defined(CONFIG_NET2BIG_V2) && defined(CONFIG_KIRKWOOD_GPIO) +/* + * CPLD GPIO bus: + * + * - address register : bit [0-2] -> GPIO [47-49] + * - data register    : bit [0-2] -> GPIO [44-46] + * - enable register  : GPIO 29 + */ +static unsigned cpld_gpio_bus_addr[] = { 47, 48, 49 }; +static unsigned cpld_gpio_bus_data[] = { 44, 45, 46 }; + +static struct cpld_gpio_bus cpld_gpio_bus = { +	.addr		= cpld_gpio_bus_addr, +	.num_addr	= ARRAY_SIZE(cpld_gpio_bus_addr), +	.data		= cpld_gpio_bus_data, +	.num_data	= ARRAY_SIZE(cpld_gpio_bus_data), +	.enable		= 29, +}; + +/* + * LEDs configuration: + * + * The LEDs are controlled by a CPLD and can be configured through + * the CPLD GPIO bus. + * + * Address register selection: + * + * addr | register + * ---------------------------- + *   0  | front LED + *   1  | front LED brightness + *   2  | SATA LED brightness + *   3  | SATA0 LED + *   4  | SATA1 LED + *   5  | SATA2 LED + *   6  | SATA3 LED + *   7  | SATA4 LED + * + * Data register configuration: + * + * data | LED brightness + * ------------------------------------------------- + *   0  | min (off) + *   -  | - + *   7  | max + * + * data | front LED mode + * ------------------------------------------------- + *   0  | fix off + *   1  | fix blue on + *   2  | fix red on + *   3  | blink blue on=1 sec and blue off=1 sec + *   4  | blink red on=1 sec and red off=1 sec + *   5  | blink blue on=2.5 sec and red on=0.5 sec + *   6  | blink blue on=1 sec and red on=1 sec + *   7  | blink blue on=0.5 sec and blue off=2.5 sec + * + * data | SATA LED mode + * ------------------------------------------------- + *   0  | fix off + *   1  | SATA activity blink + *   2  | fix red on + *   3  | blink blue on=1 sec and blue off=1 sec + *   4  | blink red on=1 sec and red off=1 sec + *   5  | blink blue on=2.5 sec and red on=0.5 sec + *   6  | blink blue on=1 sec and red on=1 sec + *   7  | fix blue on + */ +static void init_leds(void) +{ +	/* Enable the front blue LED */ +	cpld_gpio_bus_write(&cpld_gpio_bus, 0, 1); +	cpld_gpio_bus_write(&cpld_gpio_bus, 1, 3); + +	/* Configure SATA LEDs to blink in relation with the SATA activity */ +	cpld_gpio_bus_write(&cpld_gpio_bus, 3, 1); +	cpld_gpio_bus_write(&cpld_gpio_bus, 4, 1); +	cpld_gpio_bus_write(&cpld_gpio_bus, 2, 3); +} +#else +static void init_leds(void) {} +#endif /* CONFIG_NET2BIG_V2 && CONFIG_KIRKWOOD_GPIO */ +  int misc_init_r(void)  { +	init_fan();  #if defined(CONFIG_CMD_I2C) && defined(CONFIG_SYS_I2C_EEPROM_ADDR)  	if (!getenv("ethaddr")) {  		uchar mac[6]; @@ -101,9 +237,11 @@ int misc_init_r(void)  			eth_setenv_enetaddr("ethaddr", mac);  	}  #endif +	init_leds(); +  	return 0;  } -#endif +#endif /* CONFIG_MISC_INIT_R */  #if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R)  /* Configure and initialize PHY */ diff --git a/board/LaCie/net2big_v2/net2big_v2.h b/board/LaCie/net2big_v2/net2big_v2.h index f9778f4f0..83537d6b9 100644 --- a/board/LaCie/net2big_v2/net2big_v2.h +++ b/board/LaCie/net2big_v2/net2big_v2.h @@ -32,4 +32,9 @@  /* Buttons */  #define NET2BIG_V2_GPIO_PUSH_BUTTON	34 +/* GMT G762 registers (I2C fan controller) */ +#define G762_REG_SET_CNT		0x00 +#define G762_REG_SET_OUT		0x03 +#define G762_REG_FAN_CMD1		0x04 +  #endif /* NET2BIG_V2_H */ diff --git a/board/actux1/u-boot.lds b/board/actux1/u-boot.lds index ef4a25bc3..74aec5fbc 100644 --- a/board/actux1/u-boot.lds +++ b/board/actux1/u-boot.lds @@ -30,6 +30,7 @@ SECTIONS  	. = ALIGN (4);  	.text : { +		*(.__image_copy_start)  		arch/arm/cpu/ixp/start.o(.text*)  		net/libnet.o(.text*)  		board/actux1/libactux1.o(.text*) @@ -62,17 +63,23 @@ SECTIONS  	. = ALIGN (4); -	__image_copy_end = .; +	.image_copy_end : +	{ +		*(.__image_copy_end) +	} + +	.rel_dyn_start : +	{ +		*(.__rel_dyn_start) +	}  	.rel.dyn : { -		__rel_dyn_start = .;  		*(.rel*) -		__rel_dyn_end = .;  	} -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) +	.rel_dyn_end : +	{ +		*(.__rel_dyn_end)  	}  	_end = .; @@ -96,6 +103,7 @@ SECTIONS  		KEEP(*(.__bss_end));  	} +	/DISCARD/ : { *(.dynsym) }  	/DISCARD/ : { *(.dynstr*) }  	/DISCARD/ : { *(.dynamic*) }  	/DISCARD/ : { *(.plt*) } diff --git a/board/actux2/u-boot.lds b/board/actux2/u-boot.lds index 00ad8b71c..c276501bd 100644 --- a/board/actux2/u-boot.lds +++ b/board/actux2/u-boot.lds @@ -30,6 +30,7 @@ SECTIONS  	. = ALIGN (4);  	.text : { +		*(.__image_copy_start)  		arch/arm/cpu/ixp/start.o(.text*)  		net/libnet.o(.text*)  		board/actux2/libactux2.o(.text*) @@ -62,17 +63,23 @@ SECTIONS  	. = ALIGN (4); -	__image_copy_end = .; +	.image_copy_end : +	{ +		*(.__image_copy_end) +	} + +	.rel_dyn_start : +	{ +		*(.__rel_dyn_start) +	}  	.rel.dyn : { -		__rel_dyn_start = .;  		*(.rel*) -		__rel_dyn_end = .;  	} -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) +	.rel_dyn_end : +	{ +		*(.__rel_dyn_end)  	}  	_end = .; @@ -96,6 +103,7 @@ SECTIONS  		KEEP(*(.__bss_end));  	} +	/DISCARD/ : { *(.dynsym) }  	/DISCARD/ : { *(.dynstr*) }  	/DISCARD/ : { *(.dynamic*) }  	/DISCARD/ : { *(.plt*) } diff --git a/board/actux3/u-boot.lds b/board/actux3/u-boot.lds index 44b990ee7..5610644d7 100644 --- a/board/actux3/u-boot.lds +++ b/board/actux3/u-boot.lds @@ -30,6 +30,7 @@ SECTIONS  	. = ALIGN (4);  	.text : { +		*(.__image_copy_start)  		arch/arm/cpu/ixp/start.o(.text*)  		net/libnet.o(.text*)  		board/actux3/libactux3.o(.text*) @@ -62,17 +63,23 @@ SECTIONS  	. = ALIGN (4); -	__image_copy_end = .; +	.image_copy_end : +	{ +		*(.__image_copy_end) +	} + +	.rel_dyn_start : +	{ +		*(.__rel_dyn_start) +	}  	.rel.dyn : { -		__rel_dyn_start = .;  		*(.rel*) -		__rel_dyn_end = .;  	} -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) +	.rel_dyn_end : +	{ +		*(.__rel_dyn_end)  	}  	_end = .; @@ -96,6 +103,7 @@ SECTIONS  		KEEP(*(.__bss_end));  	} +	/DISCARD/ : { *(.dynsym) }  	/DISCARD/ : { *(.dynstr*) }  	/DISCARD/ : { *(.dynamic*) }  	/DISCARD/ : { *(.plt*) } diff --git a/board/ait/cam_enc_4xx/u-boot-spl.lds b/board/ait/cam_enc_4xx/u-boot-spl.lds index 1daa1b3b9..39726854c 100644 --- a/board/ait/cam_enc_4xx/u-boot-spl.lds +++ b/board/ait/cam_enc_4xx/u-boot-spl.lds @@ -54,11 +54,6 @@ SECTIONS  		__rel_dyn_end = .;  	} >.sram -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) -	} >.sram -  	.bss :  	{  		. = ALIGN(4); diff --git a/board/davinci/da8xxevm/u-boot-spl-da850evm.lds b/board/davinci/da8xxevm/u-boot-spl-da850evm.lds index b1b870181..6fa450909 100644 --- a/board/davinci/da8xxevm/u-boot-spl-da850evm.lds +++ b/board/davinci/da8xxevm/u-boot-spl-da850evm.lds @@ -55,11 +55,6 @@ SECTIONS  		__rel_dyn_end = .;  	} >.sram -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) -	} >.sram -  	.bss :  	{  		. = ALIGN(4); diff --git a/board/davinci/da8xxevm/u-boot-spl-hawk.lds b/board/davinci/da8xxevm/u-boot-spl-hawk.lds index 596a9e08e..b452f2078 100644 --- a/board/davinci/da8xxevm/u-boot-spl-hawk.lds +++ b/board/davinci/da8xxevm/u-boot-spl-hawk.lds @@ -61,7 +61,6 @@ SECTIONS  	__image_copy_end = .;  	__rel_dyn_start = .;  	__rel_dyn_end = .; -	__dynsym_start = .;  	__got_start = .;  	. = ALIGN(4); diff --git a/board/dvlhost/u-boot.lds b/board/dvlhost/u-boot.lds index 6d4b1875c..f35911232 100644 --- a/board/dvlhost/u-boot.lds +++ b/board/dvlhost/u-boot.lds @@ -30,6 +30,7 @@ SECTIONS  	. = ALIGN (4);  	.text : { +		*(.__image_copy_start)  		arch/arm/cpu/ixp/start.o(.text*)  		net/libnet.o(.text*)  		board/dvlhost/libdvlhost.o(.text*) @@ -62,17 +63,23 @@ SECTIONS  	. = ALIGN (4); -	__image_copy_end = .; +	.image_copy_end : +	{ +		*(.__image_copy_end) +	} + +	.rel_dyn_start : +	{ +		*(.__rel_dyn_start) +	}  	.rel.dyn : { -		__rel_dyn_start = .;  		*(.rel*) -		__rel_dyn_end = .;  	} -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) +	.rel_dyn_end : +	{ +		*(.__rel_dyn_end)  	}  	_end = .; @@ -96,6 +103,7 @@ SECTIONS  		KEEP(*(.__bss_end));  	} +	/DISCARD/ : { *(.dynsym) }  	/DISCARD/ : { *(.dynstr*) }  	/DISCARD/ : { *(.dynamic*) }  	/DISCARD/ : { *(.plt*) } diff --git a/board/freescale/mx31ads/u-boot.lds b/board/freescale/mx31ads/u-boot.lds index 496996000..963d29f2d 100644 --- a/board/freescale/mx31ads/u-boot.lds +++ b/board/freescale/mx31ads/u-boot.lds @@ -34,6 +34,7 @@ SECTIONS  	. = ALIGN(4);  	.text	   :  	{ +		*(.__image_copy_start)  	  /* WARNING - the following is hand-optimized to fit within	*/  	  /* the sector layout of our flash chips!	XXX FIXME XXX	*/ @@ -65,17 +66,23 @@ SECTIONS  	. = ALIGN(4); -	__image_copy_end = .; +	.image_copy_end : +	{ +		*(.__image_copy_end) +	} + +	.rel_dyn_start : +	{ +		*(.__rel_dyn_start) +	}  	.rel.dyn : { -		__rel_dyn_start = .;  		*(.rel*) -		__rel_dyn_end = .;  	} -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) +	.rel_dyn_end : +	{ +		*(.__rel_dyn_end)  	}  	_end = .; @@ -100,6 +107,7 @@ SECTIONS  	}  	/DISCARD/ : { *(.bss*) } +	/DISCARD/ : { *(.dynsym) }  	/DISCARD/ : { *(.dynstr*) }  	/DISCARD/ : { *(.dynsym*) }  	/DISCARD/ : { *(.dynamic*) } diff --git a/board/isee/igep0033/board.c b/board/isee/igep0033/board.c index 826ceadd8..ea3bea50f 100644 --- a/board/isee/igep0033/board.c +++ b/board/isee/igep0033/board.c @@ -36,37 +36,13 @@  DECLARE_GLOBAL_DATA_PTR;  static struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; -#ifdef CONFIG_SPL_BUILD -static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE; -#endif  /* MII mode defines */  #define RMII_MODE_ENABLE	0x4D  static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; -/* UART Defines */  #ifdef CONFIG_SPL_BUILD -#define UART_RESET		(0x1 << 1) -#define UART_CLK_RUNNING_MASK	0x1 -#define UART_SMART_IDLE_EN	(0x1 << 0x3) - -static void rtc32k_enable(void) -{ -	struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE; - -	/* -	 * Unlock the RTC's registers.  For more details please see the -	 * RTC_SS section of the TRM.  In order to unlock we need to -	 * write these specific values (keys) in this order. -	 */ -	writel(0x83e70b13, &rtc->kick0r); -	writel(0x95a4f1e0, &rtc->kick1r); - -	/* Enable the RTC 32K OSC by setting bits 3 and 6. */ -	writel((1 << 3) | (1 << 6), &rtc->osc); -} -  static const struct ddr_data ddr3_data = {  	.datardsratio0 = K4B2G1646EBIH9_RD_DQS,  	.datawdsratio0 = K4B2G1646EBIH9_WR_DQS, @@ -131,23 +107,9 @@ void s_init(void)  	/* Enable RTC32K clock */  	rtc32k_enable(); -	/* UART softreset */ -	u32 regval; -  	enable_uart0_pin_mux(); -	regval = readl(&uart_base->uartsyscfg); -	regval |= UART_RESET; -	writel(regval, &uart_base->uartsyscfg); -	while ((readl(&uart_base->uartsyssts) & -		UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK) -		; - -	/* Disable smart idle */ -	regval = readl(&uart_base->uartsyscfg); -	regval |= UART_SMART_IDLE_EN; -	writel(regval, &uart_base->uartsyscfg); - +	uart_soft_reset();  	gd = &gdata;  	preloader_console_init(); diff --git a/board/phytec/pcm051/board.c b/board/phytec/pcm051/board.c index 93c611dfc..0cca8d75b 100644 --- a/board/phytec/pcm051/board.c +++ b/board/phytec/pcm051/board.c @@ -39,9 +39,6 @@  DECLARE_GLOBAL_DATA_PTR;  static struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; -#ifdef CONFIG_SPL_BUILD -static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE; -#endif  /* MII mode defines */  #define MII_MODE_ENABLE		0x0 @@ -50,31 +47,11 @@ static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;  static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; -/* UART defines */  #ifdef CONFIG_SPL_BUILD -#define UART_RESET		(0x1 << 1) -#define UART_CLK_RUNNING_MASK	0x1 -#define UART_SMART_IDLE_EN	(0x1 << 0x3)  /* DDR RAM defines */  #define DDR_CLK_MHZ		303 /* DDR_DPLL_MULT value */ -static void rtc32k_enable(void) -{ -	struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE; - -	/* -	 * Unlock the RTC's registers.  For more details please see the -	 * RTC_SS section of the TRM.  In order to unlock we need to -	 * write these specific values (keys) in this order. -	 */ -	writel(0x83e70b13, &rtc->kick0r); -	writel(0x95a4f1e0, &rtc->kick1r); - -	/* Enable the RTC 32K OSC by setting bits 3 and 6. */ -	writel((1 << 3) | (1 << 6), &rtc->osc); -} -  static const struct ddr_data ddr3_data = {  	.datardsratio0 = MT41J256M8HX15E_RD_DQS,  	.datawdsratio0 = MT41J256M8HX15E_WR_DQS, @@ -141,22 +118,8 @@ void s_init(void)  	/* Enable RTC32K clock */  	rtc32k_enable(); -	/* UART softreset */ -	u32 regval; -  	enable_uart0_pin_mux(); - -	regval = readl(&uart_base->uartsyscfg); -	regval |= UART_RESET; -	writel(regval, &uart_base->uartsyscfg); -	while ((readl(&uart_base->uartsyssts) &	UART_CLK_RUNNING_MASK) -		!= UART_CLK_RUNNING_MASK) -		; - -	/* Disable smart idle */ -	regval = readl(&uart_base->uartsyscfg); -	regval |= UART_SMART_IDLE_EN; -	writel(regval, &uart_base->uartsyscfg); +	uart_soft_reset();  	gd = &gdata; diff --git a/board/samsung/dts/exynos5250-smdk5250.dts b/board/samsung/dts/exynos5250-smdk5250.dts index 8da973b30..93375a64b 100644 --- a/board/samsung/dts/exynos5250-smdk5250.dts +++ b/board/samsung/dts/exynos5250-smdk5250.dts @@ -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"; +	};  }; diff --git a/board/samsung/origen/lowlevel_init.S b/board/samsung/origen/lowlevel_init.S index 9daa0da61..be9d41826 100644 --- a/board/samsung/origen/lowlevel_init.S +++ b/board/samsung/origen/lowlevel_init.S @@ -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 diff --git a/board/samsung/origen/origen_setup.h b/board/samsung/origen/origen_setup.h index 930b94850..926a4ccc2 100644 --- a/board/samsung/origen/origen_setup.h +++ b/board/samsung/origen/origen_setup.h @@ -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 diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile index 47c6a5a46..f2c32ee4c 100644 --- a/board/samsung/smdk5250/Makefile +++ b/board/samsung/smdk5250/Makefile @@ -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 diff --git a/board/samsung/smdk5250/clock_init.c b/board/samsung/smdk5250/clock_init.c index 5b9e82fdf..b288e66f0 100644 --- a/board/samsung/smdk5250/clock_init.c +++ b/board/samsung/smdk5250/clock_init.c @@ -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); +} diff --git a/board/samsung/smdk5250/clock_init.h b/board/samsung/smdk5250/clock_init.h index f751bcb65..20a1d47e0 100644 --- a/board/samsung/smdk5250/clock_init.h +++ b/board/samsung/smdk5250/clock_init.h @@ -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 diff --git a/board/samsung/smdk5250/exynos5-dt.c b/board/samsung/smdk5250/exynos5-dt.c new file mode 100644 index 000000000..813150586 --- /dev/null +++ b/board/samsung/smdk5250/exynos5-dt.c @@ -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 diff --git a/board/samsung/smdk5250/lowlevel_init.S b/board/samsung/smdk5250/lowlevel_init.S index bc6cb6f73..edc565ef7 100644 --- a/board/samsung/smdk5250/lowlevel_init.S +++ b/board/samsung/smdk5250/lowlevel_init.S @@ -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: diff --git a/board/samsung/smdk5250/setup.h b/board/samsung/smdk5250/setup.h index 34d8bc31f..eb91d1310 100644 --- a/board/samsung/smdk5250/setup.h +++ b/board/samsung/smdk5250/setup.h @@ -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 diff --git a/board/samsung/smdk5250/smdk5250.c b/board/samsung/smdk5250/smdk5250.c index 8b09e1de4..276fd4132 100644 --- a/board/samsung/smdk5250/smdk5250.c +++ b/board/samsung/smdk5250/smdk5250.c @@ -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; -	} - -	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; +	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;  	} - -	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 diff --git a/board/samsung/smdk5250/spl_boot.c b/board/samsung/smdk5250/spl_boot.c index c0bcf460f..98f2286f9 100644 --- a/board/samsung/smdk5250/spl_boot.c +++ b/board/samsung/smdk5250/spl_boot.c @@ -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) {} diff --git a/board/samsung/smdkv310/lowlevel_init.S b/board/samsung/smdkv310/lowlevel_init.S index 7a1ea98ae..31e0e2eda 100644 --- a/board/samsung/smdkv310/lowlevel_init.S +++ b/board/samsung/smdkv310/lowlevel_init.S @@ -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 diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c index 638cc4d68..fdbe26cde 100644 --- a/board/ti/am335x/board.c +++ b/board/ti/am335x/board.c @@ -38,9 +38,6 @@  DECLARE_GLOBAL_DATA_PTR;  static struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; -#ifdef CONFIG_SPL_BUILD -static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE; -#endif  /* MII mode defines */  #define MII_MODE_ENABLE		0x0 @@ -126,28 +123,7 @@ static int read_eeprom(void)  	return 0;  } -/* UART Defines */  #ifdef CONFIG_SPL_BUILD -#define UART_RESET		(0x1 << 1) -#define UART_CLK_RUNNING_MASK	0x1 -#define UART_SMART_IDLE_EN	(0x1 << 0x3) - -static void rtc32k_enable(void) -{ -	struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE; - -	/* -	 * Unlock the RTC's registers.  For more details please see the -	 * RTC_SS section of the TRM.  In order to unlock we need to -	 * write these specific values (keys) in this order. -	 */ -	writel(0x83e70b13, &rtc->kick0r); -	writel(0x95a4f1e0, &rtc->kick1r); - -	/* Enable the RTC 32K OSC by setting bits 3 and 6. */ -	writel((1 << 3) | (1 << 6), &rtc->osc); -} -  static const struct ddr_data ddr2_data = {  	.datardsratio0 = ((MT47H128M16RT25E_RD_DQS<<30) |  			  (MT47H128M16RT25E_RD_DQS<<20) | @@ -339,9 +315,6 @@ void s_init(void)  	/* Enable RTC32K clock */  	rtc32k_enable(); -	/* UART softreset */ -	u32 regVal; -  #ifdef CONFIG_SERIAL1  	enable_uart0_pin_mux();  #endif /* CONFIG_SERIAL1 */ @@ -361,17 +334,7 @@ void s_init(void)  	enable_uart5_pin_mux();  #endif /* CONFIG_SERIAL6 */ -	regVal = readl(&uart_base->uartsyscfg); -	regVal |= UART_RESET; -	writel(regVal, &uart_base->uartsyscfg); -	while ((readl(&uart_base->uartsyssts) & -		UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK) -		; - -	/* Disable smart idle */ -	regVal = readl(&uart_base->uartsyscfg); -	regVal |= UART_SMART_IDLE_EN; -	writel(regVal, &uart_base->uartsyscfg); +	uart_soft_reset();  	gd = &gdata; diff --git a/board/ti/panda/panda.c b/board/ti/panda/panda.c index 90ae29e7c..1da5b359c 100644 --- a/board/ti/panda/panda.c +++ b/board/ti/panda/panda.c @@ -37,6 +37,11 @@  #endif  #define PANDA_ULPI_PHY_TYPE_GPIO       182 +#define PANDA_BOARD_ID_1_GPIO          101 +#define PANDA_ES_BOARD_ID_1_GPIO        48 +#define PANDA_BOARD_ID_2_GPIO          171 +#define PANDA_ES_BOARD_ID_3_GPIO         3 +#define PANDA_ES_BOARD_ID_4_GPIO         2  DECLARE_GLOBAL_DATA_PTR; @@ -66,6 +71,73 @@ int board_eth_init(bd_t *bis)  	return 0;  } +/* +* Routine: get_board_revision +* Description: Detect if we are running on a panda revision A1-A6, +*              or an ES panda board. This can be done by reading +*              the level of GPIOs and checking the processor revisions. +*              This should result in: +*			Panda 4430: +*              GPIO171, GPIO101, GPIO182: 0 1 1 => A1-A5 +*              GPIO171, GPIO101, GPIO182: 1 0 1 => A6 +*			Panda ES: +*              GPIO2, GPIO3, GPIO171, GPIO48, GPIO182: 0 0 0 1 1 => B1/B2 +*              GPIO2, GPIO3, GPIO171, GPIO48, GPIO182: 0 0 1 1 1 => B3 +*/ +int get_board_revision(void) +{ +	int board_id0, board_id1, board_id2; +	int board_id3, board_id4; +	int board_id; + +	int processor_rev = omap_revision(); + +	/* Setup the mux for the common board ID pins (gpio 171 and 182) */ +	writew((IEN | M3), (*ctrl)->control_padconf_core_base + UNIPRO_TX0); +	writew((IEN | M3), (*ctrl)->control_padconf_core_base + FREF_CLK2_OUT); + +	board_id0 = gpio_get_value(PANDA_ULPI_PHY_TYPE_GPIO); +	board_id2 = gpio_get_value(PANDA_BOARD_ID_2_GPIO); + +	if ((processor_rev >= OMAP4460_ES1_0 && +	     processor_rev <= OMAP4460_ES1_1)) { +		/* +		 * Setup the mux for the ES specific board ID pins (gpio 101, +		 * 2 and 3. +		 */ +		writew((IEN | M3), (*ctrl)->control_padconf_core_base + +				GPMC_A24); +		writew((IEN | M3), (*ctrl)->control_padconf_core_base + +				UNIPRO_RY0); +		writew((IEN | M3), (*ctrl)->control_padconf_core_base + +				UNIPRO_RX1); + +		board_id1 = gpio_get_value(PANDA_ES_BOARD_ID_1_GPIO); +		board_id3 = gpio_get_value(PANDA_ES_BOARD_ID_3_GPIO); +		board_id4 = gpio_get_value(PANDA_ES_BOARD_ID_4_GPIO); + +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +		setenv("board_name", strcat(CONFIG_SYS_BOARD, "-es")); +#endif +		board_id = ((board_id4 << 4) | (board_id3 << 3) | +			(board_id2 << 2) | (board_id1 << 1) | (board_id0)); +	} else { +		/* Setup the mux for the Ax specific board ID pins (gpio 101) */ +		writew((IEN | M3), (*ctrl)->control_padconf_core_base + +				FREF_CLK2_OUT); + +		board_id1 = gpio_get_value(PANDA_BOARD_ID_1_GPIO); +		board_id = ((board_id2 << 2) | (board_id1 << 1) | (board_id0)); + +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +		if ((board_id >= 0x3) && (processor_rev == OMAP4430_ES2_3)) +			setenv("board_name", strcat(CONFIG_SYS_BOARD, "-a4")); +#endif +	} + +	return board_id; +} +  /**   * @brief misc_init_r - Configure Panda board specific configurations   * such as power configurations, ethernet initialization as phase2 of @@ -82,11 +154,7 @@ int misc_init_r(void)  	if (omap_revision() == OMAP4430_ES1_0)  		return 0; -#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG -	if (omap_revision() >= OMAP4460_ES1_0 || -		omap_revision() <= OMAP4460_ES1_1) -		setenv("board_name", strcat(CONFIG_SYS_BOARD, "-es")); -#endif +	get_board_revision();  	gpio_direction_input(PANDA_ULPI_PHY_TYPE_GPIO);  	phy_type = gpio_get_value(PANDA_ULPI_PHY_TYPE_GPIO); @@ -106,7 +174,7 @@ int misc_init_r(void)  		auxclk |= AUXCLK_ENABLE_MASK;  		writel(auxclk, &scrm->auxclk3); -       } else { +	} else {  		/* ULPI PHY supplied by auxclk1 derived from PER dpll */  		debug("ULPI PHY supplied by auxclk1\n"); @@ -151,9 +219,9 @@ void set_muxconf_regs_essential(void)  	if (omap_revision() >= OMAP4460_ES1_0)  		do_set_mux((*ctrl)->control_padconf_wkup_base, -				 wkup_padconf_array_essential_4460, -				 sizeof(wkup_padconf_array_essential_4460) / -				 sizeof(struct pad_conf_entry)); +			   wkup_padconf_array_essential_4460, +			   sizeof(wkup_padconf_array_essential_4460) / +			   sizeof(struct pad_conf_entry));  }  void set_muxconf_regs_non_essential(void) @@ -165,14 +233,14 @@ void set_muxconf_regs_non_essential(void)  	if (omap_revision() < OMAP4460_ES1_0)  		do_set_mux((*ctrl)->control_padconf_core_base, -				core_padconf_array_non_essential_4430, -				sizeof(core_padconf_array_non_essential_4430) / -				sizeof(struct pad_conf_entry)); +			   core_padconf_array_non_essential_4430, +			   sizeof(core_padconf_array_non_essential_4430) / +			   sizeof(struct pad_conf_entry));  	else  		do_set_mux((*ctrl)->control_padconf_core_base, -				core_padconf_array_non_essential_4460, -				sizeof(core_padconf_array_non_essential_4460) / -				sizeof(struct pad_conf_entry)); +			   core_padconf_array_non_essential_4460, +			   sizeof(core_padconf_array_non_essential_4460) / +			   sizeof(struct pad_conf_entry));  	do_set_mux((*ctrl)->control_padconf_wkup_base,  		   wkup_padconf_array_non_essential, @@ -181,9 +249,9 @@ void set_muxconf_regs_non_essential(void)  	if (omap_revision() < OMAP4460_ES1_0)  		do_set_mux((*ctrl)->control_padconf_wkup_base, -				wkup_padconf_array_non_essential_4430, -				sizeof(wkup_padconf_array_non_essential_4430) / -				sizeof(struct pad_conf_entry)); +			   wkup_padconf_array_non_essential_4430, +			   sizeof(wkup_padconf_array_non_essential_4430) / +			   sizeof(struct pad_conf_entry));  }  #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC) diff --git a/board/ti/ti814x/evm.c b/board/ti/ti814x/evm.c index 4759b167a..6ad3dd8fc 100644 --- a/board/ti/ti814x/evm.c +++ b/board/ti/ti814x/evm.c @@ -37,49 +37,16 @@ DECLARE_GLOBAL_DATA_PTR;  #ifdef CONFIG_SPL_BUILD  static struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; -static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;  #endif  static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;  /* UART Defines */  #ifdef CONFIG_SPL_BUILD -#define UART_RESET		(0x1 << 1) -#define UART_CLK_RUNNING_MASK	0x1 -#define UART_SMART_IDLE_EN	(0x1 << 0x3) - -static void rtc32k_enable(void) -{ -	struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE; - -	/* -	 * Unlock the RTC's registers.  For more details please see the -	 * RTC_SS section of the TRM.  In order to unlock we need to -	 * write these specific values (keys) in this order. -	 */ -	writel(0x83e70b13, &rtc->kick0r); -	writel(0x95a4f1e0, &rtc->kick1r); - -	/* Enable the RTC 32K OSC by setting bits 3 and 6. */ -	writel((1 << 3) | (1 << 6), &rtc->osc); -} -  static void uart_enable(void)  { -	u32 regVal; -  	/* UART softreset */ -	regVal = readl(&uart_base->uartsyscfg); -	regVal |= UART_RESET; -	writel(regVal, &uart_base->uartsyscfg); -	while ((readl(&uart_base->uartsyssts) & -		UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK) -		; - -	/* Disable smart idle */ -	regVal = readl(&uart_base->uartsyscfg); -	regVal |= UART_SMART_IDLE_EN; -	writel(regVal, &uart_base->uartsyscfg); +	uart_soft_reset();  }  static void wdt_disable(void) diff --git a/board/vpac270/u-boot-spl.lds b/board/vpac270/u-boot-spl.lds index 61d1154af..1a3ef9285 100644 --- a/board/vpac270/u-boot-spl.lds +++ b/board/vpac270/u-boot-spl.lds @@ -67,11 +67,6 @@ SECTIONS  		__rel_dyn_end = .;  	} -	.dynsym : { -		__dynsym_start = .; -		*(.dynsym) -	} -  	. = ALIGN(0x800);  	_end = .; @@ -84,6 +79,7 @@ SECTIONS  	}  	/DISCARD/ : { *(.bss*) } +	/DISCARD/ : { *(.dynsym) }  	/DISCARD/ : { *(.dynstr*) }  	/DISCARD/ : { *(.dynsym*) }  	/DISCARD/ : { *(.dynamic*) } diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 7d824690b..5f1ed430e 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -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 */ diff --git a/doc/device-tree-bindings/exynos/dwmmc.txt b/doc/device-tree-bindings/exynos/dwmmc.txt new file mode 100644 index 000000000..566da3b63 --- /dev/null +++ b/doc/device-tree-bindings/exynos/dwmmc.txt @@ -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. diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 4070d4ea5..5da20eda5 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -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); diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 72a31b73f..4238dd933 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -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, host->clksel_val); +} -	dwmci_writel(host, DWMCI_CLKSEL, val); +unsigned int exynos_dwmci_get_clk(int dev_index) +{ +	return get_mmc_clk(dev_index);  } -int exynos_dwmci_init(u32 regbase, int bus_width, int 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; +	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; -	add_dwmci(host, 52000000, 400000); +		/* 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 diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index e6a296a57..83d2df774 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1503,3 +1503,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 diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile index 90f83924e..ecbb2108f 100644 --- a/drivers/mtd/spi/Makefile +++ b/drivers/mtd/spi/Makefile @@ -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 diff --git a/drivers/mtd/spi/gigadevice.c b/drivers/mtd/spi/gigadevice.c new file mode 100644 index 000000000..b5e1ebedf --- /dev/null +++ b/drivers/mtd/spi/gigadevice.c @@ -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; +} diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 0e38f5948..9991d47a4 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -342,6 +342,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 diff --git a/drivers/mtd/spi/spi_flash_internal.h b/drivers/mtd/spi/spi_flash_internal.h index 141cfa8b2..e0afbc3d8 100644 --- a/drivers/mtd/spi/spi_flash_internal.h +++ b/drivers/mtd/spi/spi_flash_internal.h @@ -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); diff --git a/drivers/power/exynos-tmu.c b/drivers/power/exynos-tmu.c index d4b3e65a3..9a093a5bd 100644 --- a/drivers/power/exynos-tmu.c +++ b/drivers/power/exynos-tmu.c @@ -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(®->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(®->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, ®->triminfo_control); @@ -288,7 +316,7 @@ static void tmu_setup_parameters(struct tmu_info *info)  	/* TMU core enable */  	con = readl(®->tmu_control); -	con |= THERM_TRIP_EN | CORE_EN; +	con |= THERM_TRIP_EN | CORE_EN | (info->tmu_mux << 20);  	writel(con, ®->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;  } diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c index 3c41242a8..e65125ccd 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c @@ -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;  	} diff --git a/drivers/video/exynos_fb.c b/drivers/video/exynos_fb.c index ed0823bf9..c3606d5b0 100644 --- a/drivers/video/exynos_fb.c +++ b/drivers/video/exynos_fb.c @@ -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; diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index 4b3984454..3e32eee92 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -90,9 +90,6 @@ extern void _start(void);  extern ulong _rel_dyn_start_ofs;  extern ulong _rel_dyn_end_ofs; -/* Start/end of the relocation symbol table, as an offset from _start */ -extern ulong _dynsym_start_ofs; -  /* End of the region to be relocated, as an offset form _start */  extern ulong _image_copy_end_ofs; diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index d1246f7c7..9c3c2cd56 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -60,7 +60,7 @@  	"rdaddr=0x81000000\0" \  	"bootdir=/boot\0" \  	"bootfile=uImage\0" \ -	"fdtfile=\0" \ +	"fdtfile=undefined\0" \  	"console=ttyO0,115200n8\0" \  	"optargs=\0" \  	"mtdids=" MTDIDS_DEFAULT "\0" \ @@ -145,8 +145,9 @@  		"if test $board_name = A33515BB; then " \  			"setenv fdtfile am335x-evm.dtb; fi; " \  		"if test $board_name = A335X_SK; then " \ -			"setenv fdtfile am335x-evmsk.dtb; fi\0" \ - +			"setenv fdtfile am335x-evmsk.dtb; fi " \ +		"if test $fdtfile = undefined; then " \ +			"echo WARNING: Could not determine device tree to use; fi; \0"  #endif  #define CONFIG_BOOTCOMMAND \ diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h index 0eea28c80..c11f00553 100644 --- a/include/configs/dra7xx_evm.h +++ b/include/configs/dra7xx_evm.h @@ -41,4 +41,7 @@  #define CONFIG_BAUDRATE			115200  #define CONFIG_SYS_OMAP_ABE_SYSCK + +#define CONSOLEDEV		"ttyO0" +  #endif /* __CONFIG_DRA7XX_EVM_H */ diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h index 41d6cf9d1..163243572 100644 --- a/include/configs/exynos5250-dt.h +++ b/include/configs/exynos5250-dt.h @@ -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 diff --git a/include/configs/lacie_kw.h b/include/configs/lacie_kw.h index 09b5798d5..e2b3b2118 100644 --- a/include/configs/lacie_kw.h +++ b/include/configs/lacie_kw.h @@ -120,10 +120,14 @@  #endif  /* + * Enable platform initialisation via misc_init_r() function + */ +#define CONFIG_MISC_INIT_R + +/*   * Ethernet Driver configuration   */  #ifdef CONFIG_CMD_NET -#define CONFIG_MISC_INIT_R /* Call misc_init_r() to initialize MAC address */  #define CONFIG_MVGBE_PORTS		{1, 0} /* enable port 0 only */  #define CONFIG_NETCONSOLE  #endif @@ -153,6 +157,9 @@  #define CONFIG_SYS_I2C_EEPROM_ADDR		0x50  #define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS	4 /* 16-byte page size */  #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN		1 /* 8-bit device address */ +#if defined(CONFIG_NET2BIG_V2) +#define CONFIG_SYS_I2C_G762_ADDR		0x3e +#endif  #endif /* CONFIG_CMD_I2C */  /* diff --git a/include/configs/omap4_common.h b/include/configs/omap4_common.h index 3e5d36b21..2fa4382c3 100644 --- a/include/configs/omap4_common.h +++ b/include/configs/omap4_common.h @@ -150,6 +150,7 @@  	"console=ttyO2,115200n8\0" \  	"fdt_high=0xffffffff\0" \  	"fdtaddr=0x80f80000\0" \ +	"fdtfile=undefined\0" \  	"bootpart=0:2\0" \  	"bootdir=/boot\0" \  	"bootfile=zImage\0" \ @@ -177,8 +178,12 @@  			"setenv fdtfile omap4-sdp.dtb; fi; " \  		"if test $board_name = panda; then " \  			"setenv fdtfile omap4-panda.dtb; fi;" \ +		"if test $board_name = panda-a4; then " \ +			"setenv fdtfile omap4-panda-a4.dtb; fi;" \  		"if test $board_name = panda-es; then " \ -			"setenv fdtfile omap4-panda-es.dtb; fi; \0" \ +			"setenv fdtfile omap4-panda-es.dtb; fi;" \ +		"if test $fdtfile = undefined; then " \ +			"echo WARNING: Could not determine device tree to use; fi; \0" \  	"loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}\0" \  #define CONFIG_BOOTCOMMAND \ diff --git a/include/configs/omap5_common.h b/include/configs/omap5_common.h index ddf2ad4fc..b87ee4228 100644 --- a/include/configs/omap5_common.h +++ b/include/configs/omap5_common.h @@ -136,9 +136,10 @@  #define CONFIG_EXTRA_ENV_SETTINGS \  	"loadaddr=0x82000000\0" \ -	"console=ttyO2,115200n8\0" \ +	"console=" CONSOLEDEV ",115200n8\0" \  	"fdt_high=0xffffffff\0" \  	"fdtaddr=0x80f80000\0" \ +	"fdtfile=undefined\0" \  	"bootpart=0:2\0" \  	"bootdir=/boot\0" \  	"bootfile=zImage\0" \ @@ -166,7 +167,11 @@  		"bootz ${loadaddr} - ${fdtaddr}\0" \  	"findfdt="\  		"if test $board_name = omap5_uevm; then " \ -			"setenv fdtfile omap5-uevm.dtb; fi;\0 " \ +			"setenv fdtfile omap5-uevm.dtb; fi; " \ +		"if test $board_name = dra7xx; then " \ +			"setenv fdtfile dra7-evm.dtb; fi;" \ +		"if test $fdtfile = undefined; then " \ +			"echo WARNING: Could not determine device tree to use; fi; \0" \  	"loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile};\0" \  #define CONFIG_BOOTCOMMAND \ diff --git a/include/configs/omap5_uevm.h b/include/configs/omap5_uevm.h index dea05bc91..46dacc207 100644 --- a/include/configs/omap5_uevm.h +++ b/include/configs/omap5_uevm.h @@ -53,7 +53,9 @@  #define CONFIG_PARTITION_UUIDS  #define CONFIG_CMD_PART -#define CONFIG_SYS_PROMPT		"OMAP5430 EVM # " +#define CONFIG_SYS_PROMPT		"OMAP5432 uEVM # " + +#define CONSOLEDEV		"ttyO2"  #define CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC	16296  #endif /* __CONFIG_OMAP5_EVM_H */ diff --git a/include/configs/origen.h b/include/configs/origen.h index ff2b24d97..e179911d0 100644 --- a/include/configs/origen.h +++ b/include/configs/origen.h @@ -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 */ diff --git a/include/configs/smdkv310.h b/include/configs/smdkv310.h index b796b46a7..5e430660f 100644 --- a/include/configs/smdkv310.h +++ b/include/configs/smdkv310.h @@ -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 */ diff --git a/include/configs/trats.h b/include/configs/trats.h index fd58558be..c70838b91 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -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 */ diff --git a/include/dwmmc.h b/include/dwmmc.h index c8b1d408e..e142f3ec4 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -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; diff --git a/include/fdtdec.h b/include/fdtdec.h index 1ece6122f..8845e294b 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -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 */ diff --git a/include/mmc.h b/include/mmc.h index ea198d87b..583c30e27 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -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 @@ -162,6 +167,7 @@  #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */  #define EXT_CSD_RPMB_MULT		168	/* 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 */ @@ -187,6 +193,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) @@ -214,6 +230,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; @@ -298,6 +319,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 diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 005ad3d53..ad25a0c9c 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -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"), diff --git a/spl/Makefile b/spl/Makefile index d8fe948ff..01873de2b 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -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 |