【TINY4412】U-BOOT移植笔记:(7)SDRAM驱动
2018-01-12 17:11
337 查看
【TINY4412】U-BOOT移植笔记:(7)SDRAM驱动
宿主机 : 虚拟机 Ubuntu 16.04 LTS / X64目标板[底板]: Tiny4412SDK - 1506
目标板[核心板]: Tiny4412 - 1412
U-BOOT版本: 2017.03
交叉编译器: gcc-arm-none-eabi-5_4-2016q3
日期: 2017-4-23 23:36:06
作者: SY
背景介绍
DDR SDRAM全名叫做:双倍数据率同步动态随机存取存储器SDRAM在一个时钟周期内只传输一次数据,它是在时钟的上升期进行数据传输
DDR SDRAM则是一个时钟周期内传输两次数据,它能够在时钟的上升期和下降期各传输一次数据
DDR SDRAM芯片的时钟频率一般为DMC控制芯片频率的2倍
开发板SDRAM
内存芯片:2片512MB的三星1600Mb/sec/pin内存颗粒,总内存大小为1GB型号:K4B4G1646D-BCK0
手册:K4B4G1646D-BCK0.pdf
自动刷新周期:Average Refresh Period 7.8us at lower than TCASE 85C, 3.9us at 85C < TCASE < 95 C
外部时钟[主芯片提供给内存颗粒的时钟]:800MHz,主芯片需要提供给内存颗粒2个差分的
时钟信号,CK、CK/,详见内存芯片手册P27
内部时钟[DMC时钟]:400MHz
自动刷新周期TIMINGAREF:24MHz * 7.8us(查看内存手册) = 187.2 = 0xBB
TIMINGROW:查看内存手册可知,
参数 | 数值 |
---|---|
t_ras | 35 |
t_rc | 48.75 |
t_rcd | 13.75 |
t_rp | 13.75 |
t_rrd | 6 |
t_rfc | 208 |
代码移植
修改文件:arch/arm/mach-exynos/exynos4412_setup.h root@ubuntu:/opt/u-boot-2017.03# git diff ../temp/ u-boot-2017.03/arch/arm/mach-exynos/exynos4_setup.h arch/arm/mach-exynos/exynos4412_setup.h diff --git a/../temp/u-boot-2017.03/arch/arm/mach-exynos/ exynos4_setup.h b/arch/arm/mach-exynos/exynos4412_setup.h index 9f29d94..3befa95 100644 --- a/../temp/u-boot-2017.03/arch/arm/mach-exynos/exynos4_setup.h +++ b/arch/arm/mach-exynos/exynos4412_setup.h @@ -6,8 +6,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#ifndef _ORIGEN_SETUP_H -#define _ORIGEN_SETUP_H +#ifndef _EXYNOS4412_SETUP_H +#define _EXYNOS4412_SETUP_H #include <config.h> #include <asm/arch/cpu.h> @@ -434,7 +434,7 @@ struct mem_timings { #define ABP_SFR_SLV1_SINGLE_ADDRMAP_START_OFFSET 0x828 #define ABP_SFR_SLV1_SINGLE_ADDRMAP_END_OFFSET 0x830 -#ifdef CONFIG_ORIGEN +#ifdef CONFIG_TINY4412 /* Interleave: 2Bit, Interleave_bit1: 0x15, Interleave_bit0: 0x7 */ #define APB_SFR_INTERLEAVE_CONF_VAL 0x20001507 #define APB_SFR_ARBRITATION_CONF_VAL 0x00000001 @@ -470,10 +470,10 @@ struct mem_timings { #define CTRL_ZQ_MODE_NOTERM (0x1 << 0) #define CTRL_ZQ_START (0x1 << 1) #define CTRL_ZQ_DIV (0 << 4) -#define CTRL_ZQ_MODE_DDS (0x7 << 8) -#define CTRL_ZQ_MODE_TERM (0x2 << 11) +#define CTRL_ZQ_MODE_DDS (0x4 << 8) +#define CTRL_ZQ_MODE_TERM (0x1 << 11) #define CTRL_ZQ_FORCE_IMPN (0x5 << 14) -#define CTRL_ZQ_FORCE_IMPP (0x6 << 17) +#define CTRL_ZQ_FORCE_IMPP (0x2 << 17) #define CTRL_DCC (0xE38 << 20) #define ZQ_CONTROL_VAL (CTRL_ZQ_MODE_NOTERM | CTRL_ZQ_START\ | CTRL_ZQ_DIV | CTRL_ZQ_MODE_DDS\ @@ -506,7 +506,7 @@ struct mem_timings { #define ADD_LAT_PALL (1 << 6) #define MEM_TYPE_DDR3 (0x6 << 8) #define MEM_WIDTH_32 (0x2 << 12) -#define NUM_CHIP_2 (1 << 16) +#define NUM_CHIP_2 (0 << 16) #define BL_8 (0x3 << 20) #define MEMCONTROL_VAL (CLK_STOP_DISABLE | DPWRDN_DISABLE\ | DPWRDN_TYPE | TP_DISABLE | DSREF_DIABLE\ @@ -515,20 +515,20 @@ struct mem_timings { #define CHIP_BANK_8 (0x3 << 0) -#define CHIP_ROW_14 (0x2 << 4) +#define CHIP_ROW_15 (0x3 << 4) #define CHIP_COL_10 (0x3 << 8) #define CHIP_MAP_INTERLEAVED (1 << 12) -#define CHIP_MASK (0xe0 << 16) +#define CHIP_MASK (0xC0 << 16) #ifdef CONFIG_MIU_LINEAR #define CHIP0_BASE (0x40 << 24) #define CHIP1_B 4000 ASE (0x60 << 24) #else -#define CHIP0_BASE (0x20 << 24) -#define CHIP1_BASE (0x40 << 24) +#define CHIP0_BASE (0x40 << 24) +#define CHIP1_BASE (0x80 << 24) #endif -#define MEMCONFIG0_VAL (CHIP_BANK_8 | CHIP_ROW_14 | CHIP_COL_10\ +#define MEMCONFIG0_VAL (CHIP_BANK_8 | CHIP_ROW_15 | CHIP_COL_10\ | CHIP_MAP_INTERLEAVED | CHIP_MASK | CHIP0_BASE) -#define MEMCONFIG1_VAL (CHIP_BANK_8 | CHIP_ROW_14 | CHIP_COL_10\ +#define MEMCONFIG1_VAL (CHIP_BANK_8 | CHIP_ROW_15 | CHIP_COL_10\ | CHIP_MAP_INTERLEAVED | CHIP_MASK | CHIP1_BASE) #define TP_CNT (0xff << 24) @@ -556,11 +556,11 @@ struct mem_timings { #define CONTROL2_VAL 0x00000000 -#ifdef CONFIG_ORIGEN -#define TIMINGREF_VAL 0x000000BB -#define TIMINGROW_VAL 0x4046654f -#define TIMINGDATA_VAL 0x46400506 -#define TIMINGPOWER_VAL 0x52000A3C +#ifdef CONFIG_TINY4412 + #define TIMINGREF_VAL 0x000000BB + #define TIMINGROW_VAL 0x6946654f + #define TIMINGDATA_VAL 0x46460506 + #define TIMINGPOWER_VAL 0x5200183c #else #define TIMINGREF_VAL 0x000000BC #ifdef DRAM_CLK_330 (END) 修改文件:/arch/arm/mach-exynos/dmc_init_exynos4412.c root@ubuntu:/opt/u-boot-2017.03# git diff ../temp/u- boot-2017.03/arch/arm/mach-exynos/dmc_init_exynos4.c arch/arm/mach-exynos/dmc_init_exynos4412.c diff --git a/../temp/u-boot-2017.03/arch/arm/mach-exynos/ dmc_init_exynos4.c b/arch/arm/mach-exynos/dmc_init_exynos4412.c index ecddc72..938348a 100644 --- a/../temp/u-boot-2017.03/arch/arm/mach-exynos/dmc_init_exynos4.c +++ b/arch/arm/mach-exynos/dmc_init_exynos4412.c @@ -1,5 +1,5 @@ /* - * Memory setup for board based on EXYNOS4210 + * Memory setup for board based on EXYNOS4412 * * Copyright (C) 2013 Samsung Electronics * Rajeshwari Shinde <rajeshwari.s@samsung.com> @@ -26,7 +26,8 @@ #include <config.h> #include <asm/arch/dmc.h> #include "common_setup.h" -#include "exynos4_setup.h" +#include <debug_uart.h> +#include "exynos4412_setup.h" struct mem_timings mem = { .direct_cmd_msr = { @@ -124,6 +125,10 @@ static void dmc_init(struct exynos4_dmc *dmc) writel(mem.memconfig0, &dmc->memconfig0); writel(mem.memconfig1, &dmc->memconfig1); +#ifdef CONFIG_TINY4412 + writel(0x8000001f, &dmc->ivcontrol); +#endif + /* Config Precharge Policy */ writel(mem.prechconfig, &dmc->prechconfig); /* @@ -175,39 +180,106 @@ void mem_ctrl_init(int reset) * 0: full_sync */ writel(1, ASYNC_CONFIG); -#ifdef CONFIG_ORIGEN - /* Interleave: 2Bit, Interleave_bit1: 0x15, Interleave_bit0: 0x7 */ - writel(APB_SFR_INTERLEAVE_CONF_VAL, EXYNOS4_MIU_BASE + - APB_SFR_INTERLEAVE_CONF_OFFSET); - /* Update MIU Configuration */ - writel(APB_SFR_ARBRITATION_CONF_VAL, EXYNOS4_MIU_BASE + - APB_SFR_ARBRITATION_CONF_OFFSET); -#else - writel(APB_SFR_INTERLEAVE_CONF_VAL, EXYNOS4_MIU_BASE + - APB_SFR_INTERLEAVE_CONF_OFFSET); - writel(INTERLEAVE_ADDR_MAP_START_ADDR, EXYNOS4_MIU_BASE + - ABP_SFR_INTERLEAVE_ADDRMAP_START_OFFSET); - writel(INTERLEAVE_ADDR_MAP_END_ADDR, EXYNOS4_MIU_BASE + - ABP_SFR_INTERLEAVE_ADDRMAP_END_OFFSET); - writel(INTERLEAVE_ADDR_MAP_EN, EXYNOS4_MIU_BASE + - ABP_SFR_SLV_ADDRMAP_CONF_OFFSET); -#ifdef CONFIG_MIU_LINEAR - writel(SLAVE0_SINGLE_ADDR_MAP_START_ADDR, EXYNOS4_MIU_BASE + - ABP_SFR_SLV0_SINGLE_ADDRMAP_START_OFFSET); - writel(SLAVE0_SINGLE_ADDR_MAP_END_ADDR, EXYNOS4_MIU_BASE + - ABP_SFR_SLV0_SINGLE_ADDRMAP_END_OFFSET); - writel(SLAVE1_SINGLE_ADDR_MAP_START_ADDR, EXYNOS4_MIU_BASE + - ABP_SFR_SLV1_SINGLE_ADDRMAP_START_OFFSET); - writel(SLAVE1_SINGLE_ADDR_MAP_END_ADDR, EXYNOS4_MIU_BASE + - ABP_SFR_SLV1_SINGLE_ADDRMAP_END_OFFSET); - writel(APB_SFR_SLV_ADDR_MAP_CONF_VAL, EXYNOS4_MIU_BASE + - ABP_SFR_SLV_ADDRMAP_CONF_OFFSET); -#endif + +#ifndef CONFIG_TINY4412 + #ifdef CONFIG_ORIGEN + /* Interleave: 2Bit, Interleave_bit1: 0x15, Interleave_bit0: 0x7 */ + writel(APB_SFR_INTERLEAVE_CONF_VAL, EXYNOS4_MIU_BASE + + APB_SFR_INTERLEAVE_CONF_OFFSET); + /* Update MIU Configuration */ + writel(APB_SFR_ARBRITATION_CONF_VAL, EXYNOS4_MIU_BASE + + APB_SFR_ARBRITATION_CONF_OFFSET); + #else + writel(APB_SFR_INTERLEAVE_CONF_VAL, EXYNOS4_MIU_BASE + + APB_SFR_INTERLEAVE_CONF_OFFSET); + writel(INTERLEAVE_ADDR_MAP_START_ADDR, EXYNOS4_MIU_BASE + + ABP_SFR_INTERLEAVE_ADDRMAP_START_OFFSET); + writel(INTERLEAVE_ADDR_MAP_END_ADDR, EXYNOS4_MIU_BASE + + ABP_SFR_INTERLEAVE_ADDRMAP_END_OFFSET); + writel(INTERLEAVE_ADDR_MAP_EN, EXYNOS4_MIU_BASE + + ABP_SFR_SLV_ADDRMAP_CONF_OFFSET); + #ifdef CONFIG_MIU_LINEAR + writel(SLAVE0_SINGLE_ADDR_MAP_START_ADDR, EXYNOS4_MIU_BASE + + ABP_SFR_SLV0_SINGLE_ADDRMAP_START_OFFSET); + writel(SLAVE0_SINGLE_ADDR_MAP_END_ADDR, EXYNOS4_MIU_BASE + + ABP_SFR_SLV0_SINGLE_ADDRMAP_END_OFFSET); + writel(SLAVE1_SINGLE_ADDR_MAP_START_ADDR, EXYNOS4_MIU_BASE + + ABP_SFR_SLV1_SINGLE_ADDRMAP_START_OFFSET); + writel(SLAVE1_SINGLE_ADDR_MAP_END_ADDR, EXYNOS4_MIU_BASE + + ABP_SFR_SLV1_SINGLE_ADDRMAP_END_OFFSET); + writel(APB_SFR_SLV_ADDR_MAP_CONF_VAL, EXYNOS4_MIU_BASE + + ABP_SFR_SLV_ADDRMAP_CONF_OFFSET); + #endif + #endif #endif - /* DREX0 */ + + printascii("[SPL] DDR3 SDRAM配置:\n"); + printascii("timingref "); printhex8(mem.timingref); printascii("\n"); + printascii("timingrow "); printhex8(mem.timingrow); printascii("\n"); + printascii("timingdata "); printhex8(mem.timingdata); printascii("\n"); + printascii("timingpower "); printhex8(mem.timingpower); printascii("\n"); + printascii("zqcontrol "); printhex8(mem.zqcontrol); printascii("\n"); + printascii("control0 "); printhex8(mem.control0); printascii("\n"); + printascii("control1 "); printhex8(mem.control1); printascii("\n"); + printascii("control2 "); printhex8(mem.control2); printascii("\n"); + printascii("concontrol "); printhex8(mem.concontrol); printascii("\n"); + printascii("prechconfig "); printhex8(mem.prechconfig); printascii("\n"); + printascii("memcontrol "); printhex8(mem.memcontrol); printascii("\n"); + printascii("memconfig0 "); printhex8(mem.memconfig0); printascii("\n"); + printascii("memconfig1 "); printhex8(mem.memconfig1); printascii("\n"); + printascii("dll_resync "); printhex8(mem.dll_resync); printascii("\n"); + printascii("dll_on "); printhex8(mem.dll_on); printascii("\n"); + + /* DMC0 */ dmc = (struct exynos4_dmc *)samsung_get_base_dmc_ctrl(); dmc_init(dmc); + + /* DMC1 */ dmc = (struct exynos4_dmc *)(samsung_get_base_dmc_ctrl() + DMC_OFFSET); dmc_init(dmc); + +{ + printascii("[SPL] DDR3 SDRAM测试:\n"); + + void Test_SDRAM(unsigned long addr, unsigned long value); + Test_SDRAM(0x40000000, 0x12121212); + Test_SDRAM(0x40000004, 0x12121213); + Test_SDRAM(0x40000008, 0x12121214); + Test_SDRAM(0x4000000C, 0x12121215); + Test_SDRAM(0x40000010, 0x12121216); + + Test_SDRAM(0x41000000, 0x23232325); + Test_SDRAM(0x42000000, 0x23232326); + + Test_SDRAM(0x42345530, 0x23232323); + Test_SDRAM(0x42345534, 0x23232324); + Test_SDRAM(0x42345538, 0x23232325); + Test_SDRAM(0x4234553C, 0x23232326); + Test_SDRAM(0x50000000, 0x34343434); + Test_SDRAM(0x58494940, 0x45454545); + Test_SDRAM(0x60000008, 0x56565656); + Test_SDRAM(0x6FFFFFFC, 0x67676767); + Test_SDRAM(0x70000000, 0x78787878); + Test_SDRAM(0x7FFFFFFC, 0x89898989); + + printascii("测试结束\n"); +} } + +void Test_SDRAM(unsigned long addr, unsigned long value) +{ + + printascii("写入地址 = "); + printhex8(addr); + + printascii(" 写入值 = "); + printhex8(value); + writel(value, addr); + + printascii(" 读取值 = "); + printhex8(readl(addr)); + printascii("\n"); +} + + (END)
测试结果: [SPL] DDR3 SDRAM配置: timingref 000000bb timingrow 6946654f timingdata 46460506 timingpower 5200183c zqcontrol e3854c03 control0 71101008 control1 e0000086 control2 00000000 concontrol 0fff301a prechconfig ff000000 memcontrol 00302640 memconfig0 40c01333 memconfig1 80c01333 dll_resync 00000003 dll_on 00000001 [SPL] DDR3 SDRAM测试: 写入地址 = 40000000 写入值 = 12121212 读取值 = 12121212 写入地址 = 40000004 写入值 = 12121213 读取值 = 12121213 写入地址 = 40000008 写入值 = 12121214 读取值 = 12121214 写入地址 = 4000000c 写入值 = 12121215 读取值 = 12121215 写入地址 = 40000010 写入值 = 12121216 读取值 = 12121216 写入地址 = 41000000 写入值 = 23232325 读取值 = 23232325 写入地址 = 42000000 写入值 = 23232326 读取值 = 23232326 写入地址 = 42345530 写入值 = 23232323 读取值 = 23232323 写入地址 = 42345534 写入值 = 23232324 读取值 = 23232324 写入地址 = 42345538 写入值 = 23232325 读取值 = 23232325 写入地址 = 4234553c 写入值 = 23232326 读取值 = 23232326 写入地址 = 50000000 写入值 = 34343434 读取值 = 34343434 写入地址 = 58494940 写入值 = 45454545 读取值 = 45454545 写入地址 = 60000008 写入值 = 56565656 读取值 = 56565656 写入地址 = 6ffffffc 写入值 = 67676767 读取值 = 67676767 写入地址 = 70000000 写入值 = 78787878 读取值 = 78787878 写入地址 = 7ffffffc 写入值 = 89898989 读取值 = 89898989
相关文章推荐
- 【TINY4412】U-BOOT移植笔记:(13)USB驱动
- 【TINY4412】U-BOOT移植笔记:(14)USB-OTG驱动
- 【TINY4412】U-BOOT移植笔记:(16)DM9621驱动
- 【TINY4412】U-BOOT移植笔记:(6)串口驱动
- 【TINY4412】U-BOOT移植笔记:(8)SD卡驱动
- 【TINY4412】U-BOOT移植笔记:(10)EMMC驱动
- 【TINY4412】U-BOOT移植笔记:(11)LED驱动
- 【TINY4412】U-BOOT移植笔记:(12)BEEP驱动
- 【TINY4412】LINUX移植笔记:(20)设备树LCD背光驱动
- 【TINY4412】U-BOOT移植笔记:(2)拷贝模板
- u-boot-2012.04.01移植笔记——时钟、SDRAM、UART
- 【TINY4412】U-BOOT移植笔记:(3)点灯
- 【TINY4412】U-BOOT移植笔记:(15)DFU更新固件
- 【TINY4412】U-BOOT移植笔记:(4)U-BOOT执行流程
- 【TINY4412】U-BOOT移植笔记:(5)时钟分析
- st7789 320*240 显示屏,uboot驱动移植笔记
- 【TINY4412】U-BOOT移植笔记:(17)BOOTP更新固件
- 【TINY4412】U-BOOT移植笔记:(19)TFTP更新固件
- 2440超详细uboot移植笔记(十二)------移植网卡驱动
- 【TINY4412】LINUX移植笔记:(22)设备树LCD按键驱动