Signed-off-by: Eric Nelson <[email protected]> --- 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 _______________________________________________ U-Boot mailing list [email protected] http://lists.denx.de/mailman/listinfo/u-boot

