diff mbox

[U-Boot] ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines

Message ID 1477855217-8046-1-git-send-email-eric@nelint.com
State Superseded
Delegated to: Stefano Babic
Headers show

Commit Message

Eric Nelson Oct. 30, 2016, 7:20 p.m. UTC
The DDR calibration routines are gated by conditionals for the
i.MX6DQ SOCs, but with the use of the sysinfo parameter, these
are usable on at least i.MX6SDL and i.MX6SL variants with DDR3.

Also, since only the Novena board currently uses the dynamic
DDR calibration routines, these routines waste space on other
boards using SPL.

Add a KConfig entry to allow boards to selectively include the
DDR calibration routines.

Signed-off-by: Eric Nelson <eric@nelint.com>
---
 arch/arm/cpu/armv7/mx6/Kconfig          | 5 +++++
 arch/arm/cpu/armv7/mx6/ddr.c            | 3 +--
 arch/arm/include/asm/arch-mx6/mx6-ddr.h | 2 +-
 configs/novena_defconfig                | 1 +
 4 files changed, 8 insertions(+), 3 deletions(-)

Comments

Marek Vasut Oct. 30, 2016, 8:03 p.m. UTC | #1
On 10/30/2016 08:20 PM, Eric Nelson wrote:
> The DDR calibration routines are gated by conditionals for the
> i.MX6DQ SOCs, but with the use of the sysinfo parameter, these
> are usable on at least i.MX6SDL and i.MX6SL variants with DDR3.
> 
> Also, since only the Novena board currently uses the dynamic
> DDR calibration routines, these routines waste space on other
> boards using SPL.
> 
> Add a KConfig entry to allow boards to selectively include the
> DDR calibration routines.
> 
> Signed-off-by: Eric Nelson <eric@nelint.com>
> ---
>  arch/arm/cpu/armv7/mx6/Kconfig          | 5 +++++
>  arch/arm/cpu/armv7/mx6/ddr.c            | 3 +--
>  arch/arm/include/asm/arch-mx6/mx6-ddr.h | 2 +-
>  configs/novena_defconfig                | 1 +
>  4 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig
> index 762a581..32536c0 100644
> --- a/arch/arm/cpu/armv7/mx6/Kconfig
> +++ b/arch/arm/cpu/armv7/mx6/Kconfig
> @@ -35,6 +35,11 @@ config MX6ULL
>  	bool
>  	select MX6UL
>  
> +config MX6_DDRCAL
> +	bool "Include dynamic DDR calibration routines"
> +	depends on SPL
> +	default n

Help text would really be helpful ;)

>  choice
>  	prompt "MX6 board select"
>  	optional
> diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
> index b12fb64..0cf391e 100644
> --- a/arch/arm/cpu/armv7/mx6/ddr.c
> +++ b/arch/arm/cpu/armv7/mx6/ddr.c
> @@ -14,8 +14,7 @@
>  #include <asm/types.h>
>  #include <wait_bit.h>
>  
> -#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
> -
> +#if defined(CONFIG_MX6_DDRCAL)
>  static void reset_read_data_fifos(void)
>  {
>  	struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
> diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
> index 12454fa..2a8d443 100644
> --- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
> +++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
> @@ -458,7 +458,7 @@ void mx6sl_dram_iocfg(unsigned width,
>  		      const struct mx6sl_iomux_ddr_regs *,
>  		      const struct mx6sl_iomux_grp_regs *);
>  
> -#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
> +#if defined(CONFIG_MX6_DDRCAL)
>  int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo);
>  int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo);
>  void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo,
> diff --git a/configs/novena_defconfig b/configs/novena_defconfig
> index 1ffdddc..9d47d5b 100644
> --- a/configs/novena_defconfig
> +++ b/configs/novena_defconfig
> @@ -3,6 +3,7 @@ CONFIG_ARCH_MX6=y
>  CONFIG_SPL_GPIO_SUPPORT=y
>  CONFIG_SPL_LIBCOMMON_SUPPORT=y
>  CONFIG_SPL_LIBGENERIC_SUPPORT=y
> +CONFIG_MX6_DDRCAL=y
>  CONFIG_TARGET_KOSAGI_NOVENA=y
>  CONFIG_SPL_EXT_SUPPORT=y
>  CONFIG_SPL_FAT_SUPPORT=y
>
Eric Nelson Oct. 30, 2016, 11:10 p.m. UTC | #2
Thanks Marek,

On 10/30/2016 01:03 PM, Marek Vasut wrote:
> On 10/30/2016 08:20 PM, Eric Nelson wrote:
>> The DDR calibration routines are gated by conditionals for the
>> i.MX6DQ SOCs, but with the use of the sysinfo parameter, these
>> are usable on at least i.MX6SDL and i.MX6SL variants with DDR3.
>>
>> Also, since only the Novena board currently uses the dynamic
>> DDR calibration routines, these routines waste space on other
>> boards using SPL.
>>
>> Add a KConfig entry to allow boards to selectively include the
>> DDR calibration routines.
>>
>> Signed-off-by: Eric Nelson <eric@nelint.com>
>> ---
>>  arch/arm/cpu/armv7/mx6/Kconfig          | 5 +++++
>>  arch/arm/cpu/armv7/mx6/ddr.c            | 3 +--
>>  arch/arm/include/asm/arch-mx6/mx6-ddr.h | 2 +-
>>  configs/novena_defconfig                | 1 +
>>  4 files changed, 8 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig
>> index 762a581..32536c0 100644
>> --- a/arch/arm/cpu/armv7/mx6/Kconfig
>> +++ b/arch/arm/cpu/armv7/mx6/Kconfig
>> @@ -35,6 +35,11 @@ config MX6ULL
>>  	bool
>>  	select MX6UL
>>  
>> +config MX6_DDRCAL
>> +	bool "Include dynamic DDR calibration routines"
>> +	depends on SPL
>> +	default n
> 
> Help text would really be helpful ;)
> 

Cool.

I'll fix this and re-send the series as V2 (with the fourth patch).
Eric Nelson Oct. 30, 2016, 11:33 p.m. UTC | #3
This set of patches updates the interface to the DDR calibration in 
preparation for the addition of a pseudo-board for calibration on
i.MX6.

The first patch fixes an ommission in the use of the DG_CMP_CYC flag
in register MPDGCTRL0.

The second patch cleans up the handling of bus widths by passing
the system configuration information to the calibration routines.

The third patch adds support for returning the calibration data
written to the MMDC registers.

The fourth patch adds a Kconfig selection to inclut the DDR calibration
routines.

Eric Nelson (4):
  mx6: ddr: allow 32 cycles for DQS gating calibration
  mx6: ddr: pass mx6_ddr_sysinfo to calibration routines
  mx6: ddr: add routine to return DDR calibration data
  ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines

 arch/arm/cpu/armv7/mx6/Kconfig          |   5 ++
 arch/arm/cpu/armv7/mx6/ddr.c            | 131 +++++++++++++++++++++-----------
 arch/arm/include/asm/arch-mx6/mx6-ddr.h |   8 +-
 board/kosagi/novena/novena_spl.c        |   4 +-
 configs/novena_defconfig                |   1 +
 5 files changed, 100 insertions(+), 49 deletions(-)
Eric Nelson Nov. 1, 2016, 8:13 p.m. UTC | #4
This patch series adds a DDR calibration tool in the form of a
virtual i.MX6 board named "mx6memcal".

I was hoping to send this without the RFC, but found something that
needs some investigation in the process of cleanup (see ccgr_init in
patch 1) and would like to get it out so that others can experiment
and so I can get some additional feedback.

The board is added in patch 1.

The second patch is kept separate because I don't yet know why this
is needed. If the initial calibration is left as all zero, the 
calibration of the Nitrogen6_Max board will fail. Other boards don't
appear to have this problem.

The rest of the patches add configurations for use in testing.

Most of the boards are supported in main-line U-Boot, though I did
add the Nitrogen6_max board as a test of a 4GiB DDR arrangement.

The 'tr1x' board is a custom design that uses i.MX6SL and DDR3 that
I've been testing against and it works fine.

The mx6slevk and warp boards aren't currently supported because LPDDR2
isn't fully supported.

I did have them working in a local tree that pre-dated Marek's addition
of the calibration code into main-line:

    https://github.com/ericnelsonaz/u-boot/tree/memcal-pass1

Finally, as noted in the commit message, I saw some quirkiness with
a Wandboard Quad. For some reason, the dynamic calibration failed on
this platform when I selected 64-bit bus width and I haven't taken
time to investigate.

Eric Nelson (9):
  mx6: Add board mx6memcal for use in validating DDR
  mx6memcal: zero values for MPWRDLCTL cause read DQS calibration errors
  mx6memcal: add configuration for SABRE Lite
  mx6memcal: add configuration for Nitrogen6_max board
  mx6memcal: add configuration for tr1x board (i.MX6SL with DDR3)
  mx6memcal: add configuration for Wandboard Solo (512MiB of x32 DDR3)
  mx6memcal: add configuration for Wandboard Quad
  mx6memcal: add configuration for mx6slevk
  mx6memcal: add configuration for warp board (i.MX6SL)

 arch/arm/cpu/armv7/mx6/Kconfig             |   9 +
 board/freescale/mx6memcal/Kconfig          | 235 +++++++++++++++
 board/freescale/mx6memcal/MAINTAINERS      |   7 +
 board/freescale/mx6memcal/Makefile         |  13 +
 board/freescale/mx6memcal/README           |  49 +++
 board/freescale/mx6memcal/mx6memcal.c      |  32 ++
 board/freescale/mx6memcal/spl.c            | 462 +++++++++++++++++++++++++++++
 configs/mx6memcal_defconfig                |  32 ++
 configs/mx6memcal_mx6slevk_defconfig       |  37 +++
 configs/mx6memcal_nitrogen6_max_defconfig  |  33 +++
 configs/mx6memcal_sabrelite_defconfig      |  34 +++
 configs/mx6memcal_tr1x_defconfig           |  36 +++
 configs/mx6memcal_wandboard_quad_defconfig |  34 +++
 configs/mx6memcal_wandboard_solo_defconfig |  35 +++
 configs/mx6memcal_warpboard_defconfig      |  39 +++
 include/configs/mx6memcal.h                |  62 ++++
 scripts/config_whitelist.txt               |   5 +
 17 files changed, 1154 insertions(+)
 create mode 100644 board/freescale/mx6memcal/Kconfig
 create mode 100644 board/freescale/mx6memcal/MAINTAINERS
 create mode 100644 board/freescale/mx6memcal/Makefile
 create mode 100644 board/freescale/mx6memcal/README
 create mode 100644 board/freescale/mx6memcal/mx6memcal.c
 create mode 100644 board/freescale/mx6memcal/spl.c
 create mode 100644 configs/mx6memcal_defconfig
 create mode 100644 configs/mx6memcal_mx6slevk_defconfig
 create mode 100644 configs/mx6memcal_nitrogen6_max_defconfig
 create mode 100644 configs/mx6memcal_sabrelite_defconfig
 create mode 100644 configs/mx6memcal_tr1x_defconfig
 create mode 100644 configs/mx6memcal_wandboard_quad_defconfig
 create mode 100644 configs/mx6memcal_wandboard_solo_defconfig
 create mode 100644 configs/mx6memcal_warpboard_defconfig
 create mode 100644 include/configs/mx6memcal.h
Eric Nelson Nov. 2, 2016, 2:06 a.m. UTC | #5
I forgot to mention in the cover letter for the previous patch set 
that because the mx6memcal board has no implementation of storage
(it only supports a serial console and DDR), I haven't tested the
resulting U-Boot, which has very little besides "mtest" included.

I'm hoping to use this code base (mx6memcal) as a straw man for 
loading both SPL (as a plugin) and U-Boot through the serial download 
path as we've previously discussed in at least [1], [2] and [3].

Now that Peng's patch to imximage has been applied, we can start
to look at the implementation details, and I hope this patch set
can help move us toward an implementation.

The gist of what's needed to allow SPL to be loaded as a plugin
and avoid the need for removable storage or a full (non-SPL)
U-Boot is shown in patch 2.

That is, we need something akin to setjmp/longjmp to:
1. to save the early state of the machine before SPL configures
   the DDR controller, and
2. a routine that we can call to return to the boot ROM

To address #1, there's a clear precedent in the support for a
save_boot_params() routine and patch 2 adds one that simply
saves the working register set. Examining the registers used
by the ROM code shows that r0-r9 plus sp and lr are sufficient.

Experimentally, I've found that the boot ROM stack is initialized
to 0x91ffb4 and that the stack pointer is at 0x91febc (248 bytes)
on all of the machines I've tested against (MX6Q, MX6DL, MX6S and
MX6SL), so we can save the stack just by moving the SPL stack
(patch #1).

We'll also need to determine where the decision to return to the
boot ROM occurs (i.e. when we call routine #2).

The obvious place for use during development is right after
DDR initialization if loaded through the serial downloader,
but it might also be useful to invoke the serial loader as
a last resort instead of the current call to hang().

Patch 3 adds a config file which will allow a build of 
u-boot.imx with SPL as a plugin followed by u-boot.bin as
the primary payload. It highlights the issue of only having
a single IMX_CONFIG variable so it breaks the build of a
stand-alone SPL. Rather, it doesn't break the build, but 
produces SPL that is effectively the same as u-boot.imx.

This leaves only the question of what the return_to_rom code 
should look like, and I'm a bit stumped. The ROM API isn't
documented in any document I have.

In Troy's original patch ([4]), he calls a routine that he
names HAB_RVT_LOAD_DATA. On i.MX Community ([5]), I found
a reference to a plugin_download() routine and I'm not
sure where that came from. The Community post suggests
that it's used in EBOOT.

I tried a simplistic copy of the tail end of plugin start
from [6] that calls pu_irom_hwcnfg_setup() and then returns
to ROM without success. I'm not certain that this was the
right approach and am hoping for some guidance.

References:
[1] - http://lists.denx.de/pipermail/u-boot/2015-June/thread.html#215606
[2] - http://lists.denx.de/pipermail/u-boot/2016-September/thread.html#266303
[3] - http://lists.denx.de/pipermail/u-boot/2015-May/thread.html#215573
[4] - http://patchwork.ozlabs.org/patch/186054/
[5] - http://community.nxp.com/thread/303794
[6] - http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/include/asm/arch-mx6/mx6_plugin.S

Eric Nelson (3):
  ARM: mx6: preserve Boot ROM stack in SPL
  ARM: mx6: ddr: add plugin-utils placeholder
  ARM: imx: mx6memcal: allow build of combined SPL+U-Boot

 arch/arm/cpu/armv7/mx6/Makefile         |  2 +-
 arch/arm/cpu/armv7/mx6/ddr.c            |  4 ++++
 arch/arm/cpu/armv7/mx6/plugin-utils.S   | 24 ++++++++++++++++++++++++
 arch/arm/imx-common/spl-plus-u-boot.cfg |  4 ++++
 arch/arm/include/asm/arch-mx6/mx6-ddr.h | 19 +++++++++++++++++++
 configs/mx6memcal_defconfig             |  2 +-
 include/configs/imx6_spl.h              |  2 +-
 7 files changed, 54 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/mx6/plugin-utils.S
 create mode 100644 arch/arm/imx-common/spl-plus-u-boot.cfg
Christoph Fritz Nov. 22, 2016, 10:59 a.m. UTC | #6
On Sun, Oct 30, 2016 at 04:33:46PM -0700, Eric Nelson wrote:
> This set of patches updates the interface to the DDR calibration in 
> preparation for the addition of a pseudo-board for calibration on
> i.MX6.

What's the current state in regard of applying this patchset?

Does it also work on i.MX6SX like the sabresd board?

Thanks
  -- Christoph
Stefano Babic Nov. 29, 2016, 4:28 p.m. UTC | #7
On 31/10/2016 00:33, Eric Nelson wrote:
> This set of patches updates the interface to the DDR calibration in 
> preparation for the addition of a pseudo-board for calibration on
> i.MX6.
> 
> The first patch fixes an ommission in the use of the DG_CMP_CYC flag
> in register MPDGCTRL0.
> 
> The second patch cleans up the handling of bus widths by passing
> the system configuration information to the calibration routines.
> 
> The third patch adds support for returning the calibration data
> written to the MMDC registers.
> 
> The fourth patch adds a Kconfig selection to inclut the DDR calibration
> routines.
> 
> Eric Nelson (4):
>   mx6: ddr: allow 32 cycles for DQS gating calibration
>   mx6: ddr: pass mx6_ddr_sysinfo to calibration routines
>   mx6: ddr: add routine to return DDR calibration data
>   ARM: mx6: ddr: use Kconfig for inclusion of DDR calibration routines
> 
>  arch/arm/cpu/armv7/mx6/Kconfig          |   5 ++
>  arch/arm/cpu/armv7/mx6/ddr.c            | 131 +++++++++++++++++++++-----------
>  arch/arm/include/asm/arch-mx6/mx6-ddr.h |   8 +-
>  board/kosagi/novena/novena_spl.c        |   4 +-
>  configs/novena_defconfig                |   1 +
>  5 files changed, 100 insertions(+), 49 deletions(-)
> 

Applied to u-boot-imx, thanks !

Best regards,
Stefano Babic
Tim Harvey Jan. 18, 2017, 1:27 a.m. UTC | #8
On Tue, Nov 1, 2016 at 7:06 PM, Eric Nelson <eric@nelint.com> wrote:
> I forgot to mention in the cover letter for the previous patch set
> that because the mx6memcal board has no implementation of storage
> (it only supports a serial console and DDR), I haven't tested the
> resulting U-Boot, which has very little besides "mtest" included.
>
> I'm hoping to use this code base (mx6memcal) as a straw man for
> loading both SPL (as a plugin) and U-Boot through the serial download
> path as we've previously discussed in at least [1], [2] and [3].
>
> Now that Peng's patch to imximage has been applied, we can start
> to look at the implementation details, and I hope this patch set
> can help move us toward an implementation.
>
> The gist of what's needed to allow SPL to be loaded as a plugin
> and avoid the need for removable storage or a full (non-SPL)
> U-Boot is shown in patch 2.
>
> That is, we need something akin to setjmp/longjmp to:
> 1. to save the early state of the machine before SPL configures
>    the DDR controller, and
> 2. a routine that we can call to return to the boot ROM
>
> To address #1, there's a clear precedent in the support for a
> save_boot_params() routine and patch 2 adds one that simply
> saves the working register set. Examining the registers used
> by the ROM code shows that r0-r9 plus sp and lr are sufficient.
>
> Experimentally, I've found that the boot ROM stack is initialized
> to 0x91ffb4 and that the stack pointer is at 0x91febc (248 bytes)
> on all of the machines I've tested against (MX6Q, MX6DL, MX6S and
> MX6SL), so we can save the stack just by moving the SPL stack
> (patch #1).
>
> We'll also need to determine where the decision to return to the
> boot ROM occurs (i.e. when we call routine #2).
>
> The obvious place for use during development is right after
> DDR initialization if loaded through the serial downloader,
> but it might also be useful to invoke the serial loader as
> a last resort instead of the current call to hang().
>
> Patch 3 adds a config file which will allow a build of
> u-boot.imx with SPL as a plugin followed by u-boot.bin as
> the primary payload. It highlights the issue of only having
> a single IMX_CONFIG variable so it breaks the build of a
> stand-alone SPL. Rather, it doesn't break the build, but
> produces SPL that is effectively the same as u-boot.imx.
>
> This leaves only the question of what the return_to_rom code
> should look like, and I'm a bit stumped. The ROM API isn't
> documented in any document I have.
>
> In Troy's original patch ([4]), he calls a routine that he
> names HAB_RVT_LOAD_DATA. On i.MX Community ([5]), I found
> a reference to a plugin_download() routine and I'm not
> sure where that came from. The Community post suggests
> that it's used in EBOOT.
>
> I tried a simplistic copy of the tail end of plugin start
> from [6] that calls pu_irom_hwcnfg_setup() and then returns
> to ROM without success. I'm not certain that this was the
> right approach and am hoping for some guidance.
>
> References:
> [1] - http://lists.denx.de/pipermail/u-boot/2015-June/thread.html#215606
> [2] - http://lists.denx.de/pipermail/u-boot/2016-September/thread.html#266303
> [3] - http://lists.denx.de/pipermail/u-boot/2015-May/thread.html#215573
> [4] - http://patchwork.ozlabs.org/patch/186054/
> [5] - http://community.nxp.com/thread/303794
> [6] - http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/include/asm/arch-mx6/mx6_plugin.S
>
> Eric Nelson (3):
>   ARM: mx6: preserve Boot ROM stack in SPL
>   ARM: mx6: ddr: add plugin-utils placeholder
>   ARM: imx: mx6memcal: allow build of combined SPL+U-Boot
>
>  arch/arm/cpu/armv7/mx6/Makefile         |  2 +-
>  arch/arm/cpu/armv7/mx6/ddr.c            |  4 ++++
>  arch/arm/cpu/armv7/mx6/plugin-utils.S   | 24 ++++++++++++++++++++++++
>  arch/arm/imx-common/spl-plus-u-boot.cfg |  4 ++++
>  arch/arm/include/asm/arch-mx6/mx6-ddr.h | 19 +++++++++++++++++++
>  configs/mx6memcal_defconfig             |  2 +-
>  include/configs/imx6_spl.h              |  2 +-
>  7 files changed, 54 insertions(+), 3 deletions(-)
>  create mode 100644 arch/arm/cpu/armv7/mx6/plugin-utils.S
>  create mode 100644 arch/arm/imx-common/spl-plus-u-boot.cfg
>
> --
> 2.7.4
>

Hi Eric,

I'm interested loading U-Boot from the OTG serial downloader and this
looks like a good approach. Thanks for continuing to plug away at
this!

If I understand correctly the approach here is to use the plugin
support such that the boot ROM will execute the SPL as a plugin which
then returns and jumps to U-boot?

I've applied your mx6memcal series to master and support for one of
the Gateworks boards I'm working with and can boot that SPL (23KB)
fine (so I've got the UART and configured correctly at least). When I
adapt that to use pl-plus-u-boot.cfg on top of this patch series the
resulting SPL (85KB) image doens't appear to boot (nothing over the
serial console) but I'm thinking I'm doing something wrong as
imx_usb_loader seems like its not loading it fully or loading it too
quickly. Do I need patches to imx_usb_loader or am I doing something
obvious wrong here?

Incidentally, did anyone ever proof out the other discussed method
where an SPL is built with zmodem and allows loading u-boot.img over
that?

Regards,

Tim
Eric Nelson Jan. 18, 2017, 5:05 p.m. UTC | #9
Hi Tim,

On 01/17/2017 06:27 PM, Tim Harvey wrote:
> On Tue, Nov 1, 2016 at 7:06 PM, Eric Nelson <eric@nelint.com> wrote:
>> I forgot to mention in the cover letter for the previous patch set
>> that because the mx6memcal board has no implementation of storage
>> (it only supports a serial console and DDR), I haven't tested the
>> resulting U-Boot, which has very little besides "mtest" included.
>>
>> I'm hoping to use this code base (mx6memcal) as a straw man for
>> loading both SPL (as a plugin) and U-Boot through the serial download
>> path as we've previously discussed in at least [1], [2] and [3].
>>
>> Now that Peng's patch to imximage has been applied, we can start
>> to look at the implementation details, and I hope this patch set
>> can help move us toward an implementation.
>>
>> The gist of what's needed to allow SPL to be loaded as a plugin
>> and avoid the need for removable storage or a full (non-SPL)
>> U-Boot is shown in patch 2.
>>
>> That is, we need something akin to setjmp/longjmp to:
>> 1. to save the early state of the machine before SPL configures
>>    the DDR controller, and
>> 2. a routine that we can call to return to the boot ROM
>>
>> To address #1, there's a clear precedent in the support for a
>> save_boot_params() routine and patch 2 adds one that simply
>> saves the working register set. Examining the registers used
>> by the ROM code shows that r0-r9 plus sp and lr are sufficient.
>>
>> Experimentally, I've found that the boot ROM stack is initialized
>> to 0x91ffb4 and that the stack pointer is at 0x91febc (248 bytes)
>> on all of the machines I've tested against (MX6Q, MX6DL, MX6S and
>> MX6SL), so we can save the stack just by moving the SPL stack
>> (patch #1).
>>
>> We'll also need to determine where the decision to return to the
>> boot ROM occurs (i.e. when we call routine #2).
>>
>> The obvious place for use during development is right after
>> DDR initialization if loaded through the serial downloader,
>> but it might also be useful to invoke the serial loader as
>> a last resort instead of the current call to hang().
>>
>> Patch 3 adds a config file which will allow a build of
>> u-boot.imx with SPL as a plugin followed by u-boot.bin as
>> the primary payload. It highlights the issue of only having
>> a single IMX_CONFIG variable so it breaks the build of a
>> stand-alone SPL. Rather, it doesn't break the build, but
>> produces SPL that is effectively the same as u-boot.imx.
>>
>> This leaves only the question of what the return_to_rom code
>> should look like, and I'm a bit stumped. The ROM API isn't
>> documented in any document I have.
>>
>> In Troy's original patch ([4]), he calls a routine that he
>> names HAB_RVT_LOAD_DATA. On i.MX Community ([5]), I found
>> a reference to a plugin_download() routine and I'm not
>> sure where that came from. The Community post suggests
>> that it's used in EBOOT.
>>
>> I tried a simplistic copy of the tail end of plugin start
>> from [6] that calls pu_irom_hwcnfg_setup() and then returns
>> to ROM without success. I'm not certain that this was the
>> right approach and am hoping for some guidance.
>>
>> References:
>> [1] - http://lists.denx.de/pipermail/u-boot/2015-June/thread.html#215606
>> [2] - http://lists.denx.de/pipermail/u-boot/2016-September/thread.html#266303
>> [3] - http://lists.denx.de/pipermail/u-boot/2015-May/thread.html#215573
>> [4] - http://patchwork.ozlabs.org/patch/186054/
>> [5] - http://community.nxp.com/thread/303794
>> [6] - http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/include/asm/arch-mx6/mx6_plugin.S
>>
>> Eric Nelson (3):
>>   ARM: mx6: preserve Boot ROM stack in SPL
>>   ARM: mx6: ddr: add plugin-utils placeholder
>>   ARM: imx: mx6memcal: allow build of combined SPL+U-Boot
>>
>>  arch/arm/cpu/armv7/mx6/Makefile         |  2 +-
>>  arch/arm/cpu/armv7/mx6/ddr.c            |  4 ++++
>>  arch/arm/cpu/armv7/mx6/plugin-utils.S   | 24 ++++++++++++++++++++++++
>>  arch/arm/imx-common/spl-plus-u-boot.cfg |  4 ++++
>>  arch/arm/include/asm/arch-mx6/mx6-ddr.h | 19 +++++++++++++++++++
>>  configs/mx6memcal_defconfig             |  2 +-
>>  include/configs/imx6_spl.h              |  2 +-
>>  7 files changed, 54 insertions(+), 3 deletions(-)
>>  create mode 100644 arch/arm/cpu/armv7/mx6/plugin-utils.S
>>  create mode 100644 arch/arm/imx-common/spl-plus-u-boot.cfg
>>
>> --
>> 2.7.4
>>
> 
> Hi Eric,
> 
> I'm interested loading U-Boot from the OTG serial downloader and this
> looks like a good approach. Thanks for continuing to plug away at
> this!
> 

NP. It seems like the easy route if we can figure out the details of
the ROM API calls.

I was hoping to get some feedback from Peng or Troy, but it seems
that they're also overloaded.

> If I understand correctly the approach here is to use the plugin
> support such that the boot ROM will execute the SPL as a plugin which
> then returns and jumps to U-boot?
> 

That's the idea. Both SB_LOADER and imx_usb support this, so the
key is figuring out how to return to the Boot ROM.

> I've applied your mx6memcal series to master and support for one of
> the Gateworks boards I'm working with and can boot that SPL (23KB)
> fine (so I've got the UART and configured correctly at least). When I
> adapt that to use spl-plus-u-boot.cfg on top of this patch series the
> resulting SPL (85KB) image doens't appear to boot (nothing over the
> serial console) but I'm thinking I'm doing something wrong as
> imx_usb_loader seems like its not loading it fully or loading it too
> quickly. Do I need patches to imx_usb_loader or am I doing something
> obvious wrong here?
> 

I need to re-visit this. My recollection is that the SPL portion should
load and run, but the return-to-ROM portion will fail.

My next thought is to use JTAG to trace things through the return to
BOOT ROM and use an image from the Freescale fork as a working
example.

> Incidentally, did anyone ever proof out the other discussed method
> where an SPL is built with zmodem and allows loading u-boot.img over
> that?
> 
Yeah.

Stefano had that working, though I had some issues getting
microcom working. I had to stop and restart microcom and initiate
the upload.

Regards,


Eric
Tim Harvey Jan. 18, 2017, 6:49 p.m. UTC | #10
On Wed, Jan 18, 2017 at 9:05 AM, Eric Nelson <eric@nelint.com> wrote:
> Hi Tim,
>
> On 01/17/2017 06:27 PM, Tim Harvey wrote:
>> On Tue, Nov 1, 2016 at 7:06 PM, Eric Nelson <eric@nelint.com> wrote:
>>> I forgot to mention in the cover letter for the previous patch set
>>> that because the mx6memcal board has no implementation of storage
>>> (it only supports a serial console and DDR), I haven't tested the
>>> resulting U-Boot, which has very little besides "mtest" included.
>>>
>>> I'm hoping to use this code base (mx6memcal) as a straw man for
>>> loading both SPL (as a plugin) and U-Boot through the serial download
>>> path as we've previously discussed in at least [1], [2] and [3].
>>>
>>> Now that Peng's patch to imximage has been applied, we can start
>>> to look at the implementation details, and I hope this patch set
>>> can help move us toward an implementation.
>>>
>>> The gist of what's needed to allow SPL to be loaded as a plugin
>>> and avoid the need for removable storage or a full (non-SPL)
>>> U-Boot is shown in patch 2.
>>>
>>> That is, we need something akin to setjmp/longjmp to:
>>> 1. to save the early state of the machine before SPL configures
>>>    the DDR controller, and
>>> 2. a routine that we can call to return to the boot ROM
>>>
>>> To address #1, there's a clear precedent in the support for a
>>> save_boot_params() routine and patch 2 adds one that simply
>>> saves the working register set. Examining the registers used
>>> by the ROM code shows that r0-r9 plus sp and lr are sufficient.
>>>
>>> Experimentally, I've found that the boot ROM stack is initialized
>>> to 0x91ffb4 and that the stack pointer is at 0x91febc (248 bytes)
>>> on all of the machines I've tested against (MX6Q, MX6DL, MX6S and
>>> MX6SL), so we can save the stack just by moving the SPL stack
>>> (patch #1).
>>>
>>> We'll also need to determine where the decision to return to the
>>> boot ROM occurs (i.e. when we call routine #2).
>>>
>>> The obvious place for use during development is right after
>>> DDR initialization if loaded through the serial downloader,
>>> but it might also be useful to invoke the serial loader as
>>> a last resort instead of the current call to hang().
>>>
>>> Patch 3 adds a config file which will allow a build of
>>> u-boot.imx with SPL as a plugin followed by u-boot.bin as
>>> the primary payload. It highlights the issue of only having
>>> a single IMX_CONFIG variable so it breaks the build of a
>>> stand-alone SPL. Rather, it doesn't break the build, but
>>> produces SPL that is effectively the same as u-boot.imx.
>>>
>>> This leaves only the question of what the return_to_rom code
>>> should look like, and I'm a bit stumped. The ROM API isn't
>>> documented in any document I have.
>>>
>>> In Troy's original patch ([4]), he calls a routine that he
>>> names HAB_RVT_LOAD_DATA. On i.MX Community ([5]), I found
>>> a reference to a plugin_download() routine and I'm not
>>> sure where that came from. The Community post suggests
>>> that it's used in EBOOT.
>>>
>>> I tried a simplistic copy of the tail end of plugin start
>>> from [6] that calls pu_irom_hwcnfg_setup() and then returns
>>> to ROM without success. I'm not certain that this was the
>>> right approach and am hoping for some guidance.
>>>
>>> References:
>>> [1] - http://lists.denx.de/pipermail/u-boot/2015-June/thread.html#215606
>>> [2] - http://lists.denx.de/pipermail/u-boot/2016-September/thread.html#266303
>>> [3] - http://lists.denx.de/pipermail/u-boot/2015-May/thread.html#215573
>>> [4] - http://patchwork.ozlabs.org/patch/186054/
>>> [5] - http://community.nxp.com/thread/303794
>>> [6] - http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/include/asm/arch-mx6/mx6_plugin.S
>>>
>>> Eric Nelson (3):
>>>   ARM: mx6: preserve Boot ROM stack in SPL
>>>   ARM: mx6: ddr: add plugin-utils placeholder
>>>   ARM: imx: mx6memcal: allow build of combined SPL+U-Boot
>>>
>>>  arch/arm/cpu/armv7/mx6/Makefile         |  2 +-
>>>  arch/arm/cpu/armv7/mx6/ddr.c            |  4 ++++
>>>  arch/arm/cpu/armv7/mx6/plugin-utils.S   | 24 ++++++++++++++++++++++++
>>>  arch/arm/imx-common/spl-plus-u-boot.cfg |  4 ++++
>>>  arch/arm/include/asm/arch-mx6/mx6-ddr.h | 19 +++++++++++++++++++
>>>  configs/mx6memcal_defconfig             |  2 +-
>>>  include/configs/imx6_spl.h              |  2 +-
>>>  7 files changed, 54 insertions(+), 3 deletions(-)
>>>  create mode 100644 arch/arm/cpu/armv7/mx6/plugin-utils.S
>>>  create mode 100644 arch/arm/imx-common/spl-plus-u-boot.cfg
>>>
>>> --
>>> 2.7.4
>>>
>>
>> Hi Eric,
>>
>> I'm interested loading U-Boot from the OTG serial downloader and this
>> looks like a good approach. Thanks for continuing to plug away at
>> this!
>>
>
> NP. It seems like the easy route if we can figure out the details of
> the ROM API calls.
>
> I was hoping to get some feedback from Peng or Troy, but it seems
> that they're also overloaded.
>
>> If I understand correctly the approach here is to use the plugin
>> support such that the boot ROM will execute the SPL as a plugin which
>> then returns and jumps to U-boot?
>>
>
> That's the idea. Both SB_LOADER and imx_usb support this, so the
> key is figuring out how to return to the Boot ROM.
>
>> I've applied your mx6memcal series to master and support for one of
>> the Gateworks boards I'm working with and can boot that SPL (23KB)
>> fine (so I've got the UART and configured correctly at least). When I
>> adapt that to use spl-plus-u-boot.cfg on top of this patch series the
>> resulting SPL (85KB) image doens't appear to boot (nothing over the
>> serial console) but I'm thinking I'm doing something wrong as
>> imx_usb_loader seems like its not loading it fully or loading it too
>> quickly. Do I need patches to imx_usb_loader or am I doing something
>> obvious wrong here?
>>
>
> I need to re-visit this. My recollection is that the SPL portion should
> load and run, but the return-to-ROM portion will fail.

ok - I thought you had it fully working, but it does sound like you at
least got further than I'm getting (you saw the SPL boot at least) so
let me know what you find when you re-visit it.

>
> My next thought is to use JTAG to trace things through the return to
> BOOT ROM and use an image from the Freescale fork as a working
> example.
>
>> Incidentally, did anyone ever proof out the other discussed method
>> where an SPL is built with zmodem and allows loading u-boot.img over
>> that?
>>
> Yeah.
>
> Stefano had that working, though I had some issues getting
> microcom working. I had to stop and restart microcom and initiate
> the upload.

Stefano,

Did you document the 'IMX6 SPL to U-Boot over serial' setup anywhere,
or can you talk me through what you did?

Thanks,

Tim
Fabio Estevam Jan. 18, 2017, 7:01 p.m. UTC | #11
Hi Tim,

On Wed, Jan 18, 2017 at 4:49 PM, Tim Harvey <tharvey@gateworks.com> wrote:

> Did you document the 'IMX6 SPL to U-Boot over serial' setup anywhere,
> or can you talk me through what you did?

It is available at doc/README.imx6 (2. Using imx_usb_loader for first
install with SPL).
Tim Harvey Jan. 20, 2017, 5:40 p.m. UTC | #12
On Wed, Jan 18, 2017 at 11:01 AM, Fabio Estevam <festevam@gmail.com> wrote:
> Hi Tim,
>
> On Wed, Jan 18, 2017 at 4:49 PM, Tim Harvey <tharvey@gateworks.com> wrote:
>
>> Did you document the 'IMX6 SPL to U-Boot over serial' setup anywhere,
>> or can you talk me through what you did?
>
> It is available at doc/README.imx6 (2. Using imx_usb_loader for first
> install with SPL).

Fabio,

Thanks for pointing me in the right direction. I did manage to get
IMX6 SPL Ymodem working although I had to hack the return value of
spl_boot_device(). In my current situation with a board that has no
BOOT MODE pin strapping, and no fuses blown imx_usb_loader
spl_boot_device() returns BOOT_DEVICE_NOR which is wrong.

The SRC_SBMR register reflects the BOOT MODE pins of the chip
(strapping) but the reference manual defines SRC_GPR9 and
SRC_GPR10[28] as reserved and I don't recall the reasoning for using
these for the boot mode. Can you provide some documentation that we
can put in the code? I'm thinking there is something else missing from
this function that should be able to determine that the serial
downloader was used in my case and return BOOT_DEVICE_UART
appropriately.

Regards,

Tim
Fabio Estevam Jan. 27, 2017, 2:56 p.m. UTC | #13
Hi Tim,

On Fri, Jan 20, 2017 at 3:40 PM, Tim Harvey <tharvey@gateworks.com> wrote:

> The SRC_SBMR register reflects the BOOT MODE pins of the chip
> (strapping) but the reference manual defines SRC_GPR9 and
> SRC_GPR10[28] as reserved and I don't recall the reasoning for using
> these for the boot mode. Can you provide some documentation that we
> can put in the code? I'm thinking there is something else missing from
> this function that should be able to determine that the serial
> downloader was used in my case and return BOOT_DEVICE_UART
> appropriately.

I could also not found any documentation about SRC_GPR9 and SRC_GPR10[28].

I also find it confusing that we use such undocumented registers in
U-Boot for determining the boot mode.
Otavio Salvador Jan. 27, 2017, 3:25 p.m. UTC | #14
On Fri, Jan 27, 2017 at 12:56 PM, Fabio Estevam <festevam@gmail.com> wrote:
> On Fri, Jan 20, 2017 at 3:40 PM, Tim Harvey <tharvey@gateworks.com> wrote:
>> The SRC_SBMR register reflects the BOOT MODE pins of the chip
>> (strapping) but the reference manual defines SRC_GPR9 and
>> SRC_GPR10[28] as reserved and I don't recall the reasoning for using
>> these for the boot mode. Can you provide some documentation that we
>> can put in the code? I'm thinking there is something else missing from
>> this function that should be able to determine that the serial
>> downloader was used in my case and return BOOT_DEVICE_UART
>> appropriately.
>
> I could also not found any documentation about SRC_GPR9 and SRC_GPR10[28].

I think the BootROM is the ultimate resource here. Did you look
internally for its source?
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig
index 762a581..32536c0 100644
--- a/arch/arm/cpu/armv7/mx6/Kconfig
+++ b/arch/arm/cpu/armv7/mx6/Kconfig
@@ -35,6 +35,11 @@  config MX6ULL
 	bool
 	select MX6UL
 
+config MX6_DDRCAL
+	bool "Include dynamic DDR calibration routines"
+	depends on SPL
+	default n
+
 choice
 	prompt "MX6 board select"
 	optional
diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index b12fb64..0cf391e 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -14,8 +14,7 @@ 
 #include <asm/types.h>
 #include <wait_bit.h>
 
-#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
-
+#if defined(CONFIG_MX6_DDRCAL)
 static void reset_read_data_fifos(void)
 {
 	struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
index 12454fa..2a8d443 100644
--- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
+++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
@@ -458,7 +458,7 @@  void mx6sl_dram_iocfg(unsigned width,
 		      const struct mx6sl_iomux_ddr_regs *,
 		      const struct mx6sl_iomux_grp_regs *);
 
-#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
+#if defined(CONFIG_MX6_DDRCAL)
 int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo);
 int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo);
 void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo,
diff --git a/configs/novena_defconfig b/configs/novena_defconfig
index 1ffdddc..9d47d5b 100644
--- a/configs/novena_defconfig
+++ b/configs/novena_defconfig
@@ -3,6 +3,7 @@  CONFIG_ARCH_MX6=y
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_MX6_DDRCAL=y
 CONFIG_TARGET_KOSAGI_NOVENA=y
 CONFIG_SPL_EXT_SUPPORT=y
 CONFIG_SPL_FAT_SUPPORT=y