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

Eric Nelson eric.nelson at boundarydevices.com
Sat Nov 9 21:12:42 CET 2013


Signed-off-by: Eric Nelson <eric.nelson at boundarydevices.com>
---
 doc/README.imx6-multi-arch | 254 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 254 insertions(+)
 create mode 100644 doc/README.imx6-multi-arch

diff --git a/doc/README.imx6-multi-arch b/doc/README.imx6-multi-arch
new file mode 100644
index 0000000..a31718c
--- /dev/null
+++ b/doc/README.imx6-multi-arch
@@ -0,0 +1,254 @@
+Supporting multiple architectures on Freescale i.MX6
+
+This file describes how to support multiple CPU architectures
+(i.MX6DQ and i.MX6DLS) in a single U-Boot image.
+
+Because memory configuration differs between architectures,
+auto-configuration of DDR is also covered.
+
+1. BACKGROUND
+-------------
+The Freescale i.MX6 processor family contains four processors 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-arch 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-architecture, single memory-layout image, the DCD
+can include DDR memory initialization values and the load address
+may be DDR directly.
+
+In order to support multiple processors, 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 architectures in the 
+same image. The SPL image will determine the processor variant
+and memory configuration, configure the IOMUX controller and
+DDR appropriately, then load either a full version of U-Boot 
+or an O/S.
+
+3. DDR configuration
+--------------------
+
+The DDR configuration data for single architecture boards is defined
+within .cfg files in the various board directories.
+
+As of this writing, most boards use the structure defined in 
+board/boundary/nitrogen6x/ that 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-arch 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 architecture for i.MX6DQ
+	MX6DL	- single architecture for i.MX6DL/S
+	MX6QDL	- multi-architecture
+
+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 architecture:
+
+	static iomux_v3_cfg_t const mypads[] = {
+		MX6_PAD_x,
+		...
+	};
+
+or multiple architectures:
+	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 architecture, such that all pads that apply to
+both i.MX6DQ and i.MX6DLS architectures 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-architecture 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, 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...
+
-- 
1.8.1.2



More information about the U-Boot mailing list