[U-Boot] [PATCH 1/4] sunxi: Make FEL mode usable again

Siarhei Siamashka siarhei.siamashka at gmail.com
Sun Feb 1 19:48:18 CET 2015


On Sun, 1 Feb 2015 09:28:36 -0700
Simon Glass <sjg at chromium.org> wrote:

> Hi,
> 
> On 30 January 2015 at 04:58, Siarhei Siamashka
> <siarhei.siamashka at gmail.com> wrote:
> > The commit f630974ccb3ce93e9607a3354e9acb266a8b7e95
> > 'sunxi: Move SPL s_init() code to board_init_f()'
> > broke the FEL boot mode.
> >
> > This patch moves the DRAM initialization back to s_init() and
> > introduces an assembly entry point for FEL in order to provide
> > guaranteed initialization of the gdata pointer (r9). The assembly
> > entry point is also needed to ensure that the SPL code starts
> > executing in ARM mode.
> >
> > Because the sunxi board_init_f() does not contain anything that
> > is not already done by the default board_init_f(), it is removed
> > too.
> >
> > Signed-off-by: Siarhei Siamashka <siarhei.siamashka at gmail.com>
> > ---
> >  arch/arm/cpu/armv7/sunxi/Makefile           |  1 +
> >  arch/arm/cpu/armv7/sunxi/board.c            | 26 ++++++++++----------------
> >  arch/arm/cpu/armv7/sunxi/start_fel.S        | 16 ++++++++++++++++
> >  arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds |  3 ++-
> >  4 files changed, 29 insertions(+), 17 deletions(-)
> >  create mode 100644 arch/arm/cpu/armv7/sunxi/start_fel.S
> >
> > diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
> > index 48db744..e0d413d 100644
> > --- a/arch/arm/cpu/armv7/sunxi/Makefile
> > +++ b/arch/arm/cpu/armv7/sunxi/Makefile
> > @@ -40,5 +40,6 @@ obj-$(CONFIG_MACH_SUN7I)      += dram_sun4i.o
> >  obj-$(CONFIG_MACH_SUN8I)       += dram_sun8i.o
> >  ifdef CONFIG_SPL_FEL
> >  obj-y  += start.o
> > +extra-y        += start_fel.o
> >  endif
> >  endif
> > diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
> > index 6e28bcd..ea6cb60 100644
> > --- a/arch/arm/cpu/armv7/sunxi/board.c
> > +++ b/arch/arm/cpu/armv7/sunxi/board.c
> > @@ -85,6 +85,16 @@ void s_init(void)
> >         timer_init();
> >         gpio_init();
> >         i2c_init_board();
> > +
> > +#ifdef CONFIG_SPL_BUILD
> > +       preloader_console_init();
> 
> s_init() is called before we have global_data, so you can't use a console.

Oh, but somehow it just works for me.

> > +
> > +#ifdef CONFIG_SPL_I2C_SUPPORT
> > +       /* Needed early by sunxi_board_init if PMU is enabled */
> > +       i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
> > +#endif
> > +       sunxi_board_init();
> > +#endif
> 
> Why do you need this code here?

The i2c_init() call is needed to initialize the PMIC as the comment
says. The PMIC is needed to set correct voltages, necessary for
the DRAM controller.

And the sunxi_board_init() initializes DRAM.

> Can it not go in board_init_f()?

Then we probably would need a special stripped down FEL variant of
board_init_f(), which makes the code a bit more messy.

> >  }
> >
> >  #ifdef CONFIG_SPL_BUILD
> > @@ -103,22 +113,6 @@ u32 spl_boot_mode(void)
> >  {
> >         return MMCSD_MODE_RAW;
> >  }
> > -
> > -void board_init_f(ulong dummy)
> > -{
> > -       preloader_console_init();
> > -
> > -#ifdef CONFIG_SPL_I2C_SUPPORT
> > -       /* Needed early by sunxi_board_init if PMU is enabled */
> > -       i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
> > -#endif
> > -       sunxi_board_init();
> > -
> > -       /* Clear the BSS. */
> > -       memset(__bss_start, 0, __bss_end - __bss_start);
> > -
> > -       board_init_r(NULL, 0);
> > -}
> >  #endif
> >
> >  void reset_cpu(ulong addr)
> > diff --git a/arch/arm/cpu/armv7/sunxi/start_fel.S b/arch/arm/cpu/armv7/sunxi/start_fel.S
> > new file mode 100644
> > index 0000000..e1c7cd4
> > --- /dev/null
> > +++ b/arch/arm/cpu/armv7/sunxi/start_fel.S
> > @@ -0,0 +1,16 @@
> > +/*
> > + * Entry point of the FEL mode SPL.
> > + *
> > + * Copyright (c) 2015 Siarhei Siamashka <siarhei.siamashka at gmail.com>
> > + *
> > + * SPDX-License-Identifier:    GPL-2.0+
> > + */
> > +
> > +#include <asm-offsets.h>
> > +#include <config.h>
> > +#include <linux/linkage.h>
> > +
> > +ENTRY(_start_fel)
> > +       ldr     r9, =gdata
> > +       b       s_init
> 
> No we don't want global data here, and need to get rid of gdata so we
> can use driver model, etc.

Appears that I need to educate myself on the global data vs. gdata
differences.

Using driver model in the sunxi SPL is a bit challenging because
we don't have abundant amounts of SRAM there:
    http://linux-sunxi.org/SRAM_Controller
Without relying on SoC-variant specific SRAM sections, we have 32 KiB
for normal SPL, and only ~15 KiB for FEL SPL (the rest is used by the
BROM FEL code). And SRAM is very much needed for the other important
features.

So far I can see that the pointer to gdata is stored in the r9 register.
And gdata resides in the ".data" section, which means that it is
initialized to 0 automatically. And this works now, unless I'm
misunderstanding something.

I would be more than happy to fix it in a future proof way. However it
is very much desired to have a properly functioning FEL boot mode in
u-boot 2015.04 and IMHO a quick hack relying on the legacy gdata feature
might be not the worst possible option today.

> > +ENDPROC(_start_fel)
> > diff --git a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds b/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
> > index 928b7c1..beb8900 100644
> > --- a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
> > +++ b/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
> > @@ -6,7 +6,7 @@
> >   */
> >  OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
> >  OUTPUT_ARCH(arm)
> > -ENTRY(s_init)
> > +ENTRY(_start_fel)
> >  SECTIONS
> >  {
> >         . = 0x00002000;
> > @@ -14,6 +14,7 @@ SECTIONS
> >         . = ALIGN(4);
> >         .text :
> >         {
> > +               arch/arm/cpu/armv7/sunxi/start_fel.o    (.text)
> >                 *(.text.s_init)
> 
> Why does this have to jump to a special s_init? Can it not just start
> SPL normally as it does on Tegra, Exynos, etc?
>
> >                 *(.text*)
> >         }
> 
> There has to be a better way of making this work. Also do you have
> instructions on how I can try this out on a pcduino3 or other low-cost
> board?
> 
> I understand that we need to fix this, but other archs deal with this
> within the existing framework, so I'd really like to get sunxi into
> the same state.

For these parts, see my replies in:
    http://lists.denx.de/pipermail/u-boot/2015-February/203439.html
    http://lists.denx.de/pipermail/u-boot/2015-February/203485.html

I'm afraid that we can't always fit the BROM code into the existing
frameworks. But maybe some good solution exists for this particular
case.

-- 
Best regards,
Siarhei Siamashka


More information about the U-Boot mailing list