iTop4412|iTop4412 uboot-2019.2移植之内存控制器(七)
一、说明
内存控制器非常难配置,故而不能出错。我严格按照文档上的步骤配置,其中的参数自行体会。
二、配置流程
首先配置内存交错,然后初始化每个DMC。
223 void mem_ctrl_init(int reset)
224 {
225struct exynos4_dmc *dmc1 = (struct exynos4_dmc *)samsung_get_base_dmc_ctrl();
226struct exynos4_dmc *dmc2 = (struct exynos4_dmc *)(samsung_get_base_dmc_ctrl() + DMC_OFFSET);
227/**
228|* 配置内存交错
229|*/
230writel(APB_SFR_INTERLEAVE_CONF_VAL, &dmc1->ivcontrol);
231writel(APB_SFR_INTERLEAVE_CONF_VAL, &dmc2->ivcontrol);
232
233/*
234|* 初始化内存控制器
235|*/
236dmc_init(dmc1);
237dmc_init(dmc2);
238 }
配置步骤在代码中,对比手册阅读
static void dmc_init(struct exynos4_dmc *dmc)
{
/**
* Setup 2:
*enable PhyControl1.term_write_en, PhyControl1.term_read_en
*/
writel(mem.control1, &dmc->phycontrol1);
//有差异/**
* Stup 3:
*disable PhyZQControl.ctrl_zq_mode_noterm
*enable PhyZQControl.ctrl_zq_start
*/
writel(mem.zqcontrol, &dmc->phyzqcontrol);
/**
* Setup 4:
*set PhyControl0.ctrl_start_point, PhyControl0.ctrl_inc
*set PhyControl0.ctrl_dll_on to 1 ——activate PHY DLL
*/
phy_control_reset(0, dmc);
/**
* Setup 5:
*set PhyControl1.ctr_shiftc, PhyControl1.ctrl_offsetc
*/
writel(mem.control1, &dmc->phycontrol1);
/**
* Setup 6:
*set PhyControl0.ctrl_start to 1
*/
writel((mem.control0 | CTRL_START | CTRL_DLL_ON), &dmc->phycontrol0);
/**
* Setup 7:
*set ConControl, close auto refresh
*/
writel(mem.concontrol, &dmc->concontrol);
/**
* Setup 8:
*set MemControl, close power down modes, close pzq_en
*/
writel(mem.memcontrol, &dmc->memcontrol);
//差异/**
* Setup 9:
*set Memory info
*/
writel(mem.memconfig0, &dmc->memconfig0);
writel(mem.memconfig1, &dmc->memconfig1);
/**
* Setup 10:
*set PrechConfig
*/
writel(mem.prechconfig, &dmc->prechconfig);
/**
* Setup 11:
*set TimingAref, TimingRow, TimingData and TimingPower
*/
writel(mem.timingref, &dmc->timingref);
writel(mem.timingrow, &dmc->timingrow);
writel(mem.timingdata, &dmc->timingdata);
writel(mem.timingpower, &dmc->timingpower);
/**
* Setup 13:
*wait PhyStatus0.ctrl_clock and PhyStatus0.ctrl_flock to 1
*/while(!(dmc->phystatus & 2));
/**
* Setup 15,16:
*set PhyContron1.fp_resync to 1
*/
phy_control_reset(1, dmc);
/**
* Setup 19:
*NOP command
*hold CKE to logic high level
*chip 0
*/
writel(DIRECT_CMD_NOP, &dmc->directcmd);
/**
* Setup 21:
*send EMRS2 command
*send EMRS3 command
*send EMRS command
*send MRS command
*chip 0
*/
dmc_config_mrs(dmc, 0);
/**
*Setup 26:
send ZQINIT command
chip 0
*/
writel(DIRECT_CMD_ZQ, &dmc->directcmd);
/**
* Setup 19:
*NOP command
*hold CKE to logic high level
*chip 1
*/
writel((DIRECT_CMD_NOP | DIRECT_CMD_CHIP1_SHIFT), &dmc->directcmd);
/**
* Setup 21:
*send EMRS2 command
*send EMRS3 command
*send EMRS command
*send MRS command
*chip 1
*/
dmc_config_mrs(dmc, 1);
/**
*Setup 26:
send ZQINIT command
chip 1
*/
writel((DIRECT_CMD_ZQ | DIRECT_CMD_CHIP1_SHIFT), &dmc->directcmd);
/**
* Setup 28:
*set ConControl auto refresh
*/
writel((mem.concontrol | AREF_EN), &dmc->concontrol);
/**
* Setup 29:
*set MemControl
*/
writel((mem.memcontrol | MEMCONTROL_OR), &dmc->memcontrol);
}
三、配置参数
/********************************************************************************
*
* 内存控制器的配置
*
********************************************************************************//* DMC */
#define DIRECT_CMD_CHIP1_SHIFT(1 << 20)
#define MEM_TIMINGS_MSR_COUNT4
#define CTRL_START(1 << 0)
#define CTRL_DLL_ON (1 << 1)
#define AREF_EN(1 << 5)
#define DRV_TYPE(1 << 6)struct mem_timings {
unsigned direct_cmd_msr[MEM_TIMINGS_MSR_COUNT];
unsigned timingref;
unsigned timingrow;
unsigned timingdata;
unsigned timingpower;
unsigned zqcontrol;
unsigned control0;
unsigned control1;
unsigned control2;
unsigned concontrol;
unsigned prechconfig;
unsigned memcontrol;
unsigned memconfig0;
unsigned memconfig1;
unsigned dll_resync;
unsigned dll_on;
};
/* MIU */
/* MIU Config Register Offsets*/#ifdef CONFIG_ITOP4412
#define APB_SFR_INTERLEAVE_CONF_VAL0x80000007
#endif#ifdef CONFIG_MIU_1BIT_INTERLEAVED
#define APB_SFR_INTERLEAVE_CONF_VAL 0x0000000c
#endif#ifdef CONFIG_MIU_2BIT_INTERLEAVED
#define APB_SFR_INTERLEAVE_CONF_VAL 0x2000150c
#endif#define FORCE_DLL_RESYNC3
#define DLL_CONTROL_ON1#define DIRECT_CMD_NOP0x07000000
#define DIRECT_CMD10x00020000
#define DIRECT_CMD20x00030000
#define DIRECT_CMD30x00010002
#define DIRECT_CMD40x00000328
#define DIRECT_CMD_ZQ0x0a000000#define CTRL_ZQ_MODE_NOTERM (0x1 << 0)
#define CTRL_ZQ_START(0x1 << 1)
#define CTRL_ZQ_DIV(0x0 << 4)
#define CTRL_ZQ_MODE_DDS(0x7 << 8)
#define CTRL_ZQ_MODE_TERM(0x2 << 11)
#define CTRL_ZQ_FORCE_IMPN(0x5 << 14)
#define CTRL_ZQ_FORCE_IMPP(0x6 << 17)
#define CTRL_DCC(0xE38 << 20)
#define ZQ_CONTROL_VAL(CTRL_ZQ_MODE_NOTERM | CTRL_ZQ_START\
| CTRL_ZQ_DIV | CTRL_ZQ_MODE_DDS\
| CTRL_ZQ_MODE_TERM | CTRL_ZQ_FORCE_IMPN\
| CTRL_ZQ_FORCE_IMPP | CTRL_DCC)#define ASYNC(0 << 0)
#define CLK_RATIO(1 << 1)
#define DIV_PIPE(1 << 3)
#define AWR_ON(1 << 4)
#define AREF_DISABLE(0 << 5)
#define DRV_TYPE_DISABLE(0 << 6)
#define CHIP0_NOT_EMPTY(0 << 8)
#define CHIP1_NOT_EMPTY(0 << 9)
#define DQ_SWAP_DISABLE(0 << 10)
#define QOS_FAST_DISABLE(0 << 11)
#define RD_FETCH(0x3 << 12)
#define TIMEOUT_LEVEL0(0xFFF << 16)
#define CONCONTROL_VAL(ASYNC | CLK_RATIO | DIV_PIPE | AWR_ON\
| AREF_DISABLE | DRV_TYPE_DISABLE\
| CHIP0_NOT_EMPTY | CHIP1_NOT_EMPTY\
| DQ_SWAP_DISABLE | QOS_FAST_DISABLE\
| RD_FETCH | TIMEOUT_LEVEL0)#define MEMCONTROL_OR(1 | 2 | (1 << 4) | (1 << 24))
#define CLK_STOP_DISABLE(0 << 1)
#define DPWRDN_DISABLE(0 << 2)
#define DPWRDN_TYPE(0 << 3)
#define TP_DISABLE(0 << 4)
#define DSREF_DIABLE(0 << 5)
#define ADD_LAT_PALL(1 << 6)
#define MEM_TYPE_DDR3(6 << 8)
#define MEM_WIDTH_32(2 << 12)
#define NUM_CHIP_2(1 << 16)
#define BL_8(3 << 20)
#define MEMCONTROL_VAL(CLK_STOP_DISABLE | DPWRDN_DISABLE\
| DPWRDN_TYPE | TP_DISABLE | DSREF_DIABLE\
| ADD_LAT_PALL | MEM_TYPE_DDR3 | MEM_WIDTH_32\
| NUM_CHIP_2 | BL_8)#define CHIP_BANK_8(0x3 << 0)
#define CHIP_COL_10(0x3 << 8)
#define CHIP_MAP_INTERLEAVED(0x1 << 12)#ifdef CONFIG_MIU_LINEAR
#define CHIP_ROW(0x2 << 4)
#define CHIP0_BASE(0x40 << 24)
#define CHIP1_BASE(0x60 << 24)
#define CHIP_MASK(0xe0 << 16)
#else
#define CHIP_ROW(0x3 << 4)
#define CHIP0_BASE(0x40 << 24)
#define CHIP1_BASE(0x80 << 24)
#define CHIP_MASK(0x80 << 16)
#endif#define MEMCONFIG0_VAL(CHIP_BANK_8 | CHIP_ROW | CHIP_COL_10\
| CHIP_MAP_INTERLEAVED | CHIP_MASK | CHIP0_BASE)
#define MEMCONFIG1_VAL(CHIP_BANK_8 | CHIP_ROW | CHIP_COL_10\
| CHIP_MAP_INTERLEAVED | CHIP_MASK | CHIP1_BASE)#define TP_CNT(0x64 << 24)
#define PRECHCONFIGTP_CNT#define CTRL_OFF(0 << 0)
#define CTRL_DLL_OFF(0 << 1)
#define CTRL_HALF(0 << 2)
#define CTRL_DFDQS(1 << 3)
#define DQS_DELAY(0 << 4)
#define CTRL_START_POINT(0x10 << 8)
#define CTRL_INC(0x10 << 16)
#define CTRL_FORCE(0x71 << 24)
#define CONTROL0_VAL(CTRL_OFF | CTRL_DLL_OFF | CTRL_HALF\
| CTRL_DFDQS | DQS_DELAY | CTRL_START_POINT\
| CTRL_INC | CTRL_FORCE)#define CTRL_SHIFTC(6 << 0)
#define CTRL_REF(8 << 4)
#define CTRL_SHGATE(1 << 29)
#define TERM_READ_EN(1 << 30)
#define TERM_WRITE_EN(1 << 31)
#define CONTROL1_VAL(CTRL_SHIFTC | CTRL_REF | CTRL_SHGATE\
| TERM_READ_EN | TERM_WRITE_EN)#define CONTROL2_VAL0x00000000#ifdef DRAM_CLK_200
#define TIMINGREF_VAL0x000000BB
#define TIMINGROW_VAL0x4046654f
#define TIMINGDATA_VAL0x46400506
#define TIMINGPOWER_VAL0x52000A3C
#endif#ifdef DRAM_CLK_330
#define TIMINGREF_VAL0x000000BC
#define TIMINGROW_VAL0x3545548d
#define TIMINGDATA_VAL0x45430506
#define TIMINGPOWER_VAL0x4439033c
#endif#ifdef DRAM_CLK_400
#define TIMINGREF_VAL0x000000BC
#define TIMINGROW_VAL0x45430506
#define TIMINGDATA_VAL0x56500506
#define TIMINGPOWER_VAL0x5444033d
#endif#endif
修改include/configs/itop4412.h,选择合适的时钟#define CONFIG_CLK_1000_200_200
四、验证结果 读写验证:在对应的内存区域随机选择内存地址,直接读写,看能否正常读写。
内存映射:在地址0x40000000处写入数据,在0x80000000读取数据,看其值是否一样。
内存间歇:在0x80000000附近读写内存,看内存是否连续。
【iTop4412|iTop4412 uboot-2019.2移植之内存控制器(七)】内存长度:在0xC0000000附近读写内存,看内存实际容量。
推荐阅读
- 三宝成功抢救大宝中国干细胞组,另一例脐血造血干细胞移植
- LUA|单片机脚本语言移植lua到stm32MDK
- linux移植过程出现“can't open /dev/tq2440_serial0: No such file or directory”
- PC/SC在android上的移植
- S905X|S905X 7.1 RTC_AM1805 移植 F&Q
- linux|【原创】ARM LINUX 外部RTC实时时钟驱动移植(RX8025)
- Felven在职场|Zynq-Linux移植学习笔记之44-linux下watchdog示例
- 不同平台下移植x264
- rk3128 平台rk818电源管理驱动移植
- 安卓5.1源码 lcd驱动移植