Hi Simon, Thank you for comments.
On Thu, Jan 10, 2013 at 11:04 PM, Simon Glass <s...@chromium.org> wrote: > Hi Rajeshwari, > > On Mon, Jan 7, 2013 at 5:08 AM, Rajeshwari Shinde > <rajeshwar...@samsung.com> wrote: >> This patch converts lowlevel_init.S to lowlevel_init_c.c for >> SMDK5250. >> Lowlevel.S as of now added only for SMDK5250 and same can be >> extended to other SOC in future. > > Should perhaps also mention new feature (controllable memory reset for > resume?) -OK > >> >> Signed-off-by: Rajeshwari Shinde <rajeshwar...@samsung.com> >> --- >> Changes in V2: >> - Renamed lowlevel_init.S to lowlevel.S and moved to >> arch/arm/cpu/armv7/exynos/ >> - Moved power mode defines to power.h >> - Added early serial support. >> - Renamed mem_reset to reset. >> arch/arm/cpu/armv7/exynos/Makefile | 6 ++ >> arch/arm/cpu/armv7/exynos/lowlevel.S | 35 ++++++++ >> arch/arm/include/asm/arch-exynos/power.h | 8 ++ >> board/samsung/smdk5250/Makefile | 2 +- >> board/samsung/smdk5250/dmc_common.c | 4 +- >> board/samsung/smdk5250/dmc_init_ddr3.c | 6 +- >> board/samsung/smdk5250/lowlevel_init.S | 96 -------------------- >> board/samsung/smdk5250/lowlevel_init.c | 81 +++++++++++++++++ > > Any change we could move all of this to arch/arm/cpu/armv7/exynos...? We do not have a separate directory for exynos5 and exynos4 and if we add all these files in arch/arm/cpu/armv7/exynos it would break the compilation for EXYNOS4. Also Later versions of exynos5 have different memory and timing variants. > > It really doesn't relate to this board alone, but to the chip. > >> board/samsung/smdk5250/setup.h | 19 ++++- >> board/samsung/smdk5250/spl_boot.c | 140 >> +++++++++++++++++++++++++++-- >> spl/Makefile | 4 + >> 11 files changed, 288 insertions(+), 113 deletions(-) >> create mode 100644 arch/arm/cpu/armv7/exynos/lowlevel.S >> delete mode 100644 board/samsung/smdk5250/lowlevel_init.S >> create mode 100644 board/samsung/smdk5250/lowlevel_init.c >> >> diff --git a/arch/arm/cpu/armv7/exynos/Makefile >> b/arch/arm/cpu/armv7/exynos/Makefile >> index 9119961..2aa2722 100644 >> --- a/arch/arm/cpu/armv7/exynos/Makefile >> +++ b/arch/arm/cpu/armv7/exynos/Makefile >> @@ -22,6 +22,12 @@ include $(TOPDIR)/config.mk >> >> LIB = $(obj)lib$(SOC).o >> >> +ifdef CONFIG_SMDK5250 >> +ifdef CONFIG_SPL >> +COBJS += lowlevel.o > > Could do: > > COBJS-$(CONFIG_SPL) += lowlevel.o > > and remove the inner ifdef - OK > >> +endif >> +endif >> + >> COBJS += clock.o power.o soc.o system.o pinmux.o >> >> SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) >> diff --git a/arch/arm/cpu/armv7/exynos/lowlevel.S >> b/arch/arm/cpu/armv7/exynos/lowlevel.S >> new file mode 100644 >> index 0000000..7307959 >> --- /dev/null >> +++ b/arch/arm/cpu/armv7/exynos/lowlevel.S >> @@ -0,0 +1,35 @@ >> +/* >> + * Lowlevel setup for SMDK5250 board based on S5PC520 >> + * >> + * 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 <config.h> >> +#include <asm/arch/cpu.h> >> + >> + .globl lowlevel_init >> +lowlevel_init: >> + /* >> + * Set the stack pointer, although it will be overwritten by the >> caller >> + * It seems we will not boot if this function is empty. >> + */ >> + ldr sp, =CONFIG_IRAM_STACK >> + mov pc, lr >> diff --git a/arch/arm/include/asm/arch-exynos/power.h >> b/arch/arm/include/asm/arch-exynos/power.h >> index f6d0278..d6fd29e 100644 >> --- a/arch/arm/include/asm/arch-exynos/power.h >> +++ b/arch/arm/include/asm/arch-exynos/power.h >> @@ -874,4 +874,12 @@ void power_ps_hold_setup(void); >> >> /* Read the resume function and call it */ >> void power_exit_wakeup(void); >> + >> + >> +/* Power Down Modes >> + * User defined values in inform1 register >> + */ >> +#define EXYNOS_CHECK_SLEEP 0x00000BAD >> +#define EXYNOS_CHECK_DIDLE 0xBAD00000 >> +#define EXYNOS_CHECK_LPA 0xABAD0000 >> #endif >> diff --git a/board/samsung/smdk5250/Makefile >> b/board/samsung/smdk5250/Makefile >> index 47c6a5a..7eaef09 100644 >> --- a/board/samsung/smdk5250/Makefile >> +++ b/board/samsung/smdk5250/Makefile >> @@ -24,7 +24,6 @@ include $(TOPDIR)/config.mk >> >> LIB = $(obj)lib$(BOARD).o >> >> -SOBJS := lowlevel_init.o >> >> COBJS := clock_init.o >> COBJS += dmc_common.o dmc_init_ddr3.o >> @@ -37,6 +36,7 @@ endif >> >> ifdef CONFIG_SPL_BUILD >> COBJS += spl_boot.o >> +COBJS += lowlevel_init.o > > Can you use this form instead of ifdef here? > > COBJS-$(CONFIG_SPL) += lowlevel_init.o > > >> endif >> >> SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) >> diff --git a/board/samsung/smdk5250/dmc_common.c >> b/board/samsung/smdk5250/dmc_common.c >> index 109602a..f637bf9 100644 >> --- a/board/samsung/smdk5250/dmc_common.c >> +++ b/board/samsung/smdk5250/dmc_common.c >> @@ -175,7 +175,7 @@ void dmc_config_memory(struct mem_timings *mem, struct >> exynos5_dmc *dmc) >> writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1); >> } >> >> -void mem_ctrl_init() >> +void mem_ctrl_init(int reset) >> { >> struct spl_machine_param *param = spl_get_machine_params(); >> struct mem_timings *mem; >> @@ -185,7 +185,7 @@ void mem_ctrl_init() >> >> /* If there are any other memory variant, add their init call below >> */ >> if (param->mem_type == DDR_MODE_DDR3) { >> - ret = ddr3_mem_ctrl_init(mem, param->mem_iv_size); >> + ret = ddr3_mem_ctrl_init(mem, param->mem_iv_size, reset); >> if (ret) { >> /* will hang if failed to init memory control */ >> while (1) >> diff --git a/board/samsung/smdk5250/dmc_init_ddr3.c >> b/board/samsung/smdk5250/dmc_init_ddr3.c >> index e050790..a5a70df 100644 >> --- a/board/samsung/smdk5250/dmc_init_ddr3.c >> +++ b/board/samsung/smdk5250/dmc_init_ddr3.c >> @@ -40,7 +40,8 @@ static void reset_phy_ctrl(void) >> writel(DDR3PHY_CTRL_PHY_RESET, &clk->lpddr3phy_ctrl); >> } >> >> -int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size) >> +int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size, >> + int reset) >> { >> unsigned int val; >> struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl; >> @@ -51,7 +52,8 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned >> long mem_iv_size) >> phy1_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY1_BASE; >> dmc = (struct exynos5_dmc *)EXYNOS5_DMC_CTRL_BASE; >> >> - reset_phy_ctrl(); >> + if (reset) >> + reset_phy_ctrl(); >> >> /* Set Impedance Output Driver */ >> val = (mem->impedance << CA_CK_DRVR_DS_OFFSET) | >> diff --git a/board/samsung/smdk5250/lowlevel_init.S >> b/board/samsung/smdk5250/lowlevel_init.S >> deleted file mode 100644 >> index bc6cb6f..0000000 >> --- a/board/samsung/smdk5250/lowlevel_init.S >> +++ /dev/null >> @@ -1,96 +0,0 @@ >> -/* >> - * Lowlevel setup for SMDK5250 board based on S5PC520 >> - * >> - * 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 <config.h> >> -#include <version.h> >> -#include <asm/arch/cpu.h> >> - >> -_TEXT_BASE: >> - .word CONFIG_SYS_TEXT_BASE >> - >> - .globl lowlevel_init >> -lowlevel_init: >> - >> - /* use iRAM stack in bl2 */ >> - ldr sp, =CONFIG_IRAM_STACK >> - stmdb r13!, {ip,lr} >> - >> - /* check reset status */ >> - ldr r0, =(EXYNOS5_POWER_BASE + INFORM1_OFFSET) >> - ldr r1, [r0] >> - >> - /* AFTR wakeup reset */ >> - ldr r2, =S5P_CHECK_DIDLE >> - cmp r1, r2 >> - beq exit_wakeup >> - >> - /* LPA wakeup reset */ >> - ldr r2, =S5P_CHECK_LPA >> - cmp r1, r2 >> - beq exit_wakeup >> - >> - /* Sleep wakeup reset */ >> - ldr r2, =S5P_CHECK_SLEEP >> - cmp r1, r2 >> - beq wakeup_reset >> - >> - /* >> - * If U-boot is already running in RAM, no need to relocate U-Boot. >> - * Memory controller must be configured before relocating U-Boot >> - * in ram. >> - */ >> - ldr r0, =0x0ffffff /* r0 <- Mask Bits*/ >> - bic r1, pc, r0 /* pc <- current addr of code */ >> - /* r1 <- unmasked bits of pc */ >> - ldr r2, _TEXT_BASE /* r2 <- original base addr in ram */ >> - bic r2, r2, r0 /* r2 <- unmasked bits of r2*/ >> - cmp r1, r2 /* compare r1, r2 */ >> - beq 1f /* r0 == r1 then skip sdram init */ >> - >> - /* init system clock */ >> - bl system_clock_init >> - >> - /* Memory initialize */ >> - bl mem_ctrl_init >> - >> -1: >> - bl tzpc_init >> - ldmia r13!, {ip,pc} >> - >> -wakeup_reset: >> - bl system_clock_init >> - bl mem_ctrl_init >> - bl tzpc_init >> - >> -exit_wakeup: >> - /* Load return address and jump to kernel */ >> - ldr r0, =(EXYNOS5_POWER_BASE + INFORM0_OFFSET) >> - >> - /* r1 = physical address of exynos5_cpu_resume function*/ >> - ldr r1, [r0] >> - >> - /* Jump to kernel */ >> - mov pc, r1 >> - nop >> - nop >> diff --git a/board/samsung/smdk5250/lowlevel_init.c >> b/board/samsung/smdk5250/lowlevel_init.c >> new file mode 100644 >> index 0000000..22bdd2b >> --- /dev/null >> +++ b/board/samsung/smdk5250/lowlevel_init.c >> @@ -0,0 +1,81 @@ >> +/* >> + * Lowlevel setup for SMDK5250 board based on S5PC520 >> + * >> + * Copyright (C) 2012 Samsung Electronics >> + * Copyright (c) 2012 The Chromium OS Authors. >> + * >> + * 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 <config.h> >> +#include <asm/arch/cpu.h> >> +#include <asm/arch/dmc.h> >> +#include <asm/arch/power.h> >> +#include <asm/arch/tzpc.h> >> +#include <asm/arch/periph.h> >> +#include <asm/arch/pinmux.h> >> +#include "setup.h" >> + >> +/* These are the things we can do during low-level init */ >> +enum { >> + DO_WAKEUP = 1 << 0, >> + DO_CLOCKS = 1 << 1, >> + DO_MEM_RESET = 1 << 2, >> + DO_UART = 1 << 3, >> +}; >> + >> +int do_lowlevel_init(void) >> +{ >> + uint32_t reset_status; >> + int actions = 0; >> + >> + arch_cpu_init(); >> + >> + reset_status = power_read_reset_status(); >> + >> + switch (reset_status) { >> + case EXYNOS_CHECK_SLEEP: >> + actions = DO_CLOCKS | DO_WAKEUP; >> + break; >> + case EXYNOS_CHECK_DIDLE: >> + case EXYNOS_CHECK_LPA: >> + actions = DO_WAKEUP; >> + break; >> + default: >> + /* This is a normal boot (not a wake from sleep) */ >> + actions = DO_CLOCKS | DO_MEM_RESET | DO_UART; >> + } >> + >> + if (actions & DO_CLOCKS) >> + system_clock_init(); >> + >> + if (actions & DO_UART) { >> + exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE); >> + serial_init(); >> + timer_init(); >> + } >> + >> + if (actions & DO_CLOCKS) { >> + mem_ctrl_init(actions & DO_MEM_RESET); >> + tzpc_init(); > > I think serial SPL support is coming later. So you want to initialise serial SPL support after mem_ctrl_init and tzpc_init? > >> + } >> + >> + return actions & DO_WAKEUP; >> +} >> diff --git a/board/samsung/smdk5250/setup.h b/board/samsung/smdk5250/setup.h >> index a159601..f1d9f79 100644 >> --- a/board/samsung/smdk5250/setup.h >> +++ b/board/samsung/smdk5250/setup.h >> @@ -537,9 +537,11 @@ enum { >> * which the DMC uses to decide how to split a memory >> * chunk into smaller chunks to support concurrent >> * accesses; may vary across boards. >> + * @param reset Reset DDR PHY during initialization. >> * @return 0 if ok, SETUP_ERR_... if there is a problem >> */ >> -int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size); >> +int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size, >> + int reset); >> >> /* >> * Configure ZQ I/O interface >> @@ -587,8 +589,21 @@ void dmc_config_memory(struct mem_timings *mem, struct >> exynos5_dmc *dmc); >> */ >> void update_reset_dll(struct exynos5_dmc *, enum ddr_mode); >> >> +/* >> + * Memory initialization >> + * >> + * @param reset Reset PHY during initialization. >> + */ >> +void mem_ctrl_init(int reset); >> + >> void sdelay(unsigned long); >> -void mem_ctrl_init(void); >> void system_clock_init(void); >> void tzpc_init(void); >> + >> +/** >> + * Init subsystems according to the reset status >> + * >> + * @return 0 for a normal boot, non-zero for a resume >> + */ >> +int do_lowlevel_init(void); >> #endif >> diff --git a/board/samsung/smdk5250/spl_boot.c >> b/board/samsung/smdk5250/spl_boot.c >> index d8f3c1e..a1c8d3d 100644 >> --- a/board/samsung/smdk5250/spl_boot.c >> +++ b/board/samsung/smdk5250/spl_boot.c >> @@ -20,18 +20,16 @@ >> * MA 02111-1307 USA >> */ >> >> -#include<common.h> >> -#include<config.h> >> +#include <common.h> >> +#include <config.h> >> +#include <asm/arch/spl.h> >> +#include <asm/arch/cpu.h> >> +#include <asm/arch/power.h> >> +#include "setup.h" >> >> -enum boot_mode { >> - BOOT_MODE_MMC = 4, >> - BOOT_MODE_SERIAL = 20, >> - /* Boot based on Operating Mode pin settings */ >> - BOOT_MODE_OM = 32, >> - BOOT_MODE_USB, /* Boot using USB download */ >> -}; >> +DECLARE_GLOBAL_DATA_PTR; >> >> - typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst); >> +typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst); > > What is happening with thsi file? I think there is another patch which > changes things here. > >> >> /* >> * Copy U-boot from mmc to RAM: >> @@ -62,15 +60,49 @@ void copy_uboot_to_ram(void) >> } >> } >> >> +void memzero(void *s, size_t n) >> +{ >> + char *ptr = s; >> + size_t i; >> + >> + for (i = 0; i < n; i++) >> + *ptr++ = '\0'; >> +} >> + >> +/** >> + * Set up the U-Boot global_data pointer >> + * >> + * This sets the address of the global data, and sets up basic values. >> + * >> + * @param gdp Value to give to gd >> + */ >> +static void setup_global_data(gd_t *gdp) >> +{ >> + gd = gdp; >> + memzero((void *)gd, sizeof(gd_t)); >> + gd->flags |= GD_FLG_RELOC; >> + gd->baudrate = CONFIG_BAUDRATE; >> + gd->have_console = 1; >> +} >> + >> void board_init_f(unsigned long bootflag) >> { >> + __attribute__((aligned(8))) gd_t local_gd; >> __attribute__((noreturn)) void (*uboot)(void); >> + >> + setup_global_data(&local_gd); >> + >> + if (do_lowlevel_init()) >> + power_exit_wakeup(); >> + >> copy_uboot_to_ram(); >> >> /* Jump to U-Boot image */ >> uboot = (void *)CONFIG_SYS_TEXT_BASE; >> (*uboot)(); >> + >> /* Never returns Here */ >> + panic("%s: u-boot jump failed", __func__); >> } >> >> /* Place Holders */ >> @@ -83,3 +115,91 @@ void board_init_r(gd_t *id, ulong dest_addr) >> } >> >> void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {} >> + >> +/* >> + * The following functions are required when linking console library to SPL. >> + * >> + * Enabling UART in SPL u-boot requires console library. But some >> + * functions we needed in the console library depends on a bunch >> + * of library in libgeneric, like lib/ctype.o, lib/div64.o, lib/string.o, >> + * and lib/vsprintf.o. Adding them makes the SPL u-boot too large and not >> + * fit into the expected size. >> + * >> + * So we mock these functions in SPL, i.e. vsprintf(), panic(), etc., >> + * in order to cut its dependency. >> + */ >> +static int _vscnprintf(char *buf, size_t size, const char *fmt, va_list >> args) >> +{ >> + char *str = buf, *s; >> + char *end = str + size - 1; >> + ulong u; >> + >> + if (size == 0) >> + return -1; >> + >> + /* >> + * We won't implement all full functions of vsprintf(). >> + * We only implement %s and %u, and ignore others and directly use >> + * the original format string as its result. >> + */ >> + >> + while (*fmt && (str < end)) { >> + if (*fmt != '%') { >> + *str++ = *fmt++; >> + continue; >> + } >> + fmt++; >> + switch (*fmt) { >> + case '%': >> + *str++ = *fmt++; >> + break; >> + case 's': >> + fmt++; >> + s = va_arg(args, char *); >> + while (*s && (str < end)) >> + *str++ = *s++; >> + break; >> + case 'u': >> + fmt++; >> + u = va_arg(args, ulong); >> + s = simple_itoa(u); >> + while (*s && (str < end)) >> + *str++ = *s++; >> + break; >> + default: >> + /* Print the original string for unsupported formats >> */ >> + *str++ = '%'; >> + if (str < end) >> + *str++ = *fmt++; >> + } >> + } >> + *str = '\0'; >> + return str - buf; >> +} >> + >> +/* Implement vsprintf in case someone doesn't have CONFIG_SYS_VSNPRINTF */ >> +int vsprintf(char *buf, const char *fmt, va_list args) >> +{ >> + return _vscnprintf(buf, CONFIG_SYS_PBSIZE, fmt, args); >> +} > > This is ready for use by SPL serial support, right? Yes it is. > >> + >> +char *simple_itoa(ulong i) >> +{ >> + /* 21 digits plus null terminator, good for 64-bit or smaller ints */ >> + static char local[22] __attribute__((section(".data"))); >> + char *p = &local[21]; >> + >> + *p-- = '\0'; >> + do { >> + *p-- = '0' + i % 10; >> + i /= 10; >> + } while (i > 0); >> + return p + 1; >> +} >> + >> +void hang(void) >> +{ >> + puts("### ERROR ### Please RESET the board ###\n"); >> + for (;;) >> + ; >> +} >> diff --git a/spl/Makefile b/spl/Makefile >> index 6dbb105..3aab466 100644 >> --- a/spl/Makefile >> +++ b/spl/Makefile >> @@ -86,6 +86,10 @@ ifneq >> ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) >> LIBS-y += $(CPUDIR)/omap-common/libomap-common.o >> endif >> >> +ifneq ($(CONFIG_EXYNOS4)$(CONFIG_EXYNOS5),) >> +LIBS-y += $(CPUDIR)/s5p-common/libs5p-common.o >> +endif >> + >> ifeq ($(SOC),tegra20) >> LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o >> LIBS-y += arch/$(ARCH)/cpu/tegra-common/libcputegra-common.o >> -- >> 1.7.4.4 >> > > Regards, > Simon > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot -- Regards, Rajeshwari Shinde _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot