diff mbox

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

Message ID 1384037510-12154-1-git-send-email-eric.nelson@boundarydevices.com
State Changes Requested
Delegated to: Stefano Babic
Headers show

Commit Message

Eric Nelson Nov. 9, 2013, 10:51 p.m. UTC
Signed-off-by: Eric Nelson <eric.nelson@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

Comments

Wolfgang Denk Nov. 10, 2013, 8:42 a.m. UTC | #1
Dear Eric Nelson,

In message <1384037510-12154-1-git-send-email-eric.nelson@boundarydevices.com> you wrote:
> Signed-off-by: Eric Nelson <eric.nelson@boundarydevices.com>
> ---
> V2 replaces the words "arch" and "architecture", since we're talking about
> processor variations within a family, not different processor architectures.

Assumin BOM means "Bill of Materials", I still think that the Subject
is not really to the point.  This document describes only the
situation when replacing the iMX6 processor by another model of the
same family, not more.

Actually you write this yourself in the document:

> +This file describes how to support multiple variants of the iMX6 CPU 
> +(i.MX6DQ and i.MX6DLS) in a single U-Boot image.

I think instead of inventing a new name that does not really match
the description, we should just write that, i. e. something like
"Add iMX6 family support README" or "Add iMX6 interchangeability
README" or something like that.

Best regards,

Wolfgang Denk
Stefano Babic Nov. 13, 2013, 8:22 a.m. UTC | #2
Hi Eric,

On 09/11/2013 23:51, Eric Nelson wrote:
> Signed-off-by: Eric Nelson <eric.nelson@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
diff mbox

Patch

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) 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.
+
+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:
+
+	#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},
+
+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)
+
+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.
+
+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...
+