[U-Boot] [PATCH 1/4] SMDK5250: Convert lowlevel_init.S to lowlevel_init_c.c

Simon Glass sjg at chromium.org
Fri Dec 28 16:17:45 CET 2012


Hi Rajeshwari,

On Fri, Dec 28, 2012 at 4:08 AM, Rajeshwari Shinde
<rajeshwari.s at samsung.com> wrote:
> This patch converts lowlevel_init.S to lowlevel_init_c.c for
> SMDK5250.
>
> Signed-off-by: Rajeshwari Shinde <rajeshwari.s at samsung.com>
> ---
>  board/samsung/smdk5250/Makefile          |    1 +
>  board/samsung/smdk5250/dmc_common.c      |    4 +-
>  board/samsung/smdk5250/dmc_init_ddr3.c   |    6 ++-
>  board/samsung/smdk5250/lowlevel_init.S   |   69 ++---------------------------
>  board/samsung/smdk5250/lowlevel_init_c.c |   70 ++++++++++++++++++++++++++++++
>  board/samsung/smdk5250/setup.h           |   17 ++++++-
>  board/samsung/smdk5250/spl_boot.c        |   52 ++++++++++++++++++----
>  spl/Makefile                             |    4 ++
>  8 files changed, 142 insertions(+), 81 deletions(-)
>  create mode 100644 board/samsung/smdk5250/lowlevel_init_c.c

Great to see this!

>
> diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile
> index 47c6a5a..b99ac7f 100644
> --- a/board/samsung/smdk5250/Makefile
> +++ b/board/samsung/smdk5250/Makefile
> @@ -37,6 +37,7 @@ endif
>
>  ifdef CONFIG_SPL_BUILD
>  COBJS  += spl_boot.o
> +COBJS  += lowlevel_init_c.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..6a26822 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 mem_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, mem_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..4e0693d 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 mem_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 (mem_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
> index bc6cb6f..469126d 100644
> --- a/board/samsung/smdk5250/lowlevel_init.S
> +++ b/board/samsung/smdk5250/lowlevel_init.S
> @@ -23,74 +23,13 @@
>   */
>
>  #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.
> +        * Set the stack pointer, although it will be overwriten by the caller

overwritten

> +        * It seems we will not boot if this function is empty.
>          */
> -       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
> +       ldr     sp, =CONFIG_IRAM_STACK
> +       mov     pc, lr
> diff --git a/board/samsung/smdk5250/lowlevel_init_c.c b/board/samsung/smdk5250/lowlevel_init_c.c
> new file mode 100644
> index 0000000..fdb98cf
> --- /dev/null
> +++ b/board/samsung/smdk5250/lowlevel_init_c.c
> @@ -0,0 +1,70 @@
> +/*
> + * 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 "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,

No early serial support yet?

> +};
> +
> +int lowlevel_init_subsystems(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;
> +       }
> +
> +       if (actions & DO_CLOCKS) {
> +               system_clock_init();
> +               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..d64e385 100644
> --- a/board/samsung/smdk5250/setup.h
> +++ b/board/samsung/smdk5250/setup.h
> @@ -28,6 +28,11 @@
>  #include <config.h>
>  #include <asm/arch/dmc.h>
>
> +/* Power Down Modes */
> +#define EXYNOS_CHECK_SLEEP     0x00000BAD
> +#define EXYNOS_CHECK_DIDLE     0xBAD00000
> +#define EXYNOS_CHECK_LPA       0xABAD0000

Are these used in this patch? Are these register values? Please can
you add a comment as to what these values are for?

> +
>  /* TZPC : Register Offsets */
>  #define TZPC0_BASE             0x10100000
>  #define TZPC1_BASE             0x10110000
> @@ -539,7 +544,8 @@ enum {
>   *                     accesses; may vary across boards.
>   * @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 mem_reset);
>
>  /*
>   * Configure ZQ I/O interface
> @@ -588,7 +594,14 @@ void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc);
>  void update_reset_dll(struct exynos5_dmc *, enum ddr_mode);
>
>  void sdelay(unsigned long);
> -void mem_ctrl_init(void);
> +void mem_ctrl_init(int mem_reset);

Please add a comment for this parameter

>  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 lowlevel_init_subsystems(void);
>  #endif
> diff --git a/board/samsung/smdk5250/spl_boot.c b/board/samsung/smdk5250/spl_boot.c
> index d8f3c1e..66bce5b 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 (lowlevel_init_subsystems())
> +               power_exit_wakeup();

Does this function exist in this patch?

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


More information about the U-Boot mailing list