blob: 1de752904b5a8aca3339d2404c348b18e8834015 [file] [log] [blame]
Ian Campbell286c3c32014-05-05 11:52:25 +01001/*
2 * sunxi DRAM controller initialization
3 * (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
4 * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
5 *
6 * Based on sun4i Linux kernel sources mach-sunxi/pm/standby/dram*.c
7 * and earlier U-Boot Allwiner A10 SPL work
8 *
9 * (C) Copyright 2007-2012
10 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
11 * Berg Xing <bergxing@allwinnertech.com>
12 * Tom Cubie <tangliang@allwinnertech.com>
13 *
14 * SPDX-License-Identifier: GPL-2.0+
15 */
16
17/*
18 * Unfortunately the only documentation we have on the sun7i DRAM
19 * controller is Allwinner boot0 + boot1 code, and that code uses
20 * magic numbers & shifts with no explanations. Hence this code is
21 * rather undocumented and full of magic.
22 */
23
24#include <common.h>
25#include <asm/io.h>
26#include <asm/arch/clock.h>
27#include <asm/arch/dram.h>
28#include <asm/arch/timer.h>
29#include <asm/arch/sys_proto.h>
30
31#define CPU_CFG_CHIP_VER(n) ((n) << 6)
32#define CPU_CFG_CHIP_VER_MASK CPU_CFG_CHIP_VER(0x3)
33#define CPU_CFG_CHIP_REV_A 0x0
34#define CPU_CFG_CHIP_REV_C1 0x1
35#define CPU_CFG_CHIP_REV_C2 0x2
36#define CPU_CFG_CHIP_REV_B 0x3
37
38/*
39 * Wait up to 1s for mask to be clear in given reg.
40 */
41static void await_completion(u32 *reg, u32 mask)
42{
43 unsigned long tmo = timer_get_us() + 1000000;
44
45 while (readl(reg) & mask) {
46 if (timer_get_us() > tmo)
47 panic("Timeout initialising DRAM\n");
48 }
49}
50
51static void mctl_ddr3_reset(void)
52{
53 struct sunxi_dram_reg *dram =
54 (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
55
Hans de Goede745325a2014-06-09 11:36:57 +020056#ifdef CONFIG_SUN4I
57 struct sunxi_timer_reg *timer =
58 (struct sunxi_timer_reg *)SUNXI_TIMER_BASE;
59 u32 reg_val;
60
61 writel(0, &timer->cpu_cfg);
62 reg_val = readl(&timer->cpu_cfg);
63
64 if ((reg_val & CPU_CFG_CHIP_VER_MASK) !=
65 CPU_CFG_CHIP_VER(CPU_CFG_CHIP_REV_A)) {
66 setbits_le32(&dram->mcr, DRAM_MCR_RESET);
67 udelay(2);
68 clrbits_le32(&dram->mcr, DRAM_MCR_RESET);
69 } else
70#endif
71 {
72 clrbits_le32(&dram->mcr, DRAM_MCR_RESET);
73 udelay(2);
74 setbits_le32(&dram->mcr, DRAM_MCR_RESET);
75 }
Ian Campbell286c3c32014-05-05 11:52:25 +010076}
77
78static void mctl_set_drive(void)
79{
80 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
81
Hans de Goede745325a2014-06-09 11:36:57 +020082#ifdef CONFIG_SUN7I
Ian Campbell286c3c32014-05-05 11:52:25 +010083 clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3) | (0x3 << 28),
Hans de Goede745325a2014-06-09 11:36:57 +020084#else
85 clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3),
86#endif
Ian Campbell286c3c32014-05-05 11:52:25 +010087 DRAM_MCR_MODE_EN(0x3) |
88 0xffc);
89}
90
91static void mctl_itm_disable(void)
92{
93 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
94
95 clrsetbits_le32(&dram->ccr, DRAM_CCR_INIT, DRAM_CCR_ITM_OFF);
96}
97
98static void mctl_itm_enable(void)
99{
100 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
101
102 clrbits_le32(&dram->ccr, DRAM_CCR_ITM_OFF);
103}
104
105static void mctl_enable_dll0(u32 phase)
106{
107 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
108
109 clrsetbits_le32(&dram->dllcr[0], 0x3f << 6,
110 ((phase >> 16) & 0x3f) << 6);
111 clrsetbits_le32(&dram->dllcr[0], DRAM_DLLCR_NRESET, DRAM_DLLCR_DISABLE);
112 udelay(2);
113
114 clrbits_le32(&dram->dllcr[0], DRAM_DLLCR_NRESET | DRAM_DLLCR_DISABLE);
115 udelay(22);
116
117 clrsetbits_le32(&dram->dllcr[0], DRAM_DLLCR_DISABLE, DRAM_DLLCR_NRESET);
118 udelay(22);
119}
120
121/*
122 * Note: This differs from pm/standby in that it checks the bus width
123 */
124static void mctl_enable_dllx(u32 phase)
125{
126 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
127 u32 i, n, bus_width;
128
129 bus_width = readl(&dram->dcr);
130
131 if ((bus_width & DRAM_DCR_BUS_WIDTH_MASK) ==
132 DRAM_DCR_BUS_WIDTH(DRAM_DCR_BUS_WIDTH_32BIT))
133 n = DRAM_DCR_NR_DLLCR_32BIT;
134 else
135 n = DRAM_DCR_NR_DLLCR_16BIT;
136
137 for (i = 1; i < n; i++) {
138 clrsetbits_le32(&dram->dllcr[i], 0xf << 14,
139 (phase & 0xf) << 14);
140 clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET,
141 DRAM_DLLCR_DISABLE);
142 phase >>= 4;
143 }
144 udelay(2);
145
146 for (i = 1; i < n; i++)
147 clrbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET |
148 DRAM_DLLCR_DISABLE);
149 udelay(22);
150
151 for (i = 1; i < n; i++)
152 clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_DISABLE,
153 DRAM_DLLCR_NRESET);
154 udelay(22);
155}
156
157static u32 hpcr_value[32] = {
Hans de Goede745325a2014-06-09 11:36:57 +0200158#ifdef CONFIG_SUN4I
159 0x0301, 0x0301, 0x0301, 0x0301,
160 0x0301, 0x0301, 0, 0,
161 0, 0, 0, 0,
162 0, 0, 0, 0,
163 0x1031, 0x1031, 0x0735, 0x5031,
164 0x1035, 0x0731, 0x1031, 0x0735,
165 0x1035, 0x1031, 0x0731, 0x1035,
166 0x1031, 0x0301, 0x0301, 0x0731
167#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100168#ifdef CONFIG_SUN7I
169 0x0301, 0x0301, 0x0301, 0x0301,
170 0x0301, 0x0301, 0x0301, 0x0301,
171 0, 0, 0, 0,
172 0, 0, 0, 0,
173 0x1031, 0x1031, 0x0735, 0x1035,
174 0x1035, 0x0731, 0x1031, 0x0735,
175 0x1035, 0x1031, 0x0731, 0x1035,
176 0x0001, 0x1031, 0, 0x1031
177 /* last row differs from boot0 source table
178 * 0x1031, 0x0301, 0x0301, 0x0731
179 * but boot0 code skips #28 and #30, and sets #29 and #31 to the
180 * value from #28 entry (0x1031)
181 */
182#endif
183};
184
185static void mctl_configure_hostport(void)
186{
187 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
188 u32 i;
189
190 for (i = 0; i < 32; i++)
191 writel(hpcr_value[i], &dram->hpcr[i]);
192}
193
194static void mctl_setup_dram_clock(u32 clk)
195{
196 u32 reg_val;
197 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
198
199 /* setup DRAM PLL */
200 reg_val = readl(&ccm->pll5_cfg);
201 reg_val &= ~CCM_PLL5_CTRL_M_MASK; /* set M to 0 (x1) */
202 reg_val &= ~CCM_PLL5_CTRL_K_MASK; /* set K to 0 (x1) */
203 reg_val &= ~CCM_PLL5_CTRL_N_MASK; /* set N to 0 (x0) */
204 reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */
205 if (clk >= 540 && clk < 552) {
206 /* dram = 540MHz, pll5p = 540MHz */
207 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
208 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
209 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(15));
210 reg_val |= CCM_PLL5_CTRL_P(1);
211 } else if (clk >= 512 && clk < 528) {
212 /* dram = 512MHz, pll5p = 384MHz */
213 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
214 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(4));
215 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(16));
216 reg_val |= CCM_PLL5_CTRL_P(2);
217 } else if (clk >= 496 && clk < 504) {
218 /* dram = 496MHz, pll5p = 372MHz */
219 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
220 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
221 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(31));
222 reg_val |= CCM_PLL5_CTRL_P(2);
223 } else if (clk >= 468 && clk < 480) {
224 /* dram = 468MHz, pll5p = 468MHz */
225 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
226 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
227 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(13));
228 reg_val |= CCM_PLL5_CTRL_P(1);
229 } else if (clk >= 396 && clk < 408) {
230 /* dram = 396MHz, pll5p = 396MHz */
231 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
232 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
233 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(11));
234 reg_val |= CCM_PLL5_CTRL_P(1);
235 } else {
236 /* any other frequency that is a multiple of 24 */
237 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
238 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
239 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24));
240 reg_val |= CCM_PLL5_CTRL_P(CCM_PLL5_CTRL_P_X(2));
241 }
242 reg_val &= ~CCM_PLL5_CTRL_VCO_GAIN; /* PLL VCO Gain off */
243 reg_val |= CCM_PLL5_CTRL_EN; /* PLL On */
244 writel(reg_val, &ccm->pll5_cfg);
245 udelay(5500);
246
247 setbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_DDR_CLK);
248
249#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)
250 /* reset GPS */
251 clrbits_le32(&ccm->gps_clk_cfg, CCM_GPS_CTRL_RESET | CCM_GPS_CTRL_GATE);
252 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
253 udelay(1);
254 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
255#endif
256
Hans de Goede745325a2014-06-09 11:36:57 +0200257#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell286c3c32014-05-05 11:52:25 +0100258 /* setup MBUS clock */
259 reg_val = CCM_MBUS_CTRL_GATE |
260 CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) |
261 CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(2)) |
262 CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2));
263 writel(reg_val, &ccm->mbus_clk_cfg);
Hans de Goede745325a2014-06-09 11:36:57 +0200264#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100265
266 /*
267 * open DRAMC AHB & DLL register clock
268 * close it first
269 */
Hans de Goede745325a2014-06-09 11:36:57 +0200270#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell286c3c32014-05-05 11:52:25 +0100271 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
Hans de Goede745325a2014-06-09 11:36:57 +0200272#else
273 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
274#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100275 udelay(22);
276
277 /* then open it */
Hans de Goede745325a2014-06-09 11:36:57 +0200278#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell286c3c32014-05-05 11:52:25 +0100279 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
Hans de Goede745325a2014-06-09 11:36:57 +0200280#else
281 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
282#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100283 udelay(22);
284}
285
286static int dramc_scan_readpipe(void)
287{
288 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
289 u32 reg_val;
290
291 /* data training trigger */
292#ifdef CONFIG_SUN7I
293 clrbits_le32(&dram->csr, DRAM_CSR_FAILED);
294#endif
295 setbits_le32(&dram->ccr, DRAM_CCR_DATA_TRAINING);
296
297 /* check whether data training process has completed */
298 await_completion(&dram->ccr, DRAM_CCR_DATA_TRAINING);
299
300 /* check data training result */
301 reg_val = readl(&dram->csr);
302 if (reg_val & DRAM_CSR_FAILED)
303 return -1;
304
305 return 0;
306}
307
308static int dramc_scan_dll_para(void)
309{
310 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
311 const u32 dqs_dly[7] = {0x3, 0x2, 0x1, 0x0, 0xe, 0xd, 0xc};
312 const u32 clk_dly[15] = {0x07, 0x06, 0x05, 0x04, 0x03,
313 0x02, 0x01, 0x00, 0x08, 0x10,
314 0x18, 0x20, 0x28, 0x30, 0x38};
315 u32 clk_dqs_count[15];
316 u32 dqs_i, clk_i, cr_i;
317 u32 max_val, min_val;
318 u32 dqs_index, clk_index;
319
320 /* Find DQS_DLY Pass Count for every CLK_DLY */
321 for (clk_i = 0; clk_i < 15; clk_i++) {
322 clk_dqs_count[clk_i] = 0;
323 clrsetbits_le32(&dram->dllcr[0], 0x3f << 6,
324 (clk_dly[clk_i] & 0x3f) << 6);
325 for (dqs_i = 0; dqs_i < 7; dqs_i++) {
326 for (cr_i = 1; cr_i < 5; cr_i++) {
327 clrsetbits_le32(&dram->dllcr[cr_i],
328 0x4f << 14,
329 (dqs_dly[dqs_i] & 0x4f) << 14);
330 }
331 udelay(2);
332 if (dramc_scan_readpipe() == 0)
333 clk_dqs_count[clk_i]++;
334 }
335 }
336 /* Test DQS_DLY Pass Count for every CLK_DLY from up to down */
337 for (dqs_i = 15; dqs_i > 0; dqs_i--) {
338 max_val = 15;
339 min_val = 15;
340 for (clk_i = 0; clk_i < 15; clk_i++) {
341 if (clk_dqs_count[clk_i] == dqs_i) {
342 max_val = clk_i;
343 if (min_val == 15)
344 min_val = clk_i;
345 }
346 }
347 if (max_val < 15)
348 break;
349 }
350
351 /* Check if Find a CLK_DLY failed */
352 if (!dqs_i)
353 goto fail;
354
355 /* Find the middle index of CLK_DLY */
356 clk_index = (max_val + min_val) >> 1;
357 if ((max_val == (15 - 1)) && (min_val > 0))
358 /* if CLK_DLY[MCTL_CLK_DLY_COUNT] is very good, then the middle
359 * value can be more close to the max_val
360 */
361 clk_index = (15 + clk_index) >> 1;
362 else if ((max_val < (15 - 1)) && (min_val == 0))
363 /* if CLK_DLY[0] is very good, then the middle value can be more
364 * close to the min_val
365 */
366 clk_index >>= 1;
367 if (clk_dqs_count[clk_index] < dqs_i)
368 clk_index = min_val;
369
370 /* Find the middle index of DQS_DLY for the CLK_DLY got above, and Scan
371 * read pipe again
372 */
373 clrsetbits_le32(&dram->dllcr[0], 0x3f << 6,
374 (clk_dly[clk_index] & 0x3f) << 6);
375 max_val = 7;
376 min_val = 7;
377 for (dqs_i = 0; dqs_i < 7; dqs_i++) {
378 clk_dqs_count[dqs_i] = 0;
379 for (cr_i = 1; cr_i < 5; cr_i++) {
380 clrsetbits_le32(&dram->dllcr[cr_i],
381 0x4f << 14,
382 (dqs_dly[dqs_i] & 0x4f) << 14);
383 }
384 udelay(2);
385 if (dramc_scan_readpipe() == 0) {
386 clk_dqs_count[dqs_i] = 1;
387 max_val = dqs_i;
388 if (min_val == 7)
389 min_val = dqs_i;
390 }
391 }
392
393 if (max_val < 7) {
394 dqs_index = (max_val + min_val) >> 1;
395 if ((max_val == (7-1)) && (min_val > 0))
396 dqs_index = (7 + dqs_index) >> 1;
397 else if ((max_val < (7-1)) && (min_val == 0))
398 dqs_index >>= 1;
399 if (!clk_dqs_count[dqs_index])
400 dqs_index = min_val;
401 for (cr_i = 1; cr_i < 5; cr_i++) {
402 clrsetbits_le32(&dram->dllcr[cr_i],
403 0x4f << 14,
404 (dqs_dly[dqs_index] & 0x4f) << 14);
405 }
406 udelay(2);
407 return dramc_scan_readpipe();
408 }
409
410fail:
411 clrbits_le32(&dram->dllcr[0], 0x3f << 6);
412 for (cr_i = 1; cr_i < 5; cr_i++)
413 clrbits_le32(&dram->dllcr[cr_i], 0x4f << 14);
414 udelay(2);
415
416 return dramc_scan_readpipe();
417}
418
419static void dramc_clock_output_en(u32 on)
420{
421#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
422 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
423
424 if (on)
425 setbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
426 else
427 clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
428#endif
Hans de Goede745325a2014-06-09 11:36:57 +0200429#ifdef CONFIG_SUN4I
430 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
431 if (on)
432 setbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
433 else
434 clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
435#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100436}
437
438static const u16 tRFC_table[2][6] = {
439 /* 256Mb 512Mb 1Gb 2Gb 4Gb 8Gb */
440 /* DDR2 75ns 105ns 127.5ns 195ns 327.5ns invalid */
441 { 77, 108, 131, 200, 336, 336 },
442 /* DDR3 invalid 90ns 110ns 160ns 300ns 350ns */
443 { 93, 93, 113, 164, 308, 359 }
444};
445
446static void dramc_set_autorefresh_cycle(u32 clk, u32 type, u32 density)
447{
448 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
449 u32 tRFC, tREFI;
450
451 tRFC = (tRFC_table[type][density] * clk + 1023) >> 10;
452 tREFI = (7987 * clk) >> 10; /* <= 7.8us */
453
454 writel(DRAM_DRR_TREFI(tREFI) | DRAM_DRR_TRFC(tRFC), &dram->drr);
455}
456
457unsigned long dramc_init(struct dram_para *para)
458{
459 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
460 u32 reg_val;
461 u32 density;
462 int ret_val;
463
464 /* check input dram parameter structure */
465 if (!para)
466 return 0;
467
468 /* setup DRAM relative clock */
469 mctl_setup_dram_clock(para->clock);
470
471 /* reset external DRAM */
Hans de Goede745325a2014-06-09 11:36:57 +0200472#ifndef CONFIG_SUN7I
473 mctl_ddr3_reset();
474#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100475 mctl_set_drive();
476
477 /* dram clock off */
478 dramc_clock_output_en(0);
479
Hans de Goede745325a2014-06-09 11:36:57 +0200480#ifdef CONFIG_SUN4I
481 /* select dram controller 1 */
482 writel(DRAM_CSEL_MAGIC, &dram->csel);
483#endif
484
Ian Campbell286c3c32014-05-05 11:52:25 +0100485 mctl_itm_disable();
486 mctl_enable_dll0(para->tpr3);
487
488 /* configure external DRAM */
489 reg_val = 0x0;
490 if (para->type == DRAM_MEMORY_TYPE_DDR3)
491 reg_val |= DRAM_DCR_TYPE_DDR3;
492 reg_val |= DRAM_DCR_IO_WIDTH(para->io_width >> 3);
493
494 if (para->density == 256)
495 density = DRAM_DCR_CHIP_DENSITY_256M;
496 else if (para->density == 512)
497 density = DRAM_DCR_CHIP_DENSITY_512M;
498 else if (para->density == 1024)
499 density = DRAM_DCR_CHIP_DENSITY_1024M;
500 else if (para->density == 2048)
501 density = DRAM_DCR_CHIP_DENSITY_2048M;
502 else if (para->density == 4096)
503 density = DRAM_DCR_CHIP_DENSITY_4096M;
504 else if (para->density == 8192)
505 density = DRAM_DCR_CHIP_DENSITY_8192M;
506 else
507 density = DRAM_DCR_CHIP_DENSITY_256M;
508
509 reg_val |= DRAM_DCR_CHIP_DENSITY(density);
510 reg_val |= DRAM_DCR_BUS_WIDTH((para->bus_width >> 3) - 1);
511 reg_val |= DRAM_DCR_RANK_SEL(para->rank_num - 1);
512 reg_val |= DRAM_DCR_CMD_RANK_ALL;
513 reg_val |= DRAM_DCR_MODE(DRAM_DCR_MODE_INTERLEAVE);
514 writel(reg_val, &dram->dcr);
515
516#ifdef CONFIG_SUN7I
517 setbits_le32(&dram->zqcr1, (0x1 << 24) | (0x1 << 1));
518 if (para->tpr4 & 0x2)
519 clrsetbits_le32(&dram->zqcr1, (0x1 << 24), (0x1 << 1));
520 dramc_clock_output_en(1);
521#endif
522
523#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I))
524 /* set odt impendance divide ratio */
525 reg_val = ((para->zq) >> 8) & 0xfffff;
526 reg_val |= ((para->zq) & 0xff) << 20;
527 reg_val |= (para->zq) & 0xf0000000;
528 writel(reg_val, &dram->zqcr0);
529#endif
530
531#ifdef CONFIG_SUN7I
532 /* Set CKE Delay to about 1ms */
533 setbits_le32(&dram->idcr, 0x1ffff);
534#endif
535
536#ifdef CONFIG_SUN7I
537 if ((readl(&dram->ppwrsctl) & 0x1) != 0x1)
538 mctl_ddr3_reset();
539 else
540 setbits_le32(&dram->mcr, DRAM_MCR_RESET);
Hans de Goede745325a2014-06-09 11:36:57 +0200541#else
542 /* dram clock on */
543 dramc_clock_output_en(1);
Ian Campbell286c3c32014-05-05 11:52:25 +0100544#endif
545
546 udelay(1);
547
548 await_completion(&dram->ccr, DRAM_CCR_INIT);
549
550 mctl_enable_dllx(para->tpr3);
551
Hans de Goede745325a2014-06-09 11:36:57 +0200552#ifdef CONFIG_SUN4I
553 /* set odt impedance divide ratio */
554 reg_val = ((para->zq) >> 8) & 0xfffff;
555 reg_val |= ((para->zq) & 0xff) << 20;
556 reg_val |= (para->zq) & 0xf0000000;
557 writel(reg_val, &dram->zqcr0);
558#endif
559
560#ifdef CONFIG_SUN4I
561 /* set I/O configure register */
562 reg_val = 0x00cc0000;
563 reg_val |= (para->odt_en) & 0x3;
564 reg_val |= ((para->odt_en) & 0x3) << 30;
565 writel(reg_val, &dram->iocr);
566#endif
567
Ian Campbell286c3c32014-05-05 11:52:25 +0100568 /* set refresh period */
569 dramc_set_autorefresh_cycle(para->clock, para->type - 2, density);
570
571 /* set timing parameters */
572 writel(para->tpr0, &dram->tpr0);
573 writel(para->tpr1, &dram->tpr1);
574 writel(para->tpr2, &dram->tpr2);
575
576 if (para->type == DRAM_MEMORY_TYPE_DDR3) {
577 reg_val = DRAM_MR_BURST_LENGTH(0x0);
578#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I))
579 reg_val |= DRAM_MR_POWER_DOWN;
580#endif
581 reg_val |= DRAM_MR_CAS_LAT(para->cas - 4);
582 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
583 } else if (para->type == DRAM_MEMORY_TYPE_DDR2) {
584 reg_val = DRAM_MR_BURST_LENGTH(0x2);
585 reg_val |= DRAM_MR_CAS_LAT(para->cas);
586 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
587 }
588 writel(reg_val, &dram->mr);
589
590 writel(para->emr1, &dram->emr);
591 writel(para->emr2, &dram->emr2);
592 writel(para->emr3, &dram->emr3);
593
594 /* set DQS window mode */
595 clrsetbits_le32(&dram->ccr, DRAM_CCR_DQS_DRIFT_COMP, DRAM_CCR_DQS_GATE);
596
597#ifdef CONFIG_SUN7I
598 /* Command rate timing mode 2T & 1T */
599 if (para->tpr4 & 0x1)
600 setbits_le32(&dram->ccr, DRAM_CCR_COMMAND_RATE_1T);
601#endif
602 /* reset external DRAM */
603 setbits_le32(&dram->ccr, DRAM_CCR_INIT);
604 await_completion(&dram->ccr, DRAM_CCR_INIT);
605
606#ifdef CONFIG_SUN7I
607 /* setup zq calibration manual */
608 reg_val = readl(&dram->ppwrsctl);
609 if ((reg_val & 0x1) == 1) {
610 /* super_standby_flag = 1 */
611
612 reg_val = readl(0x01c20c00 + 0x120); /* rtc */
613 reg_val &= 0x000fffff;
614 reg_val |= 0x17b00000;
615 writel(reg_val, &dram->zqcr0);
616
617 /* exit self-refresh state */
618 clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27);
619 /* check whether command has been executed */
620 await_completion(&dram->dcr, 0x1 << 31);
621
622 udelay(2);
623
624 /* dram pad hold off */
625 setbits_le32(&dram->ppwrsctl, 0x16510000);
626
627 await_completion(&dram->ppwrsctl, 0x1);
628
629 /* exit self-refresh state */
630 clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27);
631
632 /* check whether command has been executed */
633 await_completion(&dram->dcr, 0x1 << 31);
634
635 udelay(2);
636
637 /* issue a refresh command */
638 clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x13 << 27);
639 await_completion(&dram->dcr, 0x1 << 31);
640
641 udelay(2);
642 }
643#endif
644
645 /* scan read pipe value */
646 mctl_itm_enable();
647 if (para->tpr3 & (0x1 << 31)) {
648 ret_val = dramc_scan_dll_para();
649 if (ret_val == 0)
650 para->tpr3 =
651 (((readl(&dram->dllcr[0]) >> 6) & 0x3f) << 16) |
652 (((readl(&dram->dllcr[1]) >> 14) & 0xf) << 0) |
653 (((readl(&dram->dllcr[2]) >> 14) & 0xf) << 4) |
654 (((readl(&dram->dllcr[3]) >> 14) & 0xf) << 8) |
655 (((readl(&dram->dllcr[4]) >> 14) & 0xf) << 12
656 );
657 } else {
658 ret_val = dramc_scan_readpipe();
659 }
660
661 if (ret_val < 0)
662 return 0;
663
664 /* configure all host port */
665 mctl_configure_hostport();
666
667 return get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE);
668}