您现在的位置是:首页 >其他 >IMX6ULL裸机篇之DDR3实验-更新 imxdownload.h网站首页其他

IMX6ULL裸机篇之DDR3实验-更新 imxdownload.h

凌雪舞 2024-06-24 12:01:01
简介IMX6ULL裸机篇之DDR3实验-更新 imxdownload.h

一.   DDR实验

之前关于 IMX6ULL开发板,有关DDR实验。做了DDR内存芯片的初始化,校验与超频测试。

博文链接如下:

IMX6ULL裸机篇之DDR3初始化_凌雪舞的博客-CSDN博客

IMX6ULL裸机篇之DDR3校验与超频测试_凌雪舞的博客-CSDN博客

经过了初始化,校验,超频测试后,最终会存在一个 .inc 后缀的文件,该文件为DDR的初始化配置脚本文件。

DDR实验中,就是 "DDR_256MB.inc" 文件,文件中都是一些关于时钟或DDR寄存器的配置。

"DDR_256MB.inc" 文件中内容即与 DCD数据相一致。

DCD数据:

复位以后, I.MX6U 片内的所有寄存器都会复位为默认值,但是这些默认值往往不是我们
想要的值,而且有些外设我们必须在使用之前初始化它。
为此 I.MX6U 提出了一个 DCD(Device Config Data) 的概念,和 IVT Boot Data 一样, DCD 也是添加到 load.imx 里面的,紧跟在 IVT Boot Data 后面, IVT 里面也指定了 DCD 的位置。 DCD 其实就是 I.MX6U 寄存器地址和对应 的配置信息集合, Boot ROM 会使用这些寄存器地址和配置集合来初始化相应的寄存器,比如 开启某些外设的时钟、初始化 DDR 等等。
DCD数据结构为:"寄存器地址+对应值" 的结构方式,如下所示(参考IMX6ULL驱动开发文档):

 

二.  更新 imxdownload.h中寄存器值

更新 imxdownload.h中寄存器的值作用:

如果不更新校验(与超频测试)后的涉及 DDR 的寄存器的值,那么,每次DDR初始化就是错误的。因为裸机篇中给程序添加头部信息会用到 "imxdownload "工具,而头部信息其中就包括 DDR的初始化。

1.  imxdownload软件

裸机篇中,正点原子专门编写了一个软件来将编译出来的 .bin 文件烧写到 SD 卡中,这个软件叫做
imxdownload ”。

前面裸机篇的实验中,程序不能直接放在 SD卡运行。

imxdownload 所生成的 load.imx 就是在 led.bin 前面加上 IVT+Boot data+DCD这些头数据。

正点原子提供的一个C源码,需要编译生成 imxdownload工具,负责裸机程序的生成。

路径如下所示:

2.   更新 imxdowload.h中DDR寄存器值

这里我用的阿尔法开发板上,DDR芯片型号是 NT5CC128M16JR-EKI,256MB 大小的DDR内存芯片即 与正点原子视频中不同(正点原子视频中用的是 512MB)。

左大神讲到,如果用的DDR内存芯片是 128MB 或 2567MB的,经过校准测试完成之后,一定要更新正点原子提供的  download.h中的寄存器的值。

更新方法:更新到与 "DDR_256MB.inc" 配置文件中寄存器的值一致。

DDR_256MB.inc文件内容如下:

//=============================================================================			
//init script for i.MX6UL DDR3			
//=============================================================================			
// Revision History			
// v01			
//=============================================================================			
			
wait = on			
//=============================================================================			
// Disable	WDOG		
//=============================================================================			
setmem /16	0x020bc000 =	0x30	
			
//=============================================================================			
// Enable all clocks (they are disabled by ROM code)			
//=============================================================================			
setmem /32	0x020c4068 =	0xffffffff	
setmem /32	0x020c406c =	0xffffffff	
setmem /32	0x020c4070 =	0xffffffff	
setmem /32	0x020c4074 =	0xffffffff	
setmem /32	0x020c4078 =	0xffffffff	
setmem /32	0x020c407c =	0xffffffff	
setmem /32	0x020c4080 =	0xffffffff	
			
			
//=============================================================================			
// IOMUX			
//=============================================================================			
//DDR IO TYPE:			
setmem /32	0x020e04b4 =	0x000C0000	// IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE 
setmem /32	0x020e04ac =	0x00000000	// IOMUXC_SW_PAD_CTL_GRP_DDRPKE 
			
//CLOCK:			
setmem /32	0x020e027c =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0
			
//ADDRESS:			
setmem /32	0x020e0250 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS
setmem /32	0x020e024c =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS
setmem /32	0x020e0490 =	0x00000028	// IOMUXC_SW_PAD_CTL_GRP_ADDDS 
			
//Control:			
setmem /32	0x020e0288 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET
setmem /32	0x020e0270 =	0x00000000	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2 - DSE can be configured using Group Control Register: IOMUXC_SW_PAD_CTL_GRP_CTLDS
setmem /32	0x020e0260 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0
setmem /32	0x020e0264 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1
setmem /32	0x020e04a0 =	0x00000028	// IOMUXC_SW_PAD_CTL_GRP_CTLDS 
			
//Data Strobes:			
setmem /32	0x020e0494 =	0x00020000	// IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL 
setmem /32	0x020e0280 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 
setmem /32	0x020e0284 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 
			
//Data:			
setmem /32	0x020e04b0 =	0x00020000	// IOMUXC_SW_PAD_CTL_GRP_DDRMODE
setmem /32	0x020e0498 =	0x00000028	// IOMUXC_SW_PAD_CTL_GRP_B0DS 
setmem /32	0x020e04a4 =	0x00000028	// IOMUXC_SW_PAD_CTL_GRP_B1DS 
			
setmem /32	0x020e0244 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0
setmem /32	0x020e0248 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1
			
			
//=============================================================================			
// DDR Controller Registers			
//=============================================================================			
// Manufacturer:	Micron		
// Device Part Number:	MT41K256M16HA-125		
// Clock Freq.: 	400MHz		
// Density per CS in Gb: 	2		
// Chip Selects used:	1		
// Number of Banks:	8		
// Row address:    	14		
// Column address: 	10		
// Data bus width	16		
//=============================================================================			
setmem /32	0x021b001c =	0x00008000	// MMDC0_MDSCR, set the Configuration request bit during MMDC set up
			
//=============================================================================			
// Calibration setup.			
//=============================================================================			
setmem /32	0x021b0800 =	0xA1390003	// DDR_PHY_P0_MPZQHWCTRL, enable both one-time & periodic HW ZQ calibration.
			
// For target board, may need to run write leveling calibration to fine tune these settings.			
setmem /32	0x021b080c  =	0x00000000	
			
//Read DQS Gating calibration			
setmem /32	0x021b083c =	0x013C0138	// MPDGCTRL0 PHY0
			
//Read calibration			
setmem /32	0x021b0848 =	0x40403036	// MPRDDLCTL PHY0
			
//Write calibration                     			
setmem /32	0x021b0850 =	0x4040382C	// MPWRDLCTL PHY0
			
//read data bit delay: (3 is the reccommended default value, although out of reset value is 0)			
setmem /32	0x021b081c =	0x33333333	// MMDC_MPRDDQBY0DL
setmem /32	0x021b0820 =	0x33333333	// MMDC_MPRDDQBY1DL
			
//write data bit delay: 			
setmem /32	0x021b082c =	0xF3333333	// MMDC_MPWRDQBY0DL
setmem /32	0x021b0830 =	0xF3333333	// MMDC_MPWRDQBY1DL
			
//DQS&CLK Duty Cycle			
setmem /32	0x021b08c0 =	0x00921012	// [MMDC_MPDCCR] MMDC Duty Cycle Control Register
			
// Complete calibration by forced measurement:                  			
setmem /32	0x021b08b8 = 	0x00000800	// DDR_PHY_P0_MPMUR0, frc_msr
//=============================================================================			
// Calibration setup end			
//=============================================================================			
			
//MMDC init: 			
setmem /32	0x021b0004 =	0x0002002D	// MMDC0_MDPDC
setmem /32	0x021b0008 =	0x1B333030	// MMDC0_MDOTC
setmem /32	0x021b000c =	0x3F4352F3	// MMDC0_MDCFG0
setmem /32	0x021b0010 =	0xB66D0B63	// MMDC0_MDCFG1
setmem /32	0x021b0014 =	0x01FF00DB	// MMDC0_MDCFG2
			
//MDMISC: RALAT kept to the high level of 5. 			
//MDMISC: consider reducing RALAT if your 528MHz board design allow that. Lower RALAT benefits: 			
//a. better operation at low frequency, for LPDDR2 freq < 100MHz, change RALAT to 3			
//b. Small performence improvment 			
setmem /32	0x021b0018 =	0x00211740	// MMDC0_MDMISC
setmem /32	0x021b001c =	0x00008000	// MMDC0_MDSCR, set the Configuration request bit during MMDC set up
setmem /32	0x021b002c =	0x000026D2	// MMDC0_MDRWD
setmem /32	0x021b0030 =	0x00431023	// MMDC0_MDOR
setmem /32	0x021b0040 =	0x00000047	// Chan0 CS0_END 
setmem /32	0x021b0000 =	0x83180000	// MMDC0_MDCTL
			
setmem /32	0x021b0890 =	0x00400a38	// MPPDCMPR2
			
//Mode register writes                 			
setmem /32	0x021b001c =	0x02008032	// MMDC0_MDSCR, MR2 write, CS0
setmem /32	0x021b001c =	0x00008033	// MMDC0_MDSCR, MR3 write, CS0
setmem /32	0x021b001c =	0x00048031	// MMDC0_MDSCR, MR1 write, CS0
setmem /32	0x021b001c =	0x15208030	// MMDC0_MDSCR, MR0write, CS0
setmem /32	0x021b001c =	0x04008040	// MMDC0_MDSCR, ZQ calibration command sent to device on CS0
			
//setmem /32	0x021b001c =	0x0200803A	// MMDC0_MDSCR, MR2 write, CS1
//setmem /32	0x021b001c =	0x0000803B	// MMDC0_MDSCR, MR3 write, CS1
//setmem /32	0x021b001c =	0x00048039	// MMDC0_MDSCR, MR1 write, CS1
//setmem /32	0x021b001c =	0x15208038	// MMDC0_MDSCR, MR0write, CS1
//setmem /32	0x021b001c =	0x04008048	// MMDC0_MDSCR, ZQ calibration command sent to device on CS1
			
setmem /32	0x021b0020 =	0x00007800	// MMDC0_MDREF
			
setmem /32	0x021b0818 =	0x00000227	// DDR_PHY_P0_MPODTCTRL
			
setmem /32	0x021b0004 =	0x0002556D	// MMDC0_MDPDC now SDCTL power down enabled
			
setmem /32	0x021b0404 =	0x00011006	// MMDC0_MAPSR ADOPT power down enabled, MMDC will enter automatically to self-refresh while the number of idle cycle reached.
			
setmem /32	0x021b001c =	0x00000000	// MMDC0_MDSCR, clear this register (especially the configuration bit as initialization is complete)

imxdownload.h 中代码中,有两个数组,分别为 512MB与  256MB大小的。

数组内部的数据结构分布:寄存器地址+对应值

我这里使用的开发板上的 DDR内存芯片是 256MB。所以,这里是更新 256MB大小的数组内部寄存器的值。根据 "DDR_256MB.inc" 配置文件,更新 imxdownload.h文件中寄存器的值。

imxdownload.h文件中涉及 256MB的数组如下(这里涉及的寄存器的值已经做过更新):

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,
0X28000000,0X50020E02,0X28000000,0X4C020E02,0X28000000,0X90040E02,0X28000000,0X88020E02,
0X28000C00,0X70020E02,0X00000000,0X60020E02,0X28000000,0X64020E02,0X28000000,0XA0040E02,
0X28000000,0X94040E02,0X00000200,0X80020E02,0X28000000,0X84020E02,0X28000000,0XB0040E02,
0X00000200,0X98040E02,0X30000000,0XA4040E02,0X30000000,0X44020E02,0X28000000,0X48020E02,
0X28000000,0X1C001B02,0X00800000,0X00081B02,0X030039A1,0X0C081B02,0X00000000,0X3C081B02,
0X38013C01,0X48081B02,0X36304040,0X50081B02,0X2C384040,0X1C081B02,0X33333333,0X20081B02,
0X33333333,0X2C081B02,0X333333F3,0X30081B02,0X333333F3,0XC0081B02,0X12109200,0XB8081B02,
0X00080000,0X04001B02,0X2D000200,0X08001B02,0X3030331B,0X0C001B02,0XF352433F,0X10001B02,
0X630B6DB6,0X14001B02,0XDB00FF01,0X18001B02,0X40172100,0X1C001B02,0X00800000,0X2C001B02,
0XD2260000,0X30001B02,0X23104300,0X40001B02,0X47000000,0X00001B02,0X00001883,0X90081B02,
0X380A4000,0X1C001B02,0X32800002,0X1C001B02,0X33800000,0X1C001B02,0X31800400,0X1C001B02,
0X30802015,0X1C001B02,0X40800004,0X20001B02,0X00780000,0X18081B02,0X27020000,0X04001B02,
0X6D550200,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,
};

注意:

更新完成 imxdownload.h 文件中的寄存器值后,即以上的数组中的寄存器值后,需要重新编译 imxdownload 工程。最终生成 imxdownload工具。

在后续裸机篇开发中,使用这里新生成的 imxdownload 工具生成 load.imx程序(即添加了头部信息的程序)。

使用经过校验并超频测试后的 DDR寄存器值,运行的程序中 DDR初始化工作才是正确的!!!

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。