i.MX 6 BSP Porting Guide
Document Number: IMX6BSPPG
Rev L3.10.17_1.0.0-ga, 05/2014
Contents
Section number Title Page
Chapter 1
Porting U-Boot from an i.MX 6 Reference Board to an i.MX 6 Custom Board
1.1U-Boot Overview (7)
1.2Obtaining the Source Code for the U-Boot (7)
1.2.1Preparing the Code (8)
1.3Customizing the i.MX 6 Custom Board Code (10)
1.3.1Changing the DCD Table for i.MX 6 DDR3LPDDR2 Initialization (10)
1.3.2Booting with the Modified U-Boot (10)
1.3.3Adding New Driver Initialization Code to Board Files (11)
1.3.4Further Customization at System Boot (12)
1.3.5Customizing the Printed Board Name (12)
1.4Debugging (13)
1.4.1Using RealView ICE for Debugging (13)
1.4.2Using printf for debugging (13)
Chapter 2
Configuring the IOMUX Controller
2.1IOMUX Overview (15)
2.2Information for Setting IOMUX Controller Registers (16)
2.3Using IOMUX in the Device Tree - Example (17)
Chapter 3
Registering a New UART Driver
3.1Enabling UART on Kernel Menuconfig (19)
3.2UART Settings (19)
3.3File Names and Locations (19)
Chapter 4
Adding Support for SDHC
4.1SDHC Overview (21)
Chapter 5
Configuring the SPI NOR Flash Memory Technology Device (MTD) Driver
5.1SPI NOR Overview (23)
5.2Source Code Structure (23)
5.2.1Configuration Options (23)
5.2.2Selecting SPI NOR on the Linux Image (24)
5.3Changing the SPI Interface Configuration (24)
5.4Hardware Operation (24)
5.4.1Software Operation (25)
Chapter 6
Connecting an LVDS Panel to an i.MX 6Dual/6Quad/6Solo/6DualLite Reference Board 6.1LVDS Overview (27)
6.1.1Connecting an LVDS Panel to the i.MX 6Dual/6Quad/6DualLite Reference Board (27)
6.2Enabling an LVDS Channel (28)
6.2.1Locating Menu Configuration Options (28)
6.3LDB Ports (28)
6.3.1Input Parallel Display Ports (29)
6.3.2Output LVDS Ports (30)
6.4Additional Information (30)
Chapter 7
Supporting the i.MX 6Dual/6Quad/6Solo/6DualLite Camera Sensor with CSI
7.1CSI Overview (31)
7.1.1Required Software (31)
7.1.2i.MX 6Dual/6Quad/6Solo/6DualLite CSI Interfaces Layout (32)
7.1.3Configuring the CSI Unit in Test Mode (32)
7.2Adding Support for a New CMOS Camera Sensor (33)
7.2.1Adding a Camera Sensor Entry in Kconfig (33)
7.2.2Creating the Camera Sensor File (34)
7.2.3Adding a Compilation Flag for the New Camera (36)
7.3Using the I2C Interface (37)
7.3.1Loading and Testing the Camera Module (39)
7.4Additional Reference Information (39)
7.4.1CMOS Interfaces Supported by the i.MX 6Dual/6Quad/6Solo/6DualLite (39)
7.4.2i.MX 6Dual/6Quad/6Solo/6DualLite CSI Parallel Interface (41)
7.4.3Timing Data Mode Protocols (43)
Chapter 8
Porting Audio Codecs to a Custom Board
8.1Audio Overview (45)
8.1.1Common Porting Task (45)
8.1.2Porting the Reference BSP to a Custom Board (audio codec is the same as in the reference design) (46)
8.1.3Porting the Reference BSP to a Custom Board (audio codec is different than the reference design) (47)
Chapter 9
Porting the Ethernet Controller Driver
9.1Ethernet Controller Overview (49)
9.1.1Pin Configuration (49)
9.1.2Source Code (50)
9.1.3Ethernet Configuration (51)
Chapter 10
Porting USB Host1 and USB OTG
10.1USB Overview for i.MX 6Dual/6Quad/6Solo/6DualLite (53)
10.2USB Overview for i.MX 6SoloLite (55)
Chapter 1
Porting U-Boot from an i.MX 6 Reference Board to an i.MX 6 Custom Board
1.1U-Boot Overview
This chapter provides a step-by-step guide that explains how to add i.MX 6 custom board support for U-Boot.
This developer guide is based on the U-Boot v2013.04 package. For the i.MX patches, refer to the release notes.
1.2Obtaining the Source Code for the U-Boot
The following steps describe how to obtain the source code.
1.Install Yocto Project. See the Freescale Yocto Project User's Guide.
2.In Yocto Project, set the U-Boot preferred provider to uboot-imx. Confirm that the
sources/meta-fsl-bsp-release/imx/meta-fsl-arm/conf has the line PREFERRED_PROVIDER_u-boot_mx6 = "u-boot-imx"
The U-Boot code is now located at
?imx6qsabresd
?imx6qsabreauto
?imx6dlsabresd
?imx6dlsabreauto
?imx6solosabreauto
?imx6slevk
The U-Boot main directory is referred to as
1.2.1Preparing the Code
The following steps describes how to prepare the code.
1.Copy the board directory, as shown below:
$cp -R board/freescale/mx6_
$cp include/configs/mx6
NOTE
The configuration files for the i.MX 6 are located at
include/configs. The files associated with the boards are:
?i.MX 6 SABRE-SD:
?mx6sabresd_common.h
?mx6sabresd.h
?i.MX 6 SABRE-AI:
?mx6sabresd_common.h
?mx6sabreauto.h
?i.MX 6SL EVK:
?mx6slevk.h
NOTE
You should pay attention to the following configurations
when using a new board.
?CONFIG_LOADADDR : Normally your uImage will be
loaded to this address for boot.
?CONFIG_SYS_MALLOC_LEN : Heap memory size.
?CONFIG_STACKSIZE : Stack size.
?CONFIG_NR_DRAM_BANKS : Number of ddr banks.
?CONFIG_DDR_MB : Configure the DDR size in
?MB.PHYS_SDRAM : Physical address for the DDR
memory
?Config file is important for U-Boot. It determines the
size, functionality, and performance of u-boot.bin.
3.Create one entry in
mx6q
freescale mx6
mx6q
mx6q.cfg,MX6Q,DEFAULT_FDT_FILE="imx6q-
2048,SYS_USE_SPINOR
NOTE
U-Boot project developers recommend adding any new
board to the MAKEALL script and running this script to
validate that the new code has not broken any other
platform build. This is a requirement if you plan to submit a
patch back to the U-Boot community. For further
information, see the U-Boot README file.
4.Rename
board/freescale/mx6
to
board/freescale/mx6
5.Change the line
COBJS := mx6 name>/Makefile) to COBJS := mx6 NOTE The remaining instructions build the U-Boot manually and do not use Yocto Project. 6.Create a shell script under The file contents are as follows: #!/bin/bash export ARCH=arm export CROSS_COMPILE= /opt/poky/1.4.1/sysroots/i686-pokysdk-linux/usr/bin/cortexa9hf-vfp-neon-poky-linux- gnueabi/arm-poky-linux-gnueabi- make distclean; make mx6 make https://www.wendangku.net/doc/d117553695.html,pile U-Boot by using $./build_u-boot.sh 8.If everything is correct, you should now have u-boot.bin, which indicates that your build setup is correct and ready to be customized. The new i.MX 6 custom board that you have created is an exact copy of the i.MX 6 reference board, but the boards are two independent builds. This allows you to proceed to the next step: customizing the code to suit the new hardware design. 1.3Customizing the i.MX 6 Custom Board Code The new i.MX 6 custom board is a part of the U-Boot source tree, but it is a duplicate of the i.MX 6 reference board code and needs to be customized. The DDR technology is a potential key difference between the two boards. If there is a difference in the DDR technology between the two boards, the DDR initialization needs to be ported. DDR initialization is coded in the DCD table, inside the boot header of the U-Boot image. When porting bootloader, kernel or driver code, you must have the schematics easily accessible for reference. 1.3.1Changing the DCD Table for i.MX 6 DDR3LPDDR2Initialization Before you initialize the memory interface, you need to configure the relevant I/O pins with the right mode and impedance, and then initialize the MMDC module. 1.To port to the custom board, the DDR needs to be initialized properly. 2.Open the file board/freescale/mx6 3.Modify all items in this file to match the memory specifications. These code blocks will be read by the ROM code to initialize your DDR memory.1.3.2Booting with the Modified U-Boot This section describes how to compile and write u-boot.bin to an SD card. If the DDR configuration (board/freescale/mx6 U-Boot 2013.04-02326-gd20319c (Sep 13 2013 - 15:44:53) CPU: Freescale i.MX6Q rev1.2 at 792 MHz CPU: Temperature 31 C, calibration data: 0x5804d87d Reset cause: POR Board: MX6Q/SDL-SabreSD I2C: ready DRAM: 1 GiB MMC: FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2 In: serial Out: serial Err: serial Found PFUZE100! deviceid=10,revid=10 Net: FEC [PRIME] Hit any key to stop autoboot: 0 U-Boot > The following message should be displayed on the console if your custom board was based on the i.MX 6SoloLite EVK: U-Boot 2013.04-02326-gd20319c (Sep 13 2013 - 15:44:53) CPU: Freescale i.MX6SL rev1.2 at 396 MHz CPU: Temperature 31 C, calibration data: 0x5804d87d Reset cause: POR Board: MX6SLEVK I2C: ready DRAM: 1 GiB MMC: FSL_SDHC: 0 In: serial Out: serial Err: serial Found PFUZE100! deviceid=10,revid=11 Net: FEC Hit any key to stop autoboot: 0 U-Boot > 1.3.3Adding New Driver Initialization Code to Board Files The following steps describe how to add new driver and how to initialize code. 1.Find mx6 2.Edit mx6 clock, iomux, and gpio. 3.Put driver initialization function into board_init or board_late_init. NOTE ?The board_early_init_f() function will be called at the very early phase if you define CONFIG_BOARD_EARLY_INIT_F. You can put the UART/SPI-NOR/NAND iomux setup function which requires to be set up at the very early phase. ?The board_init()function will be called between board_early_init_f and board_late_init. You can do some general board-level setup here. If you do not define CONFIG_BOARD_EARLY_INIT_F, do not call printf before the uart setup is finished. Otherwise, the system may be down. ?board_late_init() function will be called fairly later. To debug the initialization code, put the initialization function into it. 1.3.4Further Customization at System Boot To further customize your U-Boot board project, use the first function that system boot calls on: start_armboot in "lib_arm/board.c". board_early_init_f() board_init() All board initialization is executed inside this function. It starts by running through the init_sequence[] array of function pointers. The first board dependent function inside the init_sequence[] array is board_early_init_f(). board_early_init_f() is implemented inside board/freescale/ mx6 The following line of code is most important: ... setup_iomux_uart(); ... NOTE If a device tree is used, the machine ID is not used. The compatible string of the DTS file is used to match the board. The device tree for file each boot variation is specified in the machine configuration files in the meta-fsl-arm/conf/machine directory. 1.3.5Customizing the Printed Board Name To customize the printed board name, use the checkboard() function. This function is called from the init_sequence[] array implemented inside board/ freescale/mx6 customize the printed board name. The brute force way or by using a more flexible identification method if implemented on the custom board. To customize the brute force way, delete identify_board_id( ) inside checkboard() and replace printf("Board: "); with printf("Board: i.MX 6 on If this replacement is not made, the custom board may use another identification method. The identification can be detected and printed by implementing the __print_board_info() function according to the identification method on the custom board. 1.4Debugging There are two ways for debugging: ?Use Realview ICE. ?Use printf. 1.4.1Using RealView ICE for Debugging Generally, we use RealView ICE to debug at a very early stage, for example, before uart initialization, or when it is difficult to debug with printf. 1.Make sure that your RealView ICE supports Cortex-A9. If not, you need to upgrade the firmware and the RealView software. 2.Load U-Boot (which is an elf file) in the root directory of U-Boot fully, or just symbol (faster) to debug step by step. NOTE We can make optimization level 0 in rules.mk, which is easier for debugging in RealView ICE. 1.4.2Using printf for debugging This is the most common method we use in debugging. You can print your value in the driver for debugging. NOTE If you want to use printf in early stages, such as in board_init, we can put uart initialization code earlier, such as in the board_early_init_f(). Chapter 2 Configuring the IOMUX Controller 2.1IOMUX Overview Before using the pins (or pads), users must select the desired function and correct values for characteristics such as voltage level, drive strength, and hysteresis. You can configure a set of registers from the IOMUX controller. i.MX 6Dual/6Quad For detailed information about each pin, see the "External Signals and Pin Multiplexing" chapter in the i.MX 6Dual/6Quad Multimedia Applications Processor Reference Manual. For additional information about the IOMUX controller block, see the "IOMUX Controller (IOMUXC)" chapter in the i.MX 6Dual/6Quad Multimedia Applications Processor Reference Manual. i.MX 6DualLite For detailed information about each pin, see the "External Signals and Pin Multiplexing" chapter in the i.MX 6DualLite Multimedia Applications Processor Reference Manual. For additional information about the IOMUX controller block, see the "IOMUX Controller (IOMUXC)" chapter in the i.MX 6DualLite Multimedia Applications Processor Reference Manual. i.MX 6SoloLite For detailed information about each pin, see the "External Signals and Pin Multiplexing" chapter in the i.MX 6SoloLite Multimedia Applications Processor Reference Manual. For additional information about the IOMUX controller block, see the "IOMUX Controller (IOMUXC)" chapter in the i.MX 6SoloLite Multimedia Applications Processor Reference Manual. 2.2Information for Setting IOMUX Controller Registers The IOMUX controller contains four sets of registers that affect the i.MX 6Dual/ 6Quadi.MX/6DualLite/i.MX 6Solo/i.MX 6SoloLite registers. ?General-purpose registers (IOMUXC_GPR x)-consist of registers that control PLL frequency, voltage, and other general purpose sets. ?"Daisy Chain" control registers (IOMUXC_ ?MUX control registers (changing pad modes): ?Select which of the pad's eight different functions (also called ALT modes) is used. ?Set the pad functions individually or by group using one of the following registers: ?IOMUXC_SW_MUX_CTL_PAD_ ?IOMUXC_SW_MUX_CTL_GRP_ ?Pad control registers (changing pad characteristics): ?Set pad characteristics individually or by group using one of the following registers: ?IOMUXC_SW_PAD_CTL_PAD_ ?IOMUXC_SW_PAD_CTL_GRP_ ?Pad characteristics are: ?SRE (1 bit slew rate control)-Slew rate control bit; selects between FAST/ SLOW slew rate output. Fast slew rate is used for high frequency designs. ?DSE (2 bits drive strength control)-Drive strength control bits; selects the drive strength (low, medium, high, or max). ?ODE (1 bit open drain control)-Open drain enable bit; selects open drain or CMOS output. ?HYS (1 bit hysteresis control)-Selects between CMOS or Schmitt Trigger when pad is an input. ?PUS (2 bits pull up/down configuration value)-Selects between pull up or down and its value. ?PUE (1 bit pull/keep select)-Selects between pull up or keeper. A keeper circuit help assure that a pin stays in the last logic state when the pin is no longer being driven. ?PKE (1 bit enable/disable pull up, pull down or keeper capability)-Enable or disable pull up, pull down, or keeper. ?DDR_MODE_SEL (1 bit ddr_mode control)-Needed when interfacing DDR memories. ?DDR_INPUT (1 bit ddr_input control)-Needed when interfacing DDR memories. 2.3Using IOMUX in the Device Tree - Example This is an example which shows how to use IOMUX in the Device Tree usdhc@0219c000 { /* uSDHC4 */ fsl,card-wired; vmmc-supply = <®_3p3v>; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc4_1>; }; iomuxc@020e0000 { compatible = "fsl,imx6q-iomuxc"; reg = <0x020e0000 0x4000>; /* shared pinctrl settings */ usdhc4 { pinctrl_usdhc4_1: usdhc4grp-1 { fsl,pins = < MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059 MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059 MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059 MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059 MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059 MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059 MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059 MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059 MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059 MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059 >; }; }; .... }; For details, see: Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt Documentation/devicetree/bindings/pinctrl/fsl,imx6*-pinctrl.txt Chapter 3 Registering a New UART Driver 3.1Enabling UART on Kernel Menuconfig Enable the UART driver on Linux menuconfig. This option is located at: -> Device Drivers -> Character devices -> Serial drivers <*> IMX serial port support [*] Console on IMX serial port After enabling the UART driver, build the Linux kernel and boot the board. 3.2UART Settings By default, the UART is configured as follows: ?Baud Rate: 9600 ?Data bits: 8 ?Parity: None ?Stop bits: 1 ?Flow Control: None 3.3File Names and Locations There are three Linux source code directories that contain relevant UART files. The header file is available in the directory Table below lists the UART files that are available on the directory