diff --git a/Makefile b/Makefile index 693b3f2..fdaddb9 100644 --- a/Makefile +++ b/Makefile @@ -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 dc64160..e80e1ed 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 cf55bf7..367c805 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 673c725..f4e7525 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 967a135..446d095 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 885fb2d..b935a29 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 a1efc75..9c4d0b4 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 9119961..b2f9152 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 223660a..e1c4246 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 similarity index 69% rename from board/samsung/smdk5250/tzpc_init.c rename to arch/arm/cpu/armv7/exynos/tzpc.c index c833541..f5e8e9c 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 #include -#include"setup.h" +#include /* 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 1705399..0c38bd0 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 553589c..54bafda 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 1408f03..b6ed25f 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 d9bbee3..3037885 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 df4b231..cee4fe8 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 fedc674..307ac28 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 f76e489..36b98c8 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 8acdf9b..3b147b8 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 7e0158e..cad3569 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 c5eb4b1..4d9c3a3 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 8ad9f66..9ecafb2 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 4446da9..949b9e8 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 similarity index 79% rename from arch/arm/lib/bss.c rename to arch/arm/lib/sections.c index 99eda59..5921dd8 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 0000000..fb9bf8d --- /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 + * + * 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 +#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 0000000..e9e9b96 --- /dev/null +++ b/board/LaCie/common/cpld-gpio-bus.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2013 Simon Guinot + * + * 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 fbae48e..9a6dfb6 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 e524f35..b133f7c 100644 --- a/board/LaCie/net2big_v2/net2big_v2.c +++ b/board/LaCie/net2big_v2/net2big_v2.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -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 f9778f4..83537d6 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 ef4a25b..74aec5f 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 00ad8b7..c276501 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 44b990e..5610644 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 1daa1b3..3972685 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 b1b8701..6fa4509 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 596a9e0..b452f20 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 6d4b187..f359112 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 4969960..963d29f 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 826cead..ea3bea5 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 93c611d..0cca8d7 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 8da973b..93375a6 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 9daa0da..be9d418 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 930b948..926a4cc 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 47c6a5a..f2c32ee 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 5b9e82f..b288e66 100644 --- a/board/samsung/smdk5250/clock_init.c +++ b/board/samsung/smdk5250/clock_init.c @@ -28,10 +28,14 @@ #include #include #include +#include #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 f751bcb..20a1d47 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 0000000..8131505 --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 bc6cb6f..edc565e 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 34d8bc31..eb91d13 100644 --- a/board/samsung/smdk5250/setup.h +++ b/board/samsung/smdk5250/setup.h @@ -28,18 +28,6 @@ #include #include -/* 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 8b09e1d..276fd41 100644 --- a/board/samsung/smdk5250/smdk5250.c +++ b/board/samsung/smdk5250/smdk5250.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -37,39 +38,9 @@ #include #include #include -#include 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; - } - - err = s5p_mmc_init(0, 8); - return err; + ret |= 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; - - err = exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE); - if (err) { - debug("UART0 not configured\n"); - return err; + 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; + } } - - 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 c0bcf46..98f2286 100644 --- a/board/samsung/smdk5250/spl_boot.c +++ b/board/samsung/smdk5250/spl_boot.c @@ -23,16 +23,44 @@ #include #include +#include +#include +#include + +#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 7a1ea98..31e0e2e 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 638cc4d..fdbe26c 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 90ae29e..1da5b35 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 4759b16..6ad3dd8 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 61d1154..1a3ef92 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 7d82469..5f1ed43 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 \n" + " - Enable boot_part for booting and enable R/W access of boot_part\n" + "mmc close \n" + " - Enable boot_part for booting and disable access to boot_part\n" + "mmc bootpart \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 0000000..566da3b --- /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 4070d4e..5da20ed 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 72a31b7..4238dd9 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -19,39 +19,146 @@ */ #include -#include #include +#include +#include +#include #include #include +#include -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 e6a296a..83d2df7 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 90f8392..ecbb210 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 0000000..b5e1ebe --- /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 + * + * 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 +#include +#include + +#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 0e38f59..9991d47 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 141cfa8..e0afbc3 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 d4b3e65..9a093a5 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 3c41242..e65125c 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 ed0823b..c3606d5 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 4b39844..3e32eee 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 d1246f7..9c3c2cd 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 0eea28c..c11f005 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 41d6cf9..1632435 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 09b5798..e2b3b21 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 3e5d36b..2fa4382 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 ddf2ad4..b87ee42 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 dea05bc..46dacc2 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 ff2b24d..e179911 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 b796b46..5e43066 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 fd58558..c70838b 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 c8b1d40..e142f3e 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 1ece612..8845e29 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 ea198d8..583c30e 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 005ad3d..ad25a0c 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 d8fe948..01873de 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