[U-Boot] [PATCH 0/4 V2] SMDK5250: Convert lowlevel_init.S to .c and set PMIC values

This patch converts lowlevel_init.S to lowlevel_init_c.c. Add PMIC MAX77686 voltage settings for SMDK5250.
Changes in V2: - Added early serial support. - Moved patch 2 containing power apis to patch 1 due to dependency - moved lowlevel_init.S to arch/arm/cpu/armv7/exynos and renamed as lowlevel.S - Moved power mode #defines to power.h - added error check for PMIC voltage settings.
Rajeshwari Shinde (4): EXYNOS: Add functions for power initialisation SMDK5250: Convert lowlevel_init.S to lowlevel_init.c SMDK5250: Add PMIC voltage settings SMDK5250: Modify IRAM stack pointer address
arch/arm/cpu/armv7/exynos/Makefile | 6 ++ arch/arm/cpu/armv7/exynos/lowlevel.S | 35 ++++++++ arch/arm/cpu/armv7/exynos/power.c | 27 ++++++ arch/arm/include/asm/arch-exynos/power.h | 18 ++++ 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/smdk5250.c | 110 +++++++++++++++++++++++- board/samsung/smdk5250/spl_boot.c | 140 +++++++++++++++++++++++++++-- include/configs/exynos5250-dt.h | 11 ++- include/power/max77686_pmic.h | 30 +++++++ spl/Makefile | 4 + 15 files changed, 471 insertions(+), 118 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

This patch adds functions to intialsise power registers during spl boot.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - Moved from second patch to first patch - Renamed ps_hold_setup to power_ps_hold_setup - Added explanation before each power function definition arch/arm/cpu/armv7/exynos/power.c | 27 +++++++++++++++++++++++++++ arch/arm/include/asm/arch-exynos/power.h | 10 ++++++++++ 2 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c index d4bce6d..f0c107c 100644 --- a/arch/arm/cpu/armv7/exynos/power.c +++ b/arch/arm/cpu/armv7/exynos/power.c @@ -95,3 +95,30 @@ void set_dp_phy_ctrl(unsigned int enable) if (cpu_is_exynos5()) exynos5_dp_phy_control(enable); } + +uint32_t power_read_reset_status(void) +{ + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + return power->inform1; +} + +void power_ps_hold_setup(void) +{ + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + /* Set PS-Hold high */ + setbits_le32(&power->ps_hold_control, + EXYNOS_PS_HOLD_CONTROL_DATA_HIGH); +} + +void power_exit_wakeup(void) +{ + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + typedef void (*resume_func)(void); + + ((resume_func)power->inform0)(); +} diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index d2fdb59..f6d0278 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -864,4 +864,14 @@ void set_dp_phy_ctrl(unsigned int enable);
#define EXYNOS_DP_PHY_ENABLE (1 << 0)
+#define EXYNOS_PS_HOLD_CONTROL_DATA_HIGH (1 << 8) + +/* Read inform1 to get the reset status */ +uint32_t power_read_reset_status(void); + +/*Set ps_hold data drving value high */ +void power_ps_hold_setup(void); + +/* Read the resume function and call it */ +void power_exit_wakeup(void); #endif

Hi Rajeshwari,
On Mon, Jan 7, 2013 at 5:08 AM, Rajeshwari Shinde rajeshwari.s@samsung.com wrote:
This patch adds functions to intialsise power registers during spl boot.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
Changes in V2: - Moved from second patch to first patch - Renamed ps_hold_setup to power_ps_hold_setup - Added explanation before each power function definition arch/arm/cpu/armv7/exynos/power.c | 27 +++++++++++++++++++++++++++ arch/arm/include/asm/arch-exynos/power.h | 10 ++++++++++ 2 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c index d4bce6d..f0c107c 100644 --- a/arch/arm/cpu/armv7/exynos/power.c +++ b/arch/arm/cpu/armv7/exynos/power.c @@ -95,3 +95,30 @@ void set_dp_phy_ctrl(unsigned int enable) if (cpu_is_exynos5()) exynos5_dp_phy_control(enable); }
+uint32_t power_read_reset_status(void) +{
struct exynos5_power *power =
(struct exynos5_power *)samsung_get_base_power();
return power->inform1;
+}
+void power_ps_hold_setup(void) +{
struct exynos5_power *power =
(struct exynos5_power *)samsung_get_base_power();
/* Set PS-Hold high */
setbits_le32(&power->ps_hold_control,
EXYNOS_PS_HOLD_CONTROL_DATA_HIGH);
+}
+void power_exit_wakeup(void) +{
struct exynos5_power *power =
(struct exynos5_power *)samsung_get_base_power();
typedef void (*resume_func)(void);
((resume_func)power->inform0)();
+} diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index d2fdb59..f6d0278 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -864,4 +864,14 @@ void set_dp_phy_ctrl(unsigned int enable);
#define EXYNOS_DP_PHY_ENABLE (1 << 0)
+#define EXYNOS_PS_HOLD_CONTROL_DATA_HIGH (1 << 8)
+/* Read inform1 to get the reset status */ +uint32_t power_read_reset_status(void);
+/*Set ps_hold data drving value high */
driving
While you are there I suggest you add that this enables the machine to stay powered on after the initial power-on condition goes away (e.g. power button).
+void power_ps_hold_setup(void);
+/* Read the resume function and call it */ +void power_exit_wakeup(void);
#endif
1.7.4.4
Regards, Simon

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

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

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

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

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.

This patch adds required pmic voltage settings for SMDK5250.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - Added pmic_reg_update static function. - Added error check. board/samsung/smdk5250/smdk5250.c | 110 ++++++++++++++++++++++++++++++++++++- include/power/max77686_pmic.h | 30 ++++++++++ 2 files changed, 138 insertions(+), 2 deletions(-)
diff --git a/board/samsung/smdk5250/smdk5250.c b/board/samsung/smdk5250/smdk5250.c index 73c3ec0..9b0fe39 100644 --- a/board/samsung/smdk5250/smdk5250.c +++ b/board/samsung/smdk5250/smdk5250.c @@ -24,14 +24,17 @@ #include <fdtdec.h> #include <asm/io.h> #include <i2c.h> +#include <errno.h> #include <netdev.h> #include <spi.h> #include <asm/arch/cpu.h> #include <asm/arch/gpio.h> #include <asm/arch/mmc.h> #include <asm/arch/pinmux.h> +#include <asm/arch/power.h> #include <asm/arch/sromc.h> #include <power/pmic.h> +#include <power/max77686_pmic.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -58,12 +61,115 @@ int dram_init(void) }
#if defined(CONFIG_POWER) +static int pmic_reg_update(struct pmic *p, int reg, uint regval) +{ + u32 val; + int ret = 0; + + ret = pmic_reg_read(p, reg, &val); + if (ret) { + debug("%s: PMIC register read failed\n", __func__); + return -1; + } + val |= regval; + ret = pmic_reg_write(p, reg, val); + if (ret) { + debug("%s: PMIC register write failed\n", __func__); + return -1; + } + return 0; +} + int power_init_board(void) { + struct pmic *p; + + power_ps_hold_setup(); + + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + if (pmic_init(I2C_PMIC)) return -1; - else - return 0; + + p = pmic_get("MAX77686_PMIC"); + if (!p) + return -ENODEV; + + if (pmic_probe(p)) + return -1; + + if (pmic_reg_update(p, MAX77686_REG_PMIC_32KHZ, MAX77686_32KHCP_EN)) + return -1; + + if (pmic_reg_update(p, MAX77686_REG_PMIC_BBAT, + (MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V))) + return -1; + + /* VDD_MIF */ + if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK1OUT, + MAX77686_BUCK1OUT_1V)) { + debug("%s: PMIC BUCK1OUT register write failed\n", __func__); + return -1; + } + + if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK1CRTL, + MAX77686_BUCK1CTRL_EN)) + return -1; + + /* VDD_ARM */ + if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK2DVS1, + MAX77686_BUCK2DVS1_1_3V)) { + debug("%s: PMIC BUCK2DVS1 register write failed\n", __func__); + return -1; + } + + if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK2CTRL1, + MAX77686_BUCK2CTRL_ON)) + return -1; + + /* VDD_INT */ + if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK3DVS1, + MAX77686_BUCK3DVS1_1_0125V)) { + debug("%s: PMIC BUCK3DVS1 register write failed\n", __func__); + return -1; + } + + if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK3CTRL, + MAX77686_BUCK3CTRL_ON)) + return -1; + + /* VDD_G3D */ + if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK4DVS1, + MAX77686_BUCK4DVS1_1_2V)) { + debug("%s: PMIC BUCK4DVS1 register write failed\n", __func__); + return -1; + } + + if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK4CTRL1, + MAX77686_BUCK3CTRL_ON)) + return -1; + + /* VDD_LDO2 */ + if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO2CTRL1, + (MAX77686_LD02CTRL1_1_5V | EN_LDO))) + return -1; + + /* VDD_LDO3 */ + if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO3CTRL1, + (MAX77686_LD03CTRL1_1_8V | EN_LDO))) + return -1; + + /* VDD_LDO5 */ + if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO5CTRL1, + (MAX77686_LD05CTRL1_1_8V | EN_LDO))) + return -1; + + /* VDD_LDO10 */ + if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO10CTRL1, + (MAX77686_LD10CTRL1_1_8V | EN_LDO))) + return -1; + + return 0; } #endif
diff --git a/include/power/max77686_pmic.h b/include/power/max77686_pmic.h index d949ace..5b7b6ce 100644 --- a/include/power/max77686_pmic.h +++ b/include/power/max77686_pmic.h @@ -155,4 +155,34 @@ enum { EN_LDO = (0x3 << 6), };
+/* Buck1 1 volt value */ +#define MAX77686_BUCK1OUT_1V 0x5 +#define MAX77686_BUCK1CTRL_EN (3 << 0) +/* Buck2 1.3 volt value */ +#define MAX77686_BUCK2DVS1_1_3V 0x38 +#define MAX77686_BUCK2CTRL_ON (1 << 4) +/* Buck3 1.0125 volt value */ +#define MAX77686_BUCK3DVS1_1_0125V 0x21 +#define MAX77686_BUCK3CTRL_ON (1 << 4) +/* Buck4 1.2 volt value */ +#define MAX77686_BUCK4DVS1_1_2V 0x30 +#define MAX77686_BUCK4CTRL_ON (1 << 4) +/* LDO2 1.5 volt value */ +#define MAX77686_LD02CTRL1_1_5V 0x1c +/* LDO3 1.8 volt value */ +#define MAX77686_LD03CTRL1_1_8V 0x14 +/* LDO5 1.8 volt value */ +#define MAX77686_LD05CTRL1_1_8V 0x14 +/* LDO10 1.8 volt value */ +#define MAX77686_LD10CTRL1_1_8V 0x14 +/* MAX77686_REG_PMIC_32KHZ set to 32KH CP + * output is activated + */ +#define MAX77686_32KHCP_EN (1 << 1) +/* MAX77686_REG_PMIC_BBAT set to + * Back up batery charger on and + * limit voltage setting to 3.5v + */ +#define MAX77686_BBCHOSTEN (1 << 0) +#define MAX77686_BBCVS_3_5V (3 << 3) #endif /* __MAX77686_PMIC_H_ */

Hi Rajeshwari,
On Mon, Jan 7, 2013 at 5:08 AM, Rajeshwari Shinde rajeshwari.s@samsung.com wrote:
This patch adds required pmic voltage settings for SMDK5250.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
Changes in V2: - Added pmic_reg_update static function. - Added error check. board/samsung/smdk5250/smdk5250.c | 110 ++++++++++++++++++++++++++++++++++++- include/power/max77686_pmic.h | 30 ++++++++++ 2 files changed, 138 insertions(+), 2 deletions(-)
diff --git a/board/samsung/smdk5250/smdk5250.c b/board/samsung/smdk5250/smdk5250.c index 73c3ec0..9b0fe39 100644 --- a/board/samsung/smdk5250/smdk5250.c +++ b/board/samsung/smdk5250/smdk5250.c @@ -24,14 +24,17 @@ #include <fdtdec.h> #include <asm/io.h> #include <i2c.h> +#include <errno.h> #include <netdev.h> #include <spi.h> #include <asm/arch/cpu.h> #include <asm/arch/gpio.h> #include <asm/arch/mmc.h> #include <asm/arch/pinmux.h> +#include <asm/arch/power.h> #include <asm/arch/sromc.h> #include <power/pmic.h> +#include <power/max77686_pmic.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -58,12 +61,115 @@ int dram_init(void) }
#if defined(CONFIG_POWER) +static int pmic_reg_update(struct pmic *p, int reg, uint regval) +{
u32 val;
int ret = 0;
ret = pmic_reg_read(p, reg, &val);
if (ret) {
debug("%s: PMIC register read failed\n", __func__);
Perhaps add register number here
return -1;
}
val |= regval;
ret = pmic_reg_write(p, reg, val);
if (ret) {
debug("%s: PMIC register write failed\n", __func__);
and here
return -1;
}
return 0;
+}
int power_init_board(void) {
struct pmic *p;
power_ps_hold_setup();
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
if (pmic_init(I2C_PMIC)) return -1;
else
return 0;
p = pmic_get("MAX77686_PMIC");
if (!p)
return -ENODEV;
if (pmic_probe(p))
return -1;
if (pmic_reg_update(p, MAX77686_REG_PMIC_32KHZ, MAX77686_32KHCP_EN))
return -1;
if (pmic_reg_update(p, MAX77686_REG_PMIC_BBAT,
(MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V)))
You could remove the brackets around the | expressions in this patch if you like.
return -1;
/* VDD_MIF */
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK1OUT,
MAX77686_BUCK1OUT_1V)) {
debug("%s: PMIC BUCK1OUT register write failed\n", __func__);
You can probably remove this debug() if you do what I suggest above. Same applies below I think.
return -1;
}
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK1CRTL,
MAX77686_BUCK1CTRL_EN))
return -1;
/* VDD_ARM */
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK2DVS1,
MAX77686_BUCK2DVS1_1_3V)) {
debug("%s: PMIC BUCK2DVS1 register write failed\n", __func__);
return -1;
}
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK2CTRL1,
MAX77686_BUCK2CTRL_ON))
return -1;
/* VDD_INT */
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK3DVS1,
MAX77686_BUCK3DVS1_1_0125V)) {
debug("%s: PMIC BUCK3DVS1 register write failed\n", __func__);
return -1;
}
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK3CTRL,
MAX77686_BUCK3CTRL_ON))
return -1;
/* VDD_G3D */
if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK4DVS1,
MAX77686_BUCK4DVS1_1_2V)) {
debug("%s: PMIC BUCK4DVS1 register write failed\n", __func__);
return -1;
}
if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK4CTRL1,
MAX77686_BUCK3CTRL_ON))
return -1;
/* VDD_LDO2 */
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO2CTRL1,
(MAX77686_LD02CTRL1_1_5V | EN_LDO)))
return -1;
/* VDD_LDO3 */
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO3CTRL1,
(MAX77686_LD03CTRL1_1_8V | EN_LDO)))
return -1;
/* VDD_LDO5 */
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO5CTRL1,
(MAX77686_LD05CTRL1_1_8V | EN_LDO)))
return -1;
/* VDD_LDO10 */
if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO10CTRL1,
(MAX77686_LD10CTRL1_1_8V | EN_LDO)))
return -1;
return 0;
} #endif
diff --git a/include/power/max77686_pmic.h b/include/power/max77686_pmic.h index d949ace..5b7b6ce 100644 --- a/include/power/max77686_pmic.h +++ b/include/power/max77686_pmic.h @@ -155,4 +155,34 @@ enum { EN_LDO = (0x3 << 6), };
+/* Buck1 1 volt value */ +#define MAX77686_BUCK1OUT_1V 0x5 +#define MAX77686_BUCK1CTRL_EN (3 << 0) +/* Buck2 1.3 volt value */ +#define MAX77686_BUCK2DVS1_1_3V 0x38 +#define MAX77686_BUCK2CTRL_ON (1 << 4) +/* Buck3 1.0125 volt value */ +#define MAX77686_BUCK3DVS1_1_0125V 0x21 +#define MAX77686_BUCK3CTRL_ON (1 << 4) +/* Buck4 1.2 volt value */ +#define MAX77686_BUCK4DVS1_1_2V 0x30 +#define MAX77686_BUCK4CTRL_ON (1 << 4) +/* LDO2 1.5 volt value */ +#define MAX77686_LD02CTRL1_1_5V 0x1c +/* LDO3 1.8 volt value */ +#define MAX77686_LD03CTRL1_1_8V 0x14 +/* LDO5 1.8 volt value */ +#define MAX77686_LD05CTRL1_1_8V 0x14 +/* LDO10 1.8 volt value */ +#define MAX77686_LD10CTRL1_1_8V 0x14 +/* MAX77686_REG_PMIC_32KHZ set to 32KH CP
- output is activated
- */
+#define MAX77686_32KHCP_EN (1 << 1) +/* MAX77686_REG_PMIC_BBAT set to
- Back up batery charger on and
- limit voltage setting to 3.5v
- */
+#define MAX77686_BBCHOSTEN (1 << 0) +#define MAX77686_BBCVS_3_5V (3 << 3)
#endif /* __MAX77686_PMIC_H_ */
1.7.4.4
Regards, Simon

RAM stack pointer address to enable u-boot booting after conversion of lowlevel_init.S to lowlevel_init_c.c. Added CONFIG_CMD_BOOTZ to boot zImage.dtb kernel image. Configs required for early serial initialisation added.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com --- Changes in V2: - Addded Configs required for early serial initialisation. include/configs/exynos5250-dt.h | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h index 59182f4..66e1d8d 100644 --- a/include/configs/exynos5250-dt.h +++ b/include/configs/exynos5250-dt.h @@ -114,6 +114,10 @@
/* MMC SPL */ #define CONFIG_SPL +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT + #define COPY_BL2_FNPTR_ADDR 0x02020030
/* specific .lds file */ @@ -199,9 +203,9 @@
#define CONFIG_DOS_PARTITION
-#define CONFIG_IRAM_STACK 0x02050000 - -#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) +#define CONFIG_IRAM_TOP 0x02050000 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_IRAM_TOP - 0x800) +#define CONFIG_IRAM_STACK CONFIG_SYS_INIT_SP_ADDR
/* I2C */ #define CONFIG_SYS_I2C_INIT_BOARD @@ -297,4 +301,5 @@ #define CONFIG_SHA1 #define CONFIG_SHA256
+#define CONFIG_CMD_BOOTZ #endif /* __CONFIG_H */

Hi,
On Mon, Jan 7, 2013 at 5:08 AM, Rajeshwari Shinde rajeshwari.s@samsung.com wrote:
RAM stack pointer address to enable u-boot booting after conversion of lowlevel_init.S to lowlevel_init_c.c. Added CONFIG_CMD_BOOTZ to boot zImage.dtb kernel image. Configs required for early serial initialisation added.
Perhaps should separate out the BOOTZ and early serial things into a separate patch?
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com
Changes in V2: - Addded Configs required for early serial initialisation. include/configs/exynos5250-dt.h | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h index 59182f4..66e1d8d 100644 --- a/include/configs/exynos5250-dt.h +++ b/include/configs/exynos5250-dt.h @@ -114,6 +114,10 @@
/* MMC SPL */ #define CONFIG_SPL +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT
#define COPY_BL2_FNPTR_ADDR 0x02020030
BTW, do you still need this one - or do you have function pointers elsewhere in a table now?
/* specific .lds file */ @@ -199,9 +203,9 @@
#define CONFIG_DOS_PARTITION
-#define CONFIG_IRAM_STACK 0x02050000
-#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000) +#define CONFIG_IRAM_TOP 0x02050000 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_IRAM_TOP - 0x800) +#define CONFIG_IRAM_STACK CONFIG_SYS_INIT_SP_ADDR
/* I2C */ #define CONFIG_SYS_I2C_INIT_BOARD @@ -297,4 +301,5 @@ #define CONFIG_SHA1 #define CONFIG_SHA256
+#define CONFIG_CMD_BOOTZ
#endif /* __CONFIG_H */
1.7.4.4
Regards, Simon

Hi All,
Kindly please do let me if any comments on these patches.
Regards, Rajeshwari Shinde.
On Mon, Jan 7, 2013 at 6:38 PM, Rajeshwari Shinde rajeshwari.s@samsung.com wrote:
This patch converts lowlevel_init.S to lowlevel_init_c.c. Add PMIC MAX77686 voltage settings for SMDK5250.
Changes in V2: - Added early serial support. - Moved patch 2 containing power apis to patch 1 due to dependency - moved lowlevel_init.S to arch/arm/cpu/armv7/exynos and renamed as lowlevel.S - Moved power mode #defines to power.h - added error check for PMIC voltage settings.
Rajeshwari Shinde (4): EXYNOS: Add functions for power initialisation SMDK5250: Convert lowlevel_init.S to lowlevel_init.c SMDK5250: Add PMIC voltage settings SMDK5250: Modify IRAM stack pointer address
arch/arm/cpu/armv7/exynos/Makefile | 6 ++ arch/arm/cpu/armv7/exynos/lowlevel.S | 35 ++++++++ arch/arm/cpu/armv7/exynos/power.c | 27 ++++++ arch/arm/include/asm/arch-exynos/power.h | 18 ++++ 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/smdk5250.c | 110 +++++++++++++++++++++++- board/samsung/smdk5250/spl_boot.c | 140 +++++++++++++++++++++++++++-- include/configs/exynos5250-dt.h | 11 ++- include/power/max77686_pmic.h | 30 +++++++ spl/Makefile | 4 + 15 files changed, 471 insertions(+), 118 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
-- 1.7.4.4
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Hi Rajeshwari,
On Mon, 07 Jan 2013 18:38:42 +0530, Rajeshwari Shinde rajeshwari.s@samsung.com wrote:
This patch converts lowlevel_init.S to lowlevel_init_c.c. Add PMIC MAX77686 voltage settings for SMDK5250.
Changes in V2:
- Added early serial support.
- Moved patch 2 containing power apis to patch 1 due to dependency
- moved lowlevel_init.S to arch/arm/cpu/armv7/exynos and
renamed as lowlevel.S
- Moved power mode #defines to power.h
- added error check for PMIC voltage settings.
Rajeshwari Shinde (4): EXYNOS: Add functions for power initialisation SMDK5250: Convert lowlevel_init.S to lowlevel_init.c SMDK5250: Add PMIC voltage settings SMDK5250: Modify IRAM stack pointer address
arch/arm/cpu/armv7/exynos/Makefile | 6 ++ arch/arm/cpu/armv7/exynos/lowlevel.S | 35 ++++++++ arch/arm/cpu/armv7/exynos/power.c | 27 ++++++ arch/arm/include/asm/arch-exynos/power.h | 18 ++++ 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/smdk5250.c | 110 +++++++++++++++++++++++- board/samsung/smdk5250/spl_boot.c | 140 +++++++++++++++++++++++++++-- include/configs/exynos5250-dt.h | 11 ++- include/power/max77686_pmic.h | 30 +++++++ spl/Makefile | 4 + 15 files changed, 471 insertions(+), 118 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
-- 1.7.4.4
Sorry for only chiming in at V2 stage, but... lowlevel_init is supposed to be the earliest code run ever, and is supposed to set up the environment for possibly, later, setting up a C environment. So what exactly sets up the C environment *for* lowlevel_init to be able to run in C?
Amicalement,
participants (5)
-
Albert ARIBAUD
-
Minkyu Kang
-
Rajeshwari Birje
-
Rajeshwari Shinde
-
Simon Glass