Message ID | 1357564126-13275-3-git-send-email-rajeshwari.s@samsung.com |
---|---|
State | New |
Headers | show |
Hi Rajeshwari, On Mon, Jan 7, 2013 at 5:08 AM, Rajeshwari Shinde <rajeshwari.s@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?) > > Signed-off-by: Rajeshwari Shinde <rajeshwari.s@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...? 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 > +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. > + } > + > + 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? > + > +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
Dear Rajeshwari, On 07/01/13 22:08, Rajeshwari Shinde 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. > > Signed-off-by: Rajeshwari Shinde <rajeshwari.s@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 +++++++++++++++++ > 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 Is it SMDK5250 specific? > +ifdef CONFIG_SPL > +COBJS += lowlevel.o It's a SOBJS. > +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 please fix this comment. Maybe this file is not a board specific. > + * > + * 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/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(); > + } > + > + return actions & DO_WAKEUP; > +} > 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); > > /* > * 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++; > + } > + } indentation error. > + *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); > +} > + > +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 (;;) > + ; > +} Thanks, Minkyu Kang.
Hi Minkyu Kang, Thank you for comments. On Fri, Jan 11, 2013 at 1:24 PM, Minkyu Kang <mk7.kang@samsung.com> wrote: > Dear Rajeshwari, > > On 07/01/13 22:08, Rajeshwari Shinde 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. >> >> Signed-off-by: Rajeshwari Shinde <rajeshwari.s@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 +++++++++++++++++ >> 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 > > Is it SMDK5250 specific? - Yes, As mentioned in the commit message it is currently been done only for SMDK5250 and can be also extended to other SOC in Future. > >> +ifdef CONFIG_SPL >> +COBJS += lowlevel.o > > It's a SOBJS. - 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 > > please fix this comment. > Maybe this file is not a board specific. -Ok > >> + * >> + * 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/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(); >> + } >> + >> + return actions & DO_WAKEUP; >> +} >> 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); >> >> /* >> * 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++; >> + } >> + } > > indentation error. Ok > >> + *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); >> +} >> + >> +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 (;;) >> + ; >> +} > > Thanks, > Minkyu Kang. > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot
Hi Simon, Thank you for comments. On Thu, Jan 10, 2013 at 11:04 PM, Simon Glass <sjg@chromium.org> wrote: > Hi Rajeshwari, > > On Mon, Jan 7, 2013 at 5:08 AM, Rajeshwari Shinde > <rajeshwari.s@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 <rajeshwari.s@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
Hi Rajeshwari, On Fri, Jan 11, 2013 at 2:43 AM, Rajeshwari Birje <rajeshwari.birje@gmail.com> wrote: > Hi Simon, > > Thank you for comments. > > On Thu, Jan 10, 2013 at 11:04 PM, Simon Glass <sjg@chromium.org> wrote: >> Hi Rajeshwari, >> >> On Mon, Jan 7, 2013 at 5:08 AM, Rajeshwari Shinde >> <rajeshwari.s@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 <rajeshwari.s@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. OK, but is this something you intend to fix, perhaps in a future series? It seems like you need separate directories sooner rather than later.I don't think this is board-specific code, but chip-specific. >> >> 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? No, I meant earlier, but please ignore my comment, i was confused. At present we can't move it earlier because the clocks need to be started up, and that happens in a big monolithic operation. What you have here is fine. >> >>> + } >>> + >>> + 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
Hi Minkyu Kang, >OK, but is this something you intend to fix, perhaps in a future > series? It seems like you need separate directories sooner rather than > later.I don't think this is board-specific code, but chip-specific. Please do let me know your opinion on the above comment. Regards, Rajeshwari Shinde. On Fri, Jan 11, 2013 at 7:54 PM, Simon Glass <sjg@chromium.org> wrote: > Hi Rajeshwari, > > On Fri, Jan 11, 2013 at 2:43 AM, Rajeshwari Birje > <rajeshwari.birje@gmail.com> wrote: >> Hi Simon, >> >> Thank you for comments. >> >> On Thu, Jan 10, 2013 at 11:04 PM, Simon Glass <sjg@chromium.org> wrote: >>> Hi Rajeshwari, >>> >>> On Mon, Jan 7, 2013 at 5:08 AM, Rajeshwari Shinde >>> <rajeshwari.s@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 <rajeshwari.s@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. > > OK, but is this something you intend to fix, perhaps in a future > series? It seems like you need separate directories sooner rather than > later.I don't think this is board-specific code, but chip-specific. > >>> >>> 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? > > No, I meant earlier, but please ignore my comment, i was confused. At > present we can't move it earlier because the clocks need to be started > up, and that happens in a big monolithic operation. > > What you have here is fine. > >>> >>>> + } >>>> + >>>> + 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
On 11/01/13 19:10, Rajeshwari Birje wrote: > Hi Minkyu Kang, > > Thank you for comments. > > On Fri, Jan 11, 2013 at 1:24 PM, Minkyu Kang <mk7.kang@samsung.com> wrote: >> Dear Rajeshwari, >> >> On 07/01/13 22:08, Rajeshwari Shinde 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. >>> >>> Signed-off-by: Rajeshwari Shinde <rajeshwari.s@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 +++++++++++++++++ >>> 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 >> >> Is it SMDK5250 specific? > - Yes, As mentioned in the commit message it is currently been done > only for SMDK5250 and can be also > extended to other SOC in Future. >> But I think, we don't have to get dependency with the board. Thanks. Minkyu Kang.
On 14/01/13 15:32, Rajeshwari Birje wrote: > Hi Minkyu Kang, > >> OK, but is this something you intend to fix, perhaps in a future >> series? It seems like you need separate directories sooner rather than >> later.I don't think this is board-specific code, but chip-specific. > > Please do let me know your opinion on the above comment. > > Regards, > Rajeshwari Shinde. > > On Fri, Jan 11, 2013 at 7:54 PM, Simon Glass <sjg@chromium.org> wrote: >> Hi Rajeshwari, >> >> On Fri, Jan 11, 2013 at 2:43 AM, Rajeshwari Birje >> <rajeshwari.birje@gmail.com> wrote: >>> Hi Simon, >>> >>> Thank you for comments. >>> >>> On Thu, Jan 10, 2013 at 11:04 PM, Simon Glass <sjg@chromium.org> wrote: >>>> Hi Rajeshwari, >>>> >>>> On Mon, Jan 7, 2013 at 5:08 AM, Rajeshwari Shinde >>>> <rajeshwari.s@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 <rajeshwari.s@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. >> >> OK, but is this something you intend to fix, perhaps in a future >> series? It seems like you need separate directories sooner rather than >> later.I don't think this is board-specific code, but chip-specific. >> We don't have to separate directory for exynos5 and exynos4. We can check this by cpu_is_exynos5 or cpu_is_exynos4. I think each SoCs have different memory and timing but the logic can be same. If so we can move all of changes to SoC directory. -- Thanks, Minkyu Kang.
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 +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 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(); + } + + 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); /* * 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); +} + +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
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. Signed-off-by: Rajeshwari Shinde <rajeshwari.s@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 +++++++++++++++++ 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