自己的板子是参考[fleescale][6]官方开发板[imx6qsabresd][6]的开发套件做的设计的,无奈修改的地方太多了本章主要来说ddr3 的移植,首先需要的工具和软件:
先详细阅读《飞思卡尔IMX6 平台DRAM 接口高阶应用指南 -DDR3 篇》,然后再根据自己具体使用的ddr3芯片,以及对比原理图(原理图主要看多少根地址线和数据线),然后再填写表格《MX6Q_SabreSD_DDR3_register_programming_aid_v0.10.xlsx》,如图:
填写好后会生成 [.inc][6]文件:
根据这个文件修改
mx6q-ddr.h
例如我根据生成的 inc文件
MX6Q_SabreSD_DDR3_32bit.inc
//=============================================================================
//init script for i.Mx6Q 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
setmem /32 0x020c4084 = 0xffffffff
//=============================================================================
// IOMUX
//=============================================================================
//DDR IO TYPE:
setmem /32 0x020e0798 = 0x000C0000 // IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE
setmem /32 0x020e0758 = 0x00000000 // IOMUXC_SW_PAD_CTL_GRP_DDRPKE
//CLOCK:
setmem /32 0x020e0588 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0
setmem /32 0x020e0594 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1
//ADDRESS:
setmem /32 0x020e056c = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS
setmem /32 0x020e0578 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS
setmem /32 0x020e074c = 0x00000030 // IOMUXC_SW_PAD_CTL_GRP_ADDDS
//Control:
setmem /32 0x020e057c = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET
setmem /32 0x020e058c = 0x00000000 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2 - DSE can be configured using Group Control Register: IOMUXC_SW_PAD_CTL_GRP_CTLDS
setmem /32 0x020e059c = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0
setmem /32 0x020e05a0 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1
setmem /32 0x020e078c = 0x00000030 // IOMUXC_SW_PAD_CTL_GRP_CTLDS
//Data Strobes:
setmem /32 0x020e0750 = 0x00020000 // IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL
setmem /32 0x020e05a8 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0
setmem /32 0x020e05b0 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1
setmem /32 0x020e0524 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2
setmem /32 0x020e051c = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3
//setmem /32 0x020e0518 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4
//setmem /32 0x020e050c = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5
//setmem /32 0x020e05b8 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6
//setmem /32 0x020e05c0 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7
//Data:
setmem /32 0x020e0774 = 0x00020000 // IOMUXC_SW_PAD_CTL_GRP_DDRMODE
setmem /32 0x020e0784 = 0x00000030 // IOMUXC_SW_PAD_CTL_GRP_B0DS
setmem /32 0x020e0788 = 0x00000030 // IOMUXC_SW_PAD_CTL_GRP_B1DS
setmem /32 0x020e0794 = 0x00000030 // IOMUXC_SW_PAD_CTL_GRP_B2DS
setmem /32 0x020e079c = 0x00000030 // IOMUXC_SW_PAD_CTL_GRP_B3DS
//setmem /32 0x020e07a0 = 0x00000030 // IOMUXC_SW_PAD_CTL_GRP_B4DS
//setmem /32 0x020e07a4 = 0x00000030 // IOMUXC_SW_PAD_CTL_GRP_B5DS
//setmem /32 0x020e07a8 = 0x00000030 // IOMUXC_SW_PAD_CTL_GRP_B6DS
//setmem /32 0x020e0748 = 0x00000030 // IOMUXC_SW_PAD_CTL_GRP_B7DS
setmem /32 0x020e05ac = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0
setmem /32 0x020e05b4 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1
setmem /32 0x020e0528 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2
setmem /32 0x020e0520 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3
//setmem /32 0x020e0514 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM4
//setmem /32 0x020e0510 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM5
//setmem /32 0x020e05bc = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM6
//setmem /32 0x020e05c4 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM7
//=============================================================================
// DDR Controller Registers
//=============================================================================
// Manufacturer: Micron
// Device Part Number: MT41K128M16JT-125
// Clock Freq.: 528MHz
// Density per CS in Gb: 4
// Chip Selects used: 1
// Number of Banks: 8
// Row address: 14
// Column address: 10
// Data bus width 32
//=============================================================================
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 = 0x0029002D
setmem /32 0x021b0810 = 0x00340028
//setmem /32 0x021b480c = 0x00000000
//setmem /32 0x021b4810 = 0x00000000
////Read DQS Gating calibration
setmem /32 0x021b083c = 0x0238023E // MPDGCTRL0 PHY0
setmem /32 0x021b0840 = 0x0238023C // MPDGCTRL1 PHY0
//setmem /32 0x021b483c = 0x00000000 // MPDGCTRL0 PHY1
//setmem /32 0x021b4840 = 0x00000000 // MPDGCTRL1 PHY1
//Read calibration
setmem /32 0x021b0848 = 0x342C3634 // MPRDDLCTL PHY0
//setmem /32 0x021b4848 = 0x40404040 // MPRDDLCTL PHY1
//Write calibration
setmem /32 0x021b0850 = 0x2A282A26 // MPWRDLCTL PHY0
//setmem /32 0x021b4850 = 0x40404040 // MPWRDLCTL PHY1
//read data bit delay: (3 is the reccommended default value, although out of reset value is 0)
setmem /32 0x021b081c = 0x33333333 // DDR_PHY_P0_MPREDQBY0DL3
setmem /32 0x021b0820 = 0x33333333 // DDR_PHY_P0_MPREDQBY1DL3
setmem /32 0x021b0824 = 0x33333333 // DDR_PHY_P0_MPREDQBY2DL3
setmem /32 0x021b0828 = 0x33333333 // DDR_PHY_P0_MPREDQBY3DL3
//setmem /32 0x021b481c = 0x33333333 // DDR_PHY_P1_MPREDQBY0DL3
//setmem /32 0x021b4820 = 0x33333333 // DDR_PHY_P1_MPREDQBY1DL3
//setmem /32 0x021b4824 = 0x33333333 // DDR_PHY_P1_MPREDQBY2DL3
//setmem /32 0x021b4828 = 0x33333333 // DDR_PHY_P1_MPREDQBY3DL3
//For i.mx6qd parts of versions A & B (v1.0, v1.1), uncomment the following lines. For version C (v1.2), keep commented
//setmem /32 0x021b08c0 = 0x24911492 // fine tune SDCLK duty cyc to low - seen to improve measured duty cycle of i.mx6
//setmem /32 0x021b48c0 = 0x24911492
// Complete calibration by forced measurement:
setmem /32 0x021b08b8 = 0x00000800 // DDR_PHY_P0_MPMUR0, frc_msr
//setmem /32 0x021b48b8 = 0x00000800 // DDR_PHY_P0_MPMUR0, frc_msr
//=============================================================================
// Calibration setup end
//=============================================================================
//MMDC init:
setmem /32 0x021b0004 = 0x00020036 // MMDC0_MDPDC
setmem /32 0x021b0008 = 0x09444040 // MMDC0_MDOTC
setmem /32 0x021b000c = 0x54597955 // MMDC0_MDCFG0
setmem /32 0x021b0010 = 0xFF328F64 // 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 = 0x00011740 // 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 = 0x00591023 // MMDC0_MDOR
setmem /32 0x021b0040 = 0x00000017 // Chan0 CS0_END
setmem /32 0x021b0000 = 0x83190000 // MMDC0_MDCTL
//Mode register writes
setmem /32 0x021b001c = 0x02088032 // 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 = 0x19408030 // MMDC0_MDSCR, MR0write, CS0
setmem /32 0x021b001c = 0x04008040 // MMDC0_MDSCR, ZQ calibration command sent to device on CS0
//setmem /32 0x021b001c = 0x0208803A // 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 = 0x19408038 // 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 = 0x00022227 // DDR_PHY_P0_MPODTCTRL
//setmem /32 0x021b4818 = 0x00022227 // DDR_PHY_P1_MPODTCTRL
setmem /32 0x021b0004 = 0x00025576 // 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)
修改uboot中 arch/arm/include/asm/arch-mx6/mx6q-ddr.h
/*
* Copyright (C) 2013 Boundary Devices Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __ASM_ARCH_MX6Q_DDR_H__
#define __ASM_ARCH_MX6Q_DDR_H__
#ifndef CONFIG_MX6Q
#error "wrong CPU"
#endif
#define MX6_IOM_DRAM_DQM0 0x020e05ac
#define MX6_IOM_DRAM_DQM1 0x020e05b4
#define MX6_IOM_DRAM_DQM2 0x020e0528
#define MX6_IOM_DRAM_DQM3 0x020e0520
//#define MX6_IOM_DRAM_DQM4 0x020e0514
//#define MX6_IOM_DRAM_DQM5 0x020e0510
//#define MX6_IOM_DRAM_DQM6 0x020e05bc
//#define MX6_IOM_DRAM_DQM7 0x020e05c4
#define MX6_IOM_DRAM_CAS 0x020e056c
#define MX6_IOM_DRAM_RAS 0x020e0578
#define MX6_IOM_DRAM_RESET 0x020e057c
#define MX6_IOM_DRAM_SDCLK_0 0x020e0588
#define MX6_IOM_DRAM_SDCLK_1 0x020e0594
#define MX6_IOM_DRAM_SDBA2 0x020e058c
#define MX6_IOM_DRAM_SDCKE0 0x020e0590
#define MX6_IOM_DRAM_SDCKE1 0x020e0598
#define MX6_IOM_DRAM_SDODT0 0x020e059c
#define MX6_IOM_DRAM_SDODT1 0x020e05a0
#define MX6_IOM_DRAM_SDQS0 0x020e05a8
#define MX6_IOM_DRAM_SDQS1 0x020e05b0
#define MX6_IOM_DRAM_SDQS2 0x020e0524
#define MX6_IOM_DRAM_SDQS3 0x020e051c
//#define MX6_IOM_DRAM_SDQS4 0x020e0518
//#define MX6_IOM_DRAM_SDQS5 0x020e050c
//#define MX6_IOM_DRAM_SDQS6 0x020e05b8
//#define MX6_IOM_DRAM_SDQS7 0x020e05c0
#define MX6_IOM_GRP_B0DS 0x020e0784
#define MX6_IOM_GRP_B1DS 0x020e0788
#define MX6_IOM_GRP_B2DS 0x020e0794
#define MX6_IOM_GRP_B3DS 0x020e079c
//#define MX6_IOM_GRP_B4DS 0x020e07a0
//#define MX6_IOM_GRP_B5DS 0x020e07a4
//#define MX6_IOM_GRP_B6DS 0x020e07a8
//#define MX6_IOM_GRP_B7DS 0x020e0748
#define MX6_IOM_GRP_ADDDS 0x020e074c
#define MX6_IOM_DDRMODE_CTL 0x020e0750
#define MX6_IOM_GRP_DDRPKE 0x020e0758
#define MX6_IOM_GRP_DDRMODE 0x020e0774
#define MX6_IOM_GRP_CTLDS 0x020e078c
#define MX6_IOM_GRP_DDR_TYPE 0x020e0798
#endif /*__ASM_ARCH_MX6Q_DDR_H__ */
接下来需要用到imx6 的板子来微调了
windows 下打开
ddr_stress_tester_v2.52 应用程序,选择上面生成的[.inc][6]文件,开发板进入串行下载模式,可在设备管理器中看待HID设备,点击下载 然后 微调,
Write leveling calibration
MMDC_MPWLDECTRL0 ch0 (0x021b080c) = 0x00250027
MMDC_MPWLDECTRL1 ch0 (0x021b0810) = 0x00450034
Read DQS Gating calibration
MPDGCTRL0 PHY0 (0x021b083c) = 0x032E0334
MPDGCTRL1 PHY0 (0x021b0840) = 0x03320336
Read calibration
MPRDDLCTL PHY0 (0x021b0848) = 0x3A2A302C
Write calibration
MPWRDLCTL PHY0 (0x021b0850) = 0x2A28302E
这里得到的这几个寄存器的值就是我们需要的,根据这几个值修改:
uboot中[.cfg][6]文件,例如:
/board/freescale/mx6sabresd/xxxxx.cfg
/*
* Copyright (C) 2015 FEDEVEL
*
* SPDX-License-Identifier: GPL-2.0+
*
* Refer docs/README.imxmage for more details about how-to configure
* and create imximage boot image
*
* The syntax is taken as close as possible with the kwbimage
*/
/* image version */
IMAGE_VERSION 2
/*
* Boot Device : one of
* spi, sd (the board has no nand neither onenand)
*/
BOOT_FROM sd
/*
//=============================================================================
// DDR Controller Registers
//=============================================================================
// Manufacturer: Micron
// Device Part Number: MT41K256M16HA-125
// Clock Freq.: 528MHz
// Density per CS in Gb: 8
// Chip Selects used: 1
// Number of Banks: 8
// Row address: 15
// Column address: 10
// Data bus width 32
//=============================================================================
*/
/*
* Device Configuration Data (DCD)
*
* Each entry must have the format:
* Addr-type Address Value
*
* where:
* Addr-type register length (1,2 or 4 bytes)
* Address absolute address of the register
* value value to be stored in the register
*/
DATA 4 0x020e0798 0x000C0000
DATA 4 0x020e0758 0x00000000
DATA 4 0x020e0588 0x00000028
DATA 4 0x020e0594 0x00000028
DATA 4 0x020e056c 0x00000028
DATA 4 0x020e0578 0x00000028
DATA 4 0x020e074c 0x00000028
DATA 4 0x020e057c 0x00000028
DATA 4 0x020e058c 0x00000000
DATA 4 0x020e059c 0x00000028
DATA 4 0x020e05a0 0x00000028
DATA 4 0x020e078c 0x00000028
DATA 4 0x020e0750 0x00020000
DATA 4 0x020e05a8 0x00000028
DATA 4 0x020e05b0 0x00000028
DATA 4 0x020e0524 0x00000028
DATA 4 0x020e051c 0x00000028
DATA 4 0x020e0774 0x00020000 /**/
DATA 4 0x020e0784 0x00000028
DATA 4 0x020e0788 0x00000028
DATA 4 0x020e0794 0x00000028
DATA 4 0x020e079c 0x00000028
DATA 4 0x020e05ac 0x00000028 /**/
DATA 4 0x020e05b4 0x00000028
DATA 4 0x020e0528 0x00000028
DATA 4 0x020e0520 0x00000028
DATA 4 0x021b001c 0x00008000 /**/
DATA 4 0x021b0800 0xA1390003
DATA 4 0x021b080c 0x00250027
DATA 4 0x021b0810 0x00450034
DATA 4 0x021b083c 0x032E0334
DATA 4 0x021b0840 0x03320336
DATA 4 0x021b0848 0x3A2A302C
DATA 4 0x021b0850 0x2A28302E
DATA 4 0x021b081c 0x33333333
DATA 4 0x021b0820 0x33333333
DATA 4 0x021b0824 0x33333333
DATA 4 0x021b0828 0x33333333
DATA 4 0x021b08b8 0x00000800
DATA 4 0x021b0004 0x00020036
DATA 4 0x021b0008 0x09444040
DATA 4 0x021b000c 0x898E7955
DATA 4 0x021b0010 0xFF328F64
DATA 4 0x021b0014 0x01FF00DB
DATA 4 0x021b0018 0x00011740
DATA 4 0x021b001c 0x00008000
DATA 4 0x021b002c 0x000026D2
DATA 4 0x021b0030 0x008E1023
DATA 4 0x021b0040 0x00000027
DATA 4 0x021b0000 0x84190000
DATA 4 0x021b001c 0x02088032
DATA 4 0x021b001c 0x00008033
DATA 4 0x021b001c 0x00048031
DATA 4 0x021b001c 0x09408030
DATA 4 0x021b001c 0x04008040
DATA 4 0x021b0020 0x00007800
DATA 4 0x021b0818 0x00022227
DATA 4 0x021b0004 0x00025576
DATA 4 0x021b0404 0x00011006
DATA 4 0x021b001c 0x00000000
/* set the default clock gate to save power */
DATA 4 0x020c4068 0x00C03F3F
DATA 4 0x020c406c 0x0030FC03
DATA 4 0x020c4070 0x0FFFC000
DATA 4 0x020c4074 0x3FF00000
DATA 4 0x020c4078 0x00FFF300
DATA 4 0x020c407c 0x0F0000C3
DATA 4 0x020c4080 0x000003FF
/* enable AXI cache for VDOA/VPU/IPU */
DATA 4 0x020e0010 0xF00000CF
/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
DATA 4 0x020e0018 0x007F007F
DATA 4 0x020e001c 0x007F007F
当然最后还需要重新编译下uboot,然后烧到板子上,启动:
U-Boot 2015.04-14468-gd7d7c43-dirty (Jun 24 2016 - 09:55:12)
CPU: Freescale i.MX6Q rev1.5 at 792 MHz
CPU: Temperature 40 C
Reset cause: POR
Board: MX6Q-Sabreauto revA
I2C: ready
DRAM: 1 GiB
PMIC: PFUZE100 ID=0x10
MMC: FSL_SDHC: 0
SF: Detected M25P32 with page size 256 Bytes, erase size 64 KiB, total 4 MiB
In: serial
Out: serial
Err: serial
Net: FEC [PRIME]
Boot from USB for mfgtools
Use default environment for mfgtools
Run bootcmd_mfg: run mfgtool_args;bootz loadaddr {initrd_addr} ${fdt_addr};
Hit any key to stop autoboot: 0
=>