您的位置:首页 > 其它

【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 85C, 3.9us at 85C < TCASE < 95 C

外部时钟[主芯片提供给内存颗粒的时钟]:800MHz,主芯片需要提供给内存颗粒2个差分的

时钟信号,CK、CK/,详见内存芯片手册P27

内部时钟[DMC时钟]:400MHz

自动刷新周期TIMINGAREF:24MHz * 7.8us(查看内存手册) = 187.2 = 0xBB

TIMINGROW:查看内存手册可知,

参数数值
t_ras35
t_rc48.75
t_rcd13.75
t_rp13.75
t_rrd6
t_rfc208

代码移植

修改文件: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: