[U-Boot] [RFC PATCH V2] imx: add multi-BOM README

Stefano Babic sbabic at denx.de
Wed Nov 13 09:22:12 CET 2013


Hi Eric,

On 09/11/2013 23:51, Eric Nelson wrote:
> Signed-off-by: Eric Nelson <eric.nelson at boundarydevices.com>
> ---
> V2 replaces the words "arch" and "architecture", since we're talking about
> processor variations within a family, not different processor architectures.
> 
>  doc/README.imx6-multi-bom | 241 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 241 insertions(+)
>  create mode 100644 doc/README.imx6-multi-bom
> 

We have a quite empty README.imx6. I think you can add your stuff to
that file instead of a new one.

> diff --git a/doc/README.imx6-multi-bom b/doc/README.imx6-multi-bom
> new file mode 100644
> index 0000000..be66e0a
> --- /dev/null
> +++ b/doc/README.imx6-multi-bom
> @@ -0,0 +1,241 @@
> +Supporting multiple "bills of material" on Freescale i.MX6 boards.
> +
> +This file describes how to support multiple variants of the iMX6 CPU 
> +(i.MX6DQ and i.MX6DLS) in a single U-Boot image.
> +
> +Because memory configuration differs between the various CPU
> +models, auto-configuration of DDR is also covered.
> +
> +1. BACKGROUND
> +-------------
> +The Freescale i.MX6 processor family contains four variants which are pin 
> +compatible. Refer to http://freescale.com/imx6series for details and 
> +reference  manuals, but the highlights from a U-Boot perspective are 
> +as follows:
> +
> +i.MX6Q	- Quad core, 64-bit DDR1066, 256K OCRAM
> +i.MX6D	- Dual core, 64-bit DDR1066, 256K OCRAM
> +i.MX6DL	- Dual core, 64-bit DDR800, 128K OCRAM
> +i.MX6S	- Single core, 32-bit DDR800, 128K OCRAM
> +
> +These processors are also largely register-compatible, but not completely.
> +In particular, the IOMUX registers for common functions are in different 
> +locations and have different selector values.
> +
> +The register addresses and values are consistent between the first two 
> +processors in the list above (i.MX6DQ processors) and the second two 
> +(i.MX6DLS for Dual-Lite/Solo).
> +
> +The i.MX6SL (Solo-Lite) processor is not pin compatible, so this document 
> +does not describe support for that variant.
> +
> +Because of the pin-compatibility, a number of manufacturers produce  
> +identical boards with BOM options for two or more of the processors.
> +
> +Similarly, identical boards are offered in a number of different memory 
> +layouts, whether by partially populating the DRAM sockets or by populating 
> +them with different densities of DDR.
> +
> +By following the conventions described in this document, a board can 
> +support each of these options in a single boot image, and decrease the 
> +overhead for managing images.
> +
> +Note that adding multi-BOM support will add to the size of the bootable 
> +image and slow the boot process slightly. If size and speed are critical, 
> +a configuration-specific build can be produced that removes this overhead.
> +
> +2. BOOT FLOW
> +------------
> +The boot process for i.MX6 processors begins with execution of a first 
> +level loader in the processor's internal ROM. This loader samples boot 
> +pins and on-chip fuses to determine the source of the secondary boot 
> +image.
> +
> +The boot image itself consists of a header (the DCD)

If we check exactly the terms, DCD is only a part of a whole header.

> which describes the 
> +load address and payload (the U-Boot firmware). It also contains a set of 
> +register/value pairs used to initialize the CPU prior to execution of 
> +U-Boot.
> +
> +The boot image is produced in a final stage of the build process by the
> +imximage tool by processing a configuration (.cfg) file.

This description is quite a summary of the Boot Chapter in i.MX6 manual.
This is also true for other i.MXes (even older MX3 when booting in
internal mode). Maybe it is enough to make a reference to the manual
instead of explaining everything again.

> +
> +In a single-BOM image, the DCD can include DDR memory initialization 
> +values and the load address may be DDR directly.
> +
> +In order to support all of the processors in this family, the DCD must 
> +contain a load address for the i.MX6's internal RAM (OCRAM) because the 
> +DDR memory speed (at least) will be dependent on the processor variant. 
> +Thankfully, the DCD items needed to load this binary are consistent 
> +between all of the processors.
> +
> +For this reason, support for SPL (secondary program loader) is a requirement 
> +in order to support multiple BOMS in the same image. The SPL image will 
> +determine the processor variant and memory organization, configure the 
> +IOMUX controller and DDR appropriately, and load either a full version of 
> +U-Boot or an O/S.
> +
> +3. DDR configuration
> +--------------------
> +
> +The DDR configuration data for single BOM boards is defined 
> +completely within .cfg files in the various board directories.
> +
> +As of this writing, most boards use the structure defined in the directory
> +board/boundary/nitrogen6x/ which separates the pieces of DCD data 
> +according to function, with this general form:

We should not put the path of the files into the README, as they could
be moved, and simply say that this is an example - other boards could do
differently.

> +
> +	#include "ddr-setup.cfg"
> +	#include "1066mhz_4x128mx16.cfg"
> +	#include "clocks.cfg"
> +
> +Note that only the second of these is specific to the CPU variant or 
> +memory-layout, and the multi-BOM equivalent can simply omit that for 
> +later initialization.
> +
> +	#include "ddr-setup.cfg"
> +	#include "clocks.cfg"
> +
> +In order to support the use of the memory configuration files by both the 
> +SPL code and the imximage tool, the memory configuration files 
> +(1066mhz_4x128mx16.cfg, et cetera) have been converted to use the DCD_REG
> +macro.
> +
> +In other words, this declaration in 1066mhz_4x128mx16.cfg
> +
> +	DCD_REG(MX6_MMDC_P0_MDCFG0, 0x555A7974)
> +
> +will be turned into this by the preprocessor when used by imximage:
> +	
> +	DATA 4, MX6_MMDC_P0_MDCFG0, 0x555A7974
> +
> +and this when used to generate memory configuration tables used by the 
> +SPL:
> +	{MX6_MMDC_P0_MDCFG0, 0x555A7974},

I agree with the method. We can simply switch between "imximage
only" and SPL

> +
> +3. IOMUX declarations
> +---------------------
> +
> +The declarations inside the header files
> +	arch/arm/include/asm/arch-mx6/mx6q_pins.h
> +and
> +	arch/arm/include/asm/arch-mx6/mx6dl_pins.h
> +
> +are used to configure the pads usage for a particular board design.
> +
> +As mentioned earlier, the register addresses and values are different 
> +between the 6DQ and 6DLS processor sets, and these differences are 
> +expressed in two header files:
> +
> +For i.MX6Q and i.MX6D:
> +	arch/arm/include/asm/arch-mx6/mx6q_pins.h
> +
> +and for i.MX6DL and i.MX6S:
> +	arch/arm/include/asm/arch-mx6/mx6dls_pins.h
> +
> +For example, the SD3_DAT2 pad is used for SD card data on all currently 
> +supported i.MX6 boards.
> +
> +On i.MX6DQ, this is selected by writing a zero to the mux register at 
> +address 0x020E02C8. On i.MX6DLS, the address is 0x020E031C.
> +
> +The header files mx6q_pins.h and mx6dls_pins consolidate the settings 
> +through a macro providing a common name of SD3_DAT2__USDHC3_DAT2:
> +
> +	MX6_PAD_DECL(SD3_DAT2__USDHC3_DAT2,...)
> +
> +By using the MX6_PAD_DECL macro, this can be expanded in one of three 
> +ways, depending on the declarations of CONFIG_MX6x by a board file. 
> +Valid options are:
> +
> +	MX6Q	- single BOM for i.MX6DQ
> +	MX6DL	- single BOM for i.MX6DL/S
> +	MX6QDL	- multi-BOM
> +
> +In the first two cases, the MX6_PAD_DECL macro will be expanded into 
> +a declararation with the MX6_PAD_prefix:
> +	MX6_PAD_name = IOMUX_PAD(...)
> +
> +In the last case, the MX6_PAD_DECL macro will be expanded into two sets 
> +of declarations, with the prefix MX6Q_PAD_ for the i.MX6DQ pads and the 
> +prefix MX6DL_PAD_ for the i.MX6DLS pads.
> +
> +This is accomplished by the header file mx6-pins.h:
> +	#ifdef CONFIG_MX6QDL
> +	enum {
> +		#define MX6_PAD_DECL ...
> +		#include "mx6q_pins.h"
> +		
> +		#define MX6_PAD_DECL ...
> +		#include "mx6dl_pins.h"
> +	};
> +	#elif defined(CONFIG_MX6Q)
> +	enum {
> +		#define MX6_PAD_DECL ...
> +		#include "mx6q_pins.h"
> +	};
> +	#elif defined(CONFIG_MX6DL)
> +	enum {
> +		#define MX6_PAD_DECL ...
> +		#include "mx6dl_pins.h"
> +	};
> +	#endif
> +
> +4. IOMUX usage in board files
> +-----------------------------
> +
> +The machinery described above is sufficient to allow a set of pad 
> +registers to be defined for a specific BOM:
> +
> +	static iomux_v3_cfg_t const mypads[] = {
> +		MX6_PAD_x,
> +		...
> +	};
> +
> +or multiple BOMs:
> +	static iomux_v3_cfg_t const mx6q_pads[] = {
> +		MX6Q_PAD_x,
> +		...
> +	};
> +
> +	static iomux_v3_cfg_t const mx6dl_pads[] = {
> +		MX6DL_PAD_x,
> +		...
> +	};
> +
> +In practice, 90% of the references to pads are in these types of static 
> +arrays, and mostly separated by usage (ethernet pads in a different array 
> +from UART pads).
> +
> +Going forward, it is recommended that these be consolidated instead by 
> +applicability, such that all pads that apply to both i.MX6DQ and i.MX6DLS 
> +processor types are defined in "boardname-pads.h" with macros of this 
> +form: MX6_PAD_DEF(PAD_REFERENCE)

Agree - most of them are replictaed in boards. We must factorize them.

> +
> +And that this file be included twice when being used in a multi-BOM build.
> +
> +e.g.
> +	static iomux_v3_cfg_t const mx6q_nitrogen_pads[] = {
> +		#define MX6_PAD_DEF(PAD_DEF) MX6Q_PAD_#PAD_DEF,
> +		#include "nitrogen6x-pads.h"
> +	};
> +	static iomux_v3_cfg_t const mx6dl_nitrogen_pads[] = {
> +		#define MX6_PAD_DEF(PAD_DEF) MX6DL_PAD_#PAD_DEF,
> +		#include "nitrogen6x-pads.h"
> +	}};
> +
> +Doing this allows the bulk of the pads to be defined in a single place.
> +
> +For pads that are specific to i.MX6DQ or i.MX6DLS variants, it is 
> +recommended that they be defined directly in the board file.

Agree.

> +
> +Finally, the convenience macro MX6REF(x) allows run-time selection of a 
> +variable based on the CPU type on which the reference is made:
> +
> +	imx_iomux_v3_setup_multiple_pads(
> +		MX6REF(nitrogen_pads),
> +		ARRAY_SIZE(MX6REF(nitrogen_pads))
> +	);
> +
> +N.B. This doesn't work, since ARRAY_SIZE can't be passed this kind of 
> +reference...
> +
> 

Best regards,
Stefano Babic

-- 
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================


More information about the U-Boot mailing list