Merge branch 'master' of git://git.denx.de/u-boot-arm

master
Tom Rini 11 years ago
commit 348e47f766
  1. 7
      Makefile
  2. 5
      arch/arm/config.mk
  3. 6
      arch/arm/cpu/arm920t/ep93xx/u-boot.lds
  4. 5
      arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds
  5. 5
      arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds
  6. 40
      arch/arm/cpu/armv7/am33xx/board.c
  7. 9
      arch/arm/cpu/armv7/am33xx/clock_am33xx.c
  8. 2
      arch/arm/cpu/armv7/exynos/Makefile
  9. 10
      arch/arm/cpu/armv7/exynos/clock.c
  10. 25
      arch/arm/cpu/armv7/exynos/tzpc.c
  11. 2
      arch/arm/cpu/armv7/s5p-common/Makefile
  12. 20
      arch/arm/cpu/ixp/u-boot.lds
  13. 6
      arch/arm/cpu/u-boot-spl.lds
  14. 21
      arch/arm/cpu/u-boot.lds
  15. 33
      arch/arm/dts/exynos5250.dtsi
  16. 4
      arch/arm/include/asm/arch-am33xx/sys_proto.h
  17. 4
      arch/arm/include/asm/arch-exynos/cpu.h
  18. 11
      arch/arm/include/asm/arch-exynos/dwmmc.h
  19. 58
      arch/arm/include/asm/arch-exynos/tmu.h
  20. 20
      arch/arm/include/asm/arch-exynos/tzpc.h
  21. 2
      arch/arm/lib/Makefile
  22. 61
      arch/arm/lib/relocate.S
  23. 8
      arch/arm/lib/sections.c
  24. 50
      board/LaCie/common/cpld-gpio-bus.c
  25. 24
      board/LaCie/common/cpld-gpio-bus.h
  26. 3
      board/LaCie/net2big_v2/Makefile
  27. 154
      board/LaCie/net2big_v2/net2big_v2.c
  28. 5
      board/LaCie/net2big_v2/net2big_v2.h
  29. 20
      board/actux1/u-boot.lds
  30. 20
      board/actux2/u-boot.lds
  31. 20
      board/actux3/u-boot.lds
  32. 5
      board/ait/cam_enc_4xx/u-boot-spl.lds
  33. 5
      board/davinci/da8xxevm/u-boot-spl-da850evm.lds
  34. 1
      board/davinci/da8xxevm/u-boot-spl-hawk.lds
  35. 20
      board/dvlhost/u-boot.lds
  36. 20
      board/freescale/mx31ads/u-boot.lds
  37. 40
      board/isee/igep0033/board.c
  38. 39
      board/phytec/pcm051/board.c
  39. 24
      board/samsung/dts/exynos5250-smdk5250.dts
  40. 44
      board/samsung/origen/lowlevel_init.S
  41. 25
      board/samsung/origen/origen_setup.h
  42. 5
      board/samsung/smdk5250/Makefile
  43. 18
      board/samsung/smdk5250/clock_init.c
  44. 5
      board/samsung/smdk5250/clock_init.h
  45. 423
      board/samsung/smdk5250/exynos5-dt.c
  46. 2
      board/samsung/smdk5250/lowlevel_init.S
  47. 25
      board/samsung/smdk5250/setup.h
  48. 223
      board/samsung/smdk5250/smdk5250.c
  49. 64
      board/samsung/smdk5250/spl_boot.c
  50. 60
      board/samsung/smdkv310/lowlevel_init.S
  51. 39
      board/ti/am335x/board.c
  52. 104
      board/ti/panda/panda.c
  53. 35
      board/ti/ti814x/evm.c
  54. 6
      board/vpac270/u-boot-spl.lds
  55. 109
      common/cmd_mmc.c
  56. 54
      doc/device-tree-bindings/exynos/dwmmc.txt
  57. 27
      drivers/mmc/dw_mmc.c
  58. 127
      drivers/mmc/exynos_dw_mmc.c
  59. 134
      drivers/mmc/mmc.c
  60. 1
      drivers/mtd/spi/Makefile
  61. 81
      drivers/mtd/spi/gigadevice.c
  62. 3
      drivers/mtd/spi/spi_flash.c
  63. 1
      drivers/mtd/spi/spi_flash_internal.h
  64. 123
      drivers/power/exynos-tmu.c
  65. 13
      drivers/serial/serial_s5p.c
  66. 4
      drivers/video/exynos_fb.c
  67. 3
      include/asm-generic/sections.h
  68. 7
      include/configs/am335x_evm.h
  69. 3
      include/configs/dra7xx_evm.h
  70. 11
      include/configs/exynos5250-dt.h
  71. 9
      include/configs/lacie_kw.h
  72. 7
      include/configs/omap4_common.h
  73. 9
      include/configs/omap5_common.h
  74. 4
      include/configs/omap5_uevm.h
  75. 2
      include/configs/origen.h
  76. 2
      include/configs/smdkv310.h
  77. 17
      include/configs/trats.h
  78. 3
      include/dwmmc.h
  79. 1
      include/fdtdec.h
  80. 26
      include/mmc.h
  81. 1
      lib/fdtdec.c
  82. 8
      spl/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))' ; \

@ -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

@ -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*) }

@ -57,11 +57,6 @@ SECTIONS
__rel_dyn_end = .;
}
.dynsym : {
__dynsym_start = .;
*(.dynsym)
}
.bss : {
. = ALIGN(4);
__bss_start = .;

@ -57,11 +57,6 @@ SECTIONS
__rel_dyn_end = .;
}
.dynsym : {
__dynsym_start = .;
*(.dynsym)
}
.bss : {
. = ALIGN(4);
__bss_start = .;

@ -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

@ -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;

@ -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))

@ -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;

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

@ -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))

@ -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*) }

@ -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*) }

@ -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*) }

@ -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>;
};
};

@ -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

@ -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 */

@ -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);

@ -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 */

@ -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

@ -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

@ -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)

@ -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")));

@ -0,0 +1,50 @@
/*
* cpld-gpio-bus.c: provides support for the CPLD GPIO bus found on some LaCie
* boards (as the 2Big/5Big Network v2 and the 2Big NAS). This parallel GPIO
* bus exposes two registers (address and data). Each of this register is made
* up of several dedicated GPIOs. An extra GPIO is used to notify the CPLD that
* the registers have been updated.
*
* Mostly this bus is used to configure the LEDs on LaCie boards.
*
* Copyright (C) 2013 Simon Guinot <simon.guinot@sequanux.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
#include <asm/arch/gpio.h>
#include "cpld-gpio-bus.h"
static void cpld_gpio_bus_set_addr(struct cpld_gpio_bus *bus, unsigned addr)
{
int pin;
for (pin = 0; pin < bus->num_addr; pin++)
kw_gpio_set_value(bus->addr[pin], (addr >> pin) & 1);
}
static void cpld_gpio_bus_set_data(struct cpld_gpio_bus *bus, unsigned data)
{
int pin;
for (pin = 0; pin < bus->num_data; pin++)
kw_gpio_set_value(bus->data[pin], (data >> pin) & 1);
}
static void cpld_gpio_bus_enable_select(struct cpld_gpio_bus *bus)
{
/* The transfer is enabled on the raising edge. */
kw_gpio_set_value(bus->enable, 0);
kw_gpio_set_value(bus->enable, 1);
}
void cpld_gpio_bus_write(struct cpld_gpio_bus *bus,
unsigned addr, unsigned value)
{
cpld_gpio_bus_set_addr(bus, addr);
cpld_gpio_bus_set_data(bus, value);
cpld_gpio_bus_enable_select(bus);
}

@ -0,0 +1,24 @@
/*
* Copyright (C) 2013 Simon Guinot <simon.guinot@sequanux.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
#ifndef _LACIE_CPLD_GPI0_BUS_H
#define _LACIE_CPLD_GPI0_BUS_H
struct cpld_gpio_bus {
unsigned *addr;
unsigned num_addr;
unsigned *data;
unsigned num_data;
unsigned enable;
};
void cpld_gpio_bus_write(struct cpld_gpio_bus *cpld_gpio_bus,
unsigned addr, unsigned value);
#endif /* _LACIE_CPLD_GPI0_BUS_H */

@ -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))

@ -22,6 +22,7 @@
#include <common.h>
#include <command.h>
#include <i2c.h>
#include <asm/arch/cpu.h>
#include <asm/arch/kirkwood.h>
#include <asm/arch/mpp.h>
@ -29,6 +30,7 @@
#include "net2big_v2.h"
#include "../common/common.h"
#include "../common/cpld-gpio-bus.h"
DECLARE_GLOBAL_DATA_PTR;
@ -60,18 +62,18 @@ int board_early_init_f(void)
MPP24_GPIO, /* USB mode select */
MPP26_GPIO, /* USB device vbus */
MPP28_GPIO, /* USB enable host vbus */
MPP29_GPIO, /* GPIO extension ALE */
MPP29_GPIO, /* CPLD GPIO bus ALE */
MPP34_GPIO, /* Rear Push button 0=on 1=off */
MPP35_GPIO, /* Inhibit switch power-off */
MPP36_GPIO, /* SATA HDD1 presence */
MPP37_GPIO, /* SATA HDD2 presence */
MPP40_GPIO, /* eSATA presence */
MPP44_GPIO, /* GPIO extension (data 0) */
MPP45_GPIO, /* GPIO extension (data 1) */
MPP46_GPIO, /* GPIO extension (data 2) */
MPP47_GPIO, /* GPIO extension (addr 0) */
MPP48_GPIO, /* GPIO extension (addr 1) */
MPP49_GPIO, /* GPIO extension (addr 2) */
MPP44_GPIO, /* CPLD GPIO bus (data 0) */
MPP45_GPIO, /* CPLD GPIO bus (data 1) */
MPP46_GPIO, /* CPLD GPIO bus (data 2) */
MPP47_GPIO, /* CPLD GPIO bus (addr 0) */
MPP48_GPIO, /* CPLD GPIO bus (addr 1) */
MPP49_GPIO, /* CPLD GPIO bus (addr 2) */
0
};
@ -92,8 +94,142 @@ int board_init(void)
}
#if defined(CONFIG_MISC_INIT_R)
#if defined(CONFIG_CMD_I2C) && defined(CONFIG_SYS_I2C_G762_ADDR)
/*
* Start I2C fan (GMT G762 controller)
*/
static void init_fan(void)
{
u8 data;
i2c_set_bus_num(0);
/* Enable open-loop and PWM modes */
data = 0x20;
if (i2c_write(CONFIG_SYS_I2C_G762_ADDR,
G762_REG_FAN_CMD1, 1, &data, 1) != 0)
goto err;
data = 0;
if (i2c_write(CONFIG_SYS_I2C_G762_ADDR,
G762_REG_SET_CNT, 1, &data, 1) != 0)
goto err;
/*
* RPM to PWM (set_out register) fan speed conversion array:
* 0 0x00
* 1500 0x04
* 2800 0x08
* 3400 0x0C
* 3700 0x10
* 4400 0x20
* 4700 0x30
* 4800 0x50
* 5200 0x80
* 5400 0xC0
* 5500 0xFF
*
* Start fan at low speed (2800 RPM):
*/
data = 0x08;
if (i2c_write(CONFIG_SYS_I2C_G762_ADDR,
G762_REG_SET_OUT, 1, &data, 1) != 0)
goto err;
return;
err:
printf("Error: failed to start I2C fan @%02x\n",
CONFIG_SYS_I2C_G762_ADDR);
}
#else
static void init_fan(void) {}
#endif /* CONFIG_CMD_I2C && CONFIG_SYS_I2C_G762_ADDR */
#if defined(CONFIG_NET2BIG_V2) && defined(CONFIG_KIRKWOOD_GPIO)
/*
* CPLD GPIO bus:
*
* - address register : bit [0-2] -> GPIO [47-49]
* - data register : bit [0-2] -> GPIO [44-46]
* - enable register : GPIO 29
*/
static unsigned cpld_gpio_bus_addr[] = { 47, 48, 49 };
static unsigned cpld_gpio_bus_data[] = { 44, 45, 46 };
static struct cpld_gpio_bus cpld_gpio_bus = {
.addr = cpld_gpio_bus_addr,
.num_addr = ARRAY_SIZE(cpld_gpio_bus_addr),
.data = cpld_gpio_bus_data,
.num_data = ARRAY_SIZE(cpld_gpio_bus_data),
.enable = 29,
};
/*
* LEDs configuration:
*
* The LEDs are controlled by a CPLD and can be configured through
* the CPLD GPIO bus.
*
* Address register selection:
*
* addr | register
* ----------------------------
* 0 | front LED
* 1 | front LED brightness
* 2 | SATA LED brightness
* 3 | SATA0 LED
* 4 | SATA1 LED
* 5 | SATA2 LED
* 6 | SATA3 LED
* 7 | SATA4 LED
*
* Data register configuration:
*
* data | LED brightness
* -------------------------------------------------
* 0 | min (off)
* - | -
* 7 | max
*
* data | front LED mode
* -------------------------------------------------
* 0 | fix off
* 1 | fix blue on
* 2 | fix red on
* 3 | blink blue on=1 sec and blue off=1 sec
* 4 | blink red on=1 sec and red off=1 sec
* 5 | blink blue on=2.5 sec and red on=0.5 sec
* 6 | blink blue on=1 sec and red on=1 sec
* 7 | blink blue on=0.5 sec and blue off=2.5 sec
*
* data | SATA LED mode
* -------------------------------------------------
* 0 | fix off
* 1 | SATA activity blink
* 2 | fix red on
* 3 | blink blue on=1 sec and blue off=1 sec
* 4 | blink red on=1 sec and red off=1 sec
* 5 | blink blue on=2.5 sec and red on=0.5 sec
* 6 | blink blue on=1 sec and red on=1 sec
* 7 | fix blue on
*/
static void init_leds(void)
{
/* Enable the front blue LED */
cpld_gpio_bus_write(&cpld_gpio_bus, 0, 1);
cpld_gpio_bus_write(&cpld_gpio_bus, 1, 3);
/* Configure SATA LEDs to blink in relation with the SATA activity */
cpld_gpio_bus_write(&cpld_gpio_bus, 3, 1);
cpld_gpio_bus_write(&cpld_gpio_bus, 4, 1);
cpld_gpio_bus_write(&cpld_gpio_bus, 2, 3);
}
#else
static void init_leds(void) {}
#endif /* CONFIG_NET2BIG_V2 && CONFIG_KIRKWOOD_GPIO */
int misc_init_r(void)
{
init_fan();
#if defined(CONFIG_CMD_I2C) && defined(CONFIG_SYS_I2C_EEPROM_ADDR)
if (!getenv("ethaddr")) {
uchar mac[6];
@ -101,9 +237,11 @@ int misc_init_r(void)
eth_setenv_enetaddr("ethaddr", mac);
}
#endif
init_leds();
return 0;
}
#endif
#endif /* CONFIG_MISC_INIT_R */
#if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R)
/* Configure and initialize PHY */

@ -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 */

@ -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*) }

@ -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*) }

@ -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*) }

@ -54,11 +54,6 @@ SECTIONS
__rel_dyn_end = .;
} >.sram
.dynsym : {
__dynsym_start = .;
*(.dynsym)
} >.sram
.bss :
{
. = ALIGN(4);

@ -55,11 +55,6 @@ SECTIONS
__rel_dyn_end = .;
} >.sram
.dynsym : {
__dynsym_start = .;
*(.dynsym)
} >.sram
.bss :
{
. = ALIGN(4);

@ -61,7 +61,6 @@ SECTIONS
__image_copy_end = .;
__rel_dyn_start = .;
__rel_dyn_end = .;
__dynsym_start = .;
__got_start = .;
. = ALIGN(4);

@ -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*) }

@ -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*) }

@ -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();

@ -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;

@ -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";
};
};

@ -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

@ -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

@ -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

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

@ -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

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

@ -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:

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

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

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

@ -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

@ -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;

@ -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)

@ -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)

@ -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*) }

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

@ -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.

@ -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);

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

@ -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

@ -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

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

@ -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

@ -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);

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

@ -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;
}

@ -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;

@ -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;

@ -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 \

@ -41,4 +41,7 @@
#define CONFIG_BAUDRATE 115200
#define CONFIG_SYS_OMAP_ABE_SYSCK
#define CONSOLEDEV "ttyO0"
#endif /* __CONFIG_DRA7XX_EVM_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

@ -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 */
/*

@ -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 \

@ -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 \

@ -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 */

@ -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 */

@ -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 */

@ -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 */

@ -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;

@ -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 */

@ -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

@ -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"),

@ -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

Loading…
Cancel
Save