
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