1 概述
1.1 boot rom
启动过程从上电复位开始,硬件复位逻辑迫使arm内核从片上的boot rom开始执行。NXP在内部ROM中写入了一段程序,SOC上电复位会执行这段代码,起到初始化硬件以及引导启动设备的启动。
boot rom 代码根据BOOT_MODE[1:0]的值以及熔丝或者GPIO对应的状态来确定启动设备。
1.2 boot rom 代码的主要功能
支持不同的启动设备。
串行下载程序
设备配置信息和插件(在bin文件的头部信息中就含有DCD)
基于数字签名和加密的高保证启动
低功耗唤醒模式
1.3 boot rom 支持的设备
NOR flash
NAND flash
OneNAND flash
SD/MMC
Serial(SPI) NOR flash and EEPROM
QSPI flash
1.4 低功耗模式唤醒
boot rom允许从低功耗模式唤醒,在复位时,boot rom 会检查电源门状态寄存器。当从低功耗模式唤醒时,内核会调过启动设备加载镜像,并跳转到保存在PERSISTENT_ENTRY0中的地址。(PERS-
ISTENT_ENTRY0)是系统复位控制器高级通用寄存器,这个寄存器只给boot rom代码使用,用户应用程序不应该去使用它。
1.5 设备配置数据(DCD)
设备配置数据(DCD)功能允许boot ROM代码从存储在引导设备上的外部程序映像获取SOC配置数据。DCD可用于对DDR控制器进行编程以获得最佳设置,从而提高引导性能。DCD仅限于被认为是启
动所必需的内存区域和外围地址。
1.6 内部RAM/ROM内存映射
2 启动模式
2.1 在SOC上电复位的时候会检查电源门状态寄存器。
2.2 内核行为
在设备启动的时候,内核的行为由启动模式引脚的设置决定。当从低功耗模式唤醒时,内核会调过时钟设置。boot在设备启动的时候,内核的行为由启动模式引脚的设置决定。当从低功耗模式唤醒时,内核会调过时钟设置。boot rom 会检查PERSISTENT_ENTRY0有没有指向有效的地址空间(启动设备的地址),
如果该寄存器执行的地址有效,则boot rom会从PERSISTENT_ENTRY0指向的地址开始执行程序。如果该寄存器的地址无效,则系统复位。
2.3 启动模式引脚设置
IMX6ULL有四种启动模式,其中一种保留,只给NXP使用,启动模式取决于内部BOOT_MODE[1:0](BOOT_MODE1和BOOT_MODE0两个管脚的高低电平)的二进制值,该值在设备启动后会储存在SRC_SBMR2
寄存器中,且启动完成后该值不受BOOT_MODE[1:0]的影响。
可用的启动模式:
00: Boot From Fuses
01: Serial Downloader
10: Internal Boot
11: Reserved
2.4 串行下载模式
串行下载器提供了通过USB和UART串行连接将程序映像下载到芯片的方法。在这个模式下,如果WDOG_ENABLE eFuse为1并持续轮询USB和USART连接,则boot rom 将WDOG1配置为fuse WDOG超时选择,
看门狗定时器开,在规定的时间内,如果没有发现有USB或者UART1/2上没有任何活动,则arm内核复位。
2.5 内部启动模式
当BOOT_MODE[1:0]寄存器的值为0b10的时候,就会进入内部启动模式。在这个模式,处理器会继续执行boot rom 的代码。
系统上电复位后,执行boot rom代码,并准备初始化硬件,从选择的启动设备中下载程序镜像,使用HAB库来进行验证,读取程序镜像头部信息,并跳转到程序镜像所指定的链接地址开始执行代码。
如果在内部启动的时候发生错误,则boot rom将会跳转到Serial Downloader模式。
3 设备控制
3.1 概览
设备控制描述了控制boot rom代码行为的外部输入行为,包括了启动设备的选择、启动设备的配置(总线宽度、速度等),一般来说,这些配置都是来源于芯片内部的eFUSEs。不过,我们可以通过GPIO
修改某些参数。
3.2 Boot eFUSEs 描述
我们基本上不会去通过修改熔丝俩选择启动设备,因为熔丝只可以修改一次。
SRC_SBMR2寄存器的BT_FUSE_SEL位与BOOT_MODE[1:0]共同决定了启动设置是否由GPIO引脚控制。当BOOT_MODE[1:0] = 10,BT_FUSE_SEL = 0时,SRC_SBMR寄存器的值将被GPIO覆盖;如果BT_FUSE_SEL = 1
时,SRC_SBMR寄存器的特殊位将由eFUSE设置。当BOOT_MODE[1:0] = 00,BT_FUSE_SEL = 0时,启动配置熔丝没有被编程,自动跳转到serial downloader;BT_FUSE_SEL = 1时,启动配置eFUSE已经编程,
执行常规启动流程。
BOOT_CFG1[7:0]、BOOT_CFG2[7:0]、BOOT_CFG4[7:0]的值取决于启动时对应GPIO的高低电平,其中BOOT_CFG4[7]用于调试目的,设置为0失能。WDOG_ENABLE为1开启看门狗复位计数器。
3.3 GPIO启动覆盖eFUSE列表
package pin direction on reset eFuse
BOOT_MODE1 Input Boot mode selection
BOOT_MODE0 Input Boot mode selection
LCD1_DATA00 Input BOOT_CFG1[0]
LCD1_DATA01 Input BOOT_CFG1[1]
LCD1_DATA02 Input BOOT_CFG1[2]
LCD1_DATA03 Input BOOT_CFG1[3]
LCD1_DATA04 Input BOOT_CFG1[4]
LCD1_DATA05 Input BOOT_CFG1[5]
LCD1_DATA06 Input BOOT_CFG1[6]
LCD1_DATA07 Input BOOT_CFG1[7]
LCD1_DATA08 Input BOOT_CFG2[0]
LCD1_DATA09 Input BOOT_CFG2[1]
LCD1_DATA10 Input BOOT_CFG2[2]
LCD1_DATA11 Input BOOT_CFG2[3]
LCD1_DATA12 Input BOOT_CFG2[4]
LCD1_DATA13 Input BOOT_CFG2[5]
LCD1_DATA14 Input BOOT_CFG2[6]
LCD1_DATA15 Input BOOT_CFG2[7]
LCD1_DATA16 Input BOOT_CFG4[0]
LCD1_DATA17 Input BOOT_CFG4[1]
LCD1_DATA18 Input BOOT_CFG4[2]
LCD1_DATA19 Input BOOT_CFG4[3]
LCD1_DATA20 Input BOOT_CFG4[4]
LCD1_DATA21 Input BOOT_CFG4[5]
LCD1_DATA22 Input BOOT_CFG4[6]
LCD1_DATA23 Input BOOT_CFG4[7]
根据BT_FUSE_SEL保险丝的设置,所提供的输入引脚在启动时采样,并可用于覆盖相应的eFUSE值。
DCD是包含在程序映像头部中的配置信息,ROM使用其信息来配置片上外设。
4 设备初始化
4.1 ROM详细信息与初始化
初始化详细内容:
The ROM memory map
The RAM memory map
On-chip blocks that the ROM must use or change the POR register default values
Clock initialization
Enabling the MMU/L2 cache
Exception handling and interrupt handling
4.2 内部 RAM/ROM 内存映射
IMX6ULL有96KB的内部ROM,128KB的内部RAM。
4.3 启动块激活
boot rom代码将许多硬件初始化,这些硬件在后面的启动引导中起到很重要的作用。
ROM在启动引导过程中配置并使用以下块,实际使用的块取决于引导模式和引导设备:
• APBH—the DMA engine to drive the GPMI module (用于驱动GPMI模块的DMA引擎)
• BCH—40-bit error correction hardware engine with the AXI bus master and a
private connection to the GPMI (40位纠错硬件引擎,带有AXI总线主机和GPMI专用连接)
• CCM—Clock Control Module (时钟控制模块)
• ECSPI—Enhanced Configurable Serial Peripheral Interface (增强型可配置串行外围接口)
• EIM—External Interface Module used for the NOR and OneNAND devices (NOR flash和OneNAND flash使用的外部接口模块)
• GPMI—NAND controller pin interface (NAND控制器引脚接口)
• OCOTP_CTRL—On-Chip OTP Controller; the OCOTP contains the eFUSEs (片上OTP控制器;OCOTP包含EFUse)
• IOMUXC—I/O Multiplexer Control which allows the GPIO use to override the (I/O多路复用器控制,允许GPIO用于覆盖eFUSE引导设置)
eFUSE boot settings;
• IOMUXC GPR—I/O Multiplexer Control General-Purpose Registers (I/O多路复用器控制通用寄存器)
• DCP—Data Co-Processor (协同处理器)
• QSPI—QuadSPI flash (6线SPI,在SPI协议的基础上,增加了队列传输机制,推出了队列串行外围接口协议)
• SNVS—Secure Non-Volatile Storage (安全非易失性存储)
• SRC—System Reset Controller (系统复位控制器)
• UART—Universal Asynchronous Receiver/Transmitter controller (通用异步接收机/发射机控制器)
• USB—used for the serial download of a boot device provisioning program (用于串行下载引导设备配置程序)
• USDHC—Ultra-Secure Digital Host Controller (超安全数字主机控制器)
• WDOG-1—Watchdog timer (看门狗定时器)
4.4 启动时的时钟设置
下表显示了boot rom使用到的时钟及其时钟源。
4.5 使能MMU和caches
boot rom使能MMU和caches以提高启动速度。
一级指令缓存在图像下载开始时启用。一级数据缓存、二级缓存和MMU在图像认证期间启用。当HAB认证完成时,ROM禁用一级数据缓存、二级缓存和MMU。
一级指令缓存、一级数据cahce、二级缓存和MMU由eFuse(GPIO可覆盖)控制。默认情况下,这些功能已启用。
在SEC_CONFIG=01处于非安全引导时启用MMU,并将镜像向量表中的CSF指针设置为空,对引导性能没有影响。使用此配置,建议熔断BT_MMU_DISABLE保险丝(BT_MMU_DISABLE=0)。
4.6 启动中的中断处理
在boot rom启动的时候中断是被禁用的,在后面的启动过程中可以被启用。
5 启动设备(内部启动模式)
5.1 IMX6ULL支持的启动设备
• NOR flash with the External Interface Module (EIM), located on CS0, 16-bit bus
width.
• OneNAND flash with the EIM interface, located on CS0, 16-bits bus width.
• Raw NAND (MLC and SLC), and Toggle-mode NAND flash through GPMI-2
interface. Page sizes of 2 KB, 4 KB, and 8 KB. The bus widths of 8-bit with 2
through 40-bit BCH hardware ECC (Error Correction) are supported.
• Quad SPI flash.
• SD/MMC/eSD/SDXC/eMMC4.4 via USDHC interface, supporting high capacity
cards.
• EEPROM boot via SPI (serial flash).
5.2 外部引导设备类型的选择由BOOT_CFG1[7:4]eFUSEs控制,见下表
5.3 扩展设备
SD/MMC/eSD/eMMC/SDXC引导可以使用USDHC端口执行,基于BOOT_CFG2[4:3]设置,或者与引导时的GPIO输入值相关。
启动引导代码支持以下标准:
• MMCv4.4 or less
• eMMCv4.4 or less
• SDv2.0 or less
• eSDv2.10 rev-0.9, with or without FAST_BOOT
• SDXCv3.0
MMC/SD/eSD/SDXC/eMMC可以连接到任何USDHC块,并且可以通过将4KB的数据从MMC/SDESD/eMMC设备复制到内部RAM来启动。
在检查来自程序镜像的镜像矢量表Tag的值(0xD1)之后,ROM代码执行DCD检查。在成功提取DCD之后,ROM代码从引导数据结构
中提取要复制到RAM设备的目标指针和镜像长度,从该RAM设备执行代码。
加载到SD/MMC引导中的最大映像大小为32 MB(裸机)。这是由于ROM分配的uSDHC ADMA缓冲区描述符数量有限。
程序镜像的初始4KB必须包含IVT、DCD和BD。
5.4 SD/MMC的I/O多路复用配置
6 烧写镜像
6.1 程序镜像必须包含的数据结构
Image Vector table (位于固定地址的指针列表,ROM检查该列表以确定程序映像的其他组件的位置)
Boot data (指示程序映像位置、程序映像大小和插件)
Device configuration data (IC配置信息)
user code and data (用户代码和数据)
6.2 Image Vector Table and Boot Data
图像矢量表(IVT)是ROM从提供程序镜像的引导设备读取的数据结构,该程序图像包含执行成功引导所需的数据组件。
IVT包括程序镜像入口点(链接地址)、指向设备配置数据(DCD)的指针以及ROM在引导过程中使用的其他指针。ROM将IVT定位在由连接到芯片的引导设备确定的固定地址上。
下表中定义了每种引导设备类型的IVT偏移量与基址和初始加载区域大小。IVT的位置是ROM的唯一固定要求。剩余部分或图像存储器映射是灵活的,由IVT的内容决定。由表可知,
对于SD/MMC/eSD/eMMC/SDXC而言,其初始加载区域为4KB,IVT偏移量为1KB,所以下载IVT表从启动设备的基地址开始存放,其后存放BD和DCD数据,相对启动设备的基地址开始
偏移4KB是可执行程序(bin文件)的存放地址。
6.2.1 Image Vector Table
header
entry : Absolute address of the first instruction to execute from the image(程序第一条指令所在的地址,也就是链接地址)
reserved1: Reserved and should be zero
dcd : Absolute address of the image DCD. The DCD is optional so this field may be set to NULL if no DCD is required. (DCD表的绝对位置,DCD是可选的,
如果不需要可以设置为空)
boot data: Absolute address of the boot data (boot data的绝对地址)
self : Absolute address of the IVT. Used internally by the ROM. (IVT复制到DDR后所处的位置)
csf : Absolute address of the Command Sequence File (CSF) used by the HAB library. (CSF地址,不需要设置为0)
reserved2: Reserved and should be zero
IVT向量表一共占32个字节
IVT header
Tag:固定为0xD1,一个字节
Length:IVT表的总长度,长度是固定的32字节(0x20),占据两个字节,采用大端存储。
Version:设置为0x40或者0x41.
6.2.2 Boot data
start:整个程序镜像的地址,包括前面的地址偏移
length:程序镜像大小的上限,采用大端存储。
plugin:插件
6.3 Device Configuration Data (DCD)
在上电复位后,芯片使用系统外设的默认寄存器的值,而有些设置不是实现系统性能的理想设置,甚至有些外围设备必须在试用前进行配置。
DCD是包含在程序镜像里的配置信息,ROM将用其来配置外围设备。
例如,EIM默认设置允许内核在重置后立即连接到NOR闪存设备。这允许芯片与任何NOR闪存设备接口,但具有性能慢的缺点。此外,一些组件
(如DDR)需要一些寄存器编程序列作为配置的一部分,然后才能使用。DCD功能可用于将EIM寄存器和MMDC寄存器编程为最佳设置。
ROM通过IVT表中的信息来确定DCD的位置,DCD表最大为1768字节。
DCD data format见下图
DCD header
Tag: 固定为0xD2
Length: DCD表的大小,包括header,采用大端存储。
Version: 0x40或者0x41
6.3.1 Write data command
Tag: 固定为0xcc
Length: 表示大端模式的命令总长度,包括了header
Parameter:
bytes(bit[2:0]): 目标位置的宽度
flags(bit[7:3]): 命令行为的控制标志
Data Mask(bit[3]): if set, only specific bits may be overwritten at the target address
(otherwise all bits may be overwritten)
Data Set(bit[4]): if set, the bits at the target address are overwritten with this flag
(otherwise it is ignored)
bit[7:5]无效
Data Mask和Data Set决定了value写入address的方式。
Address: the target address to which the data must be written (4个字节)
Value/Mask: the data value (or bitmask) to be written to the preceding address (4个字节)
如果任何目标地址的对齐方式与参数字段中指示的数据宽度不同,则不会写入任何值。
如果任何值大于或任何位掩码大于参数字段中指示的数据宽度所允许的宽度,则不会写入任何值。
如果任何目标地址不在允许的区域内,则不会写入任何值。
芯片的允许块与目标地址见下表:
6.3.2 Check data command
检查数据命令用于测试源地址中给定的1、2或4字节位掩码。一般不用。
6.3.3 NOP command
此命令无效
6.3.4 unlock command
解锁命令用于防止退出ROM时锁定特定引擎功能。
DCD表一般包含Write data command即可。
7 插件镜像
ROM支持有限数量的引导设备。当使用其他设备作为引导源(例如,以太网、CDROM或USB)时,必须将支持的引导设备(通常是串行ROM)用作固件,以提供缺少的引导驱动程序。
一般不用,如果需要插件,在boot data中表明。
8 串行下载器
8.1 描述
串行下载器提供了通过USB和UART串行连接将程序映像下载到芯片的方法。
串行下载器提供了通过USB和UART串行连接将程序映像下载到芯片的方法。在这个模式下,如果WDOG_ENABLE eFuse为1并持续轮询USB和USART连接,则boot rom 将WDOG1配置为fuse WDOG超时选择,
看门狗定时器开,在规定的时间内,如果没有发现有USB或者UART1/2上没有任何活动,则arm内核复位。
8.2 USB
USB支持由USBOH3USBO2(符合USB 2.0规范的USB OTG1USB OTG核心控制器)和USBPHY(HS USB收发器)组成。
ROM支持USB OTG端口用于引导。芯片上的其他USB端口不支持启动。
USB驱动程序实现为USB HID类。四个HID Report ID 的集合用于实现数据传输的SDP协议,如下表:
8.2.1 USB configuration details
USB OTG功能设备驱动程序支持最大数据包大小为512 B的高速(HS用于UTMI)非流模式和低级USB OTG功能。
在IOMUX中未配置UTMI PHY的接口信号。UTMI PHY接口使用IC上的专用触点。在芯片数据手册上有详细信息。
8.2.2 UART
ROM支持UART1和UART2端口用于引导启动,芯片上的其他UART端口不支持引导。如果检测到UART FIFO中的数据就绪事件,
ROM进入UART串行下载引导模式,并开始从UART端口读取数据,该端口报告数据就绪事件。UART接收数据板上的噪声可能
导致UART控制器报告“数据就绪”事件,这是一个假的就绪事件,并进一步导致ROM进入UART串行下载模式。硬件设计师必须注意避免此类异常。
串口配置信息:
start bit : 1 bit
stop bit : 1 bit
parity bit: no needed
flow control: no needed
baud rate : 115200 bps
8.2.3 UART eFUSE配置
选自serial download模式后,boot ROM代码会设置ROM BOOT 引导带的相应寄存器。
信息内容如图:
8.2.4 IOMUX configuration for UART
9 烧写工具
- 根据IMX6U的系统引导流程编写的裸机烧写工具。
/*
* file name : imxdownload.c
* 根据正点原子所写代码做了一点修改。
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "./imxdownload.h"
#define SHELL_CMD_SIZE (100)
#define BIN_OFFSET (3072)
enum {
ddr_256 = 0, // 256
ddr_512 = 1, // 512
};
int main(int argc, char const *argv[])
{
unsigned char* file_buf = NULL;
unsigned char* sheel_cmd_buf = NULL;
FILE* file = NULL;
char file_name[64] = {0};
strcpy(file_name, argv[1]);
char device_name[64] = {0};
strcpy(device_name, argv[2]);
char download_file_name[32] = {0};
int file_size = 0;
int write_bytes = 0;
int ddr_type = ddr_512; // default
if (argc != 3 && argc != 4)
{
printf("pleause use command \"%s <-512MB or -256MB> <source_bin> <sd_device>\"\n", argv[0]);
}
else if (argc == 4)
{
for (size_t i = 0; i < argc; i++)
{
char const *param = argv[i];
if (param[0] != '-')
continue;
if (strcmp(param, "-256MB"))
ddr_type = ddr_256;
else if (strcmp(param, "-512MB"))
ddr_type = ddr_512;
}
strcpy(file_name, argv[2]);
strcpy(device_name, argv[3]);
}
file = fopen(file_name, "rb");
if (file == NULL)
{
printf("can't open file %s\n", file_name);
return -1;
}
fseek(file, 0, SEEK_END);
file_size = ftell(file);
fseek(file, 0, SEEK_SET);
printf("file %s size : %d\n", file_name, file_size);
file_buf = (unsigned char*)malloc(file_size + BIN_OFFSET);
if (file_buf == NULL)
{
printf("malloc error\n");
return -1;
}
memset(file_buf, 0, file_size + BIN_OFFSET);
fread(file_buf + BIN_OFFSET, 1, file_size, file);
fclose(file);
if (ddr_type == ddr_256)
{
printf("Board DDR size : %dMB\n", 256);
memcpy(file_buf, imx6_256mb_ivtdcd_table, sizeof(imx6_256mb_ivtdcd_table));
}
else if (ddr_type == ddr_512)
{
printf("Board DDR size : %dMB\n", 512);
memcpy(file_buf, imx6_512mb_ivtdcd_table, sizeof(imx6_512mb_ivtdcd_table));
}
sheel_cmd_buf = (unsigned char*)malloc(SHELL_CMD_SIZE);
if (sheel_cmd_buf == NULL)
{
printf("malloc error in %d line\n", __LINE__);
free(file_buf);
return -1;
}
memset(sheel_cmd_buf, 0, SHELL_CMD_SIZE);
sprintf(download_file_name, "%s_load.imx", strtok(file_name, "."));
printf("delete old %s\n", download_file_name);
memset(sheel_cmd_buf, 0, SHELL_CMD_SIZE);
sprintf(sheel_cmd_buf, "rm -rf %s", download_file_name);
system(sheel_cmd_buf);
memset(sheel_cmd_buf, 0, SHELL_CMD_SIZE);
printf("touch new %s file\n", download_file_name);
sprintf(sheel_cmd_buf, "touch %s", download_file_name);
system(sheel_cmd_buf);
file = fopen(download_file_name, "wb");
if (file == NULL)
{
printf("can't open file %s\n", download_file_name);
free(file_buf);
free(sheel_cmd_buf);
return -1;
}
write_bytes = fwrite(file_buf, 1, file_size + BIN_OFFSET, file);
if (write_bytes != (file_size + BIN_OFFSET))
{
printf("write buf to %s error\n", download_file_name);
fclose(file);
free(file_buf);
free(sheel_cmd_buf);
return -1;
}
fclose(file);
free(file_buf);
/*
* param:
* iflag: 根据给定值进行读
* oflag: 根据给定值进行写
* if : 要读取的标准输入
* of : 要写入的标准输出
* bs : 一次要写入或读取的最大字节数,覆盖ibs和obs
* seek : 在输出时调过N个obs的大小
* value:
* dsync: 对数据采用同步I/O读取
*/
sprintf(sheel_cmd_buf, "sudo dd iflag=dsync oflag=dsync if=%s of=%s bs=512 seek=2", download_file_name, device_name);
printf("download %s to %s\n", download_file_name, device_name);
system(sheel_cmd_buf);
free(sheel_cmd_buf);
return 0;
}
#ifndef _IMXDOWNLOAD_H
#define _IMXDOWNLOAD_H
/* IMX6U IVT DCD表信息 暂时定义为1K Bytes,此表是读取的u-boot.imx前1K Bytes
* imx6_ivedcd_table[9]是指明代码长度的,本应该根据实际的代码长度来修改
* 这里为了方便,就直接定义为2M Bytes,即
*/
const int imx6_512mb_ivtdcd_table[256] = {
// IVT
0X402000D1,0X87800000,0X00000000,0X877FF42C,0X877FF420,0X877FF400,0X00000000,0X00000000,
// BD
/* 整个镜像的起始地址,整个镜像大小,插件 */
0X877FF000,0X00200000,0X00000000,
// DCD
/*
* 0X40E801D2是DCD表的头部,其中E801是大端模式,即01E8,代表整个DCD表大小为488字节。
* 0X04E401CC是写数据命令,其中E401是大端模式,代表整个数据命令的大小(包括header)。
* 整个数据命令都为大端模式
*/
0X40E801D2,0X04E401CC,
/*
* 开启CCGR0~CCGR6寄存器上的所有时钟
*/
0X68400C02,0XFFFFFFFF,0X6C400C02,0XFFFFFFFF,0X70400C02,0XFFFFFFFF,
0X74400C02,0XFFFFFFFF,0X78400C02,0XFFFFFFFF,0X7C400C02,0XFFFFFFFF,0X80400C02,0XFFFFFFFF,
// 配置DDR所用到的所有IO
0XB4040E02,0X00000C00,0XAC040E02,0X00000000,0X7C020E02,0X30000000,0X50020E02,0X30000000,
0X4C020E02,0X30000000,0X90040E02,0X30000000,0X88020E02,0X30000C00,0X70020E02,0X00000000,
0X60020E02,0X30000000,0X64020E02,0X30000000,0XA0040E02,0X30000000,0X94040E02,0X00000200,
0X80020E02,0X30000000,0X84020E02,0X30000000,0XB0040E02,0X00000200,0X98040E02,0X30000000,
0XA4040E02,0X30000000,0X44020E02,0X30000000,0X48020E02,0X30000000,
//配置 MMDC 控制器,初始化 DDR3
0X1C001B02,0X00800000,0X00081B02,0X030039A1,0X0C081B02,0X0B000300,0X3C081B02,0X44014801,
0X48081B02,0X302C4040,0X50081B02,0X343E4040,0X1C081B02,0X33333333,0X20081B02,0X33333333,
0X2C081B02,0X333333F3,0X30081B02,0X333333F3,0XC0081B02,0X09409400,0XB8081B02,0X00080000,
0X04001B02,0X2D000200,0X08001B02,0X3030331B,0X0C001B02,0XF3526B67,0X10001B02,0X630B6DB6,
0X14001B02,0XDB00FF01,0X18001B02,0X40172000,0X1C001B02,0X00800000,0X2C001B02,0XD2260000,
0X30001B02,0X23106B00,0X40001B02,0X4F000000,0X00001B02,0X00001884,0X90081B02,0X00004000,
0X1C001B02,0X32800002,0X1C001B02,0X33800000,0X1C001B02,0X31800400,0X1C001B02,0X30802015,
0X1C001B02,0X40800004,0X20001B02,0X00080000,0X18081B02,0X27020000,0X04001B02,0X2D550200,
0X04041B02,0X06100100,0X1C001B02,0X00000000,
// 无效数据
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,
};
const int imx6_256mb_ivtdcd_table[256] = {
0X402000D1,0X87800000,0X00000000,0X877FF42C,0X877FF420,0X877FF400,0X00000000,0X00000000,
0X877FF000,0X00076000,0X00000000,0X40E801D2,0X04E401CC,0X68400C02,0XFFFFFFFF,0X6C400C02,
0XFFFFFFFF,0X70400C02,0XFFFFFFFF,0X74400C02,0XFFFFFFFF,0X78400C02,0XFFFFFFFF,0X7C400C02,
0XFFFFFFFF,0X80400C02,0XFFFFFFFF,0XB4040E02,0X00000C00,0XAC040E02,0X00000000,0X7C020E02,
0X30000000,0X50020E02,0X30000000,0X4C020E02,0X30000000,0X90040E02,0X30000000,0X88020E02,
0X30000C00,0X70020E02,0X00000000,0X60020E02,0X30000000,0X64020E02,0X30000000,0XA0040E02,
0X30000000,0X94040E02,0X00000200,0X80020E02,0X30000000,0X84020E02,0X30000000,0XB0040E02,
0X00000200,0X98040E02,0X30000000,0XA4040E02,0X30000000,0X44020E02,0X30000000,0X48020E02,
0X30000000,0X1C001B02,0X00800000,0X00081B02,0X030039A1,0X0C081B02,0X04000000,0X3C081B02,
0X3C013C01,0X48081B02,0X38324040,0X50081B02,0X28304040,0X1C081B02,0X33333333,0X20081B02,
0X33333333,0X2C081B02,0X333333F3,0X30081B02,0X333333F3,0XC0081B02,0X09409400,0XB8081B02,
0X00080000,0X04001B02,0X2D000200,0X08001B02,0X3030331B,0X0C001B02,0XF352433F,0X10001B02,
0X630B6DB6,0X14001B02,0XDB00FF01,0X18001B02,0X40172000,0X1C001B02,0X00800000,0X2C001B02,
0XD2260000,0X30001B02,0X23104300,0X40001B02,0X47000000,0X00001B02,0X00001883,0X90081B02,
0X00004000,0X1C001B02,0X32800002,0X1C001B02,0X33800000,0X1C001B02,0X31800400,0X1C001B02,
0X30802015,0X1C001B02,0X40800004,0X20001B02,0X00080000,0X18081B02,0X27020000,0X04001B02,
0X2D550200,0X04041B02,0X06100100,0X1C001B02,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
};
#endif