blob: b43c4b41d3c53dc339b3f4f4229daa9fca7f9764 [file] [log] [blame]
Ian Campbell2f1afcc2014-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
56 clrbits_le32(&dram->mcr, DRAM_MCR_RESET);
57 udelay(2);
58 setbits_le32(&dram->mcr, DRAM_MCR_RESET);
59}
60
61static void mctl_set_drive(void)
62{
63 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
64
65 clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3) | (0x3 << 28),
66 DRAM_MCR_MODE_EN(0x3) |
67 0xffc);
68}
69
70static void mctl_itm_disable(void)
71{
72 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
73
74 clrsetbits_le32(&dram->ccr, DRAM_CCR_INIT, DRAM_CCR_ITM_OFF);
75}
76
77static void mctl_itm_enable(void)
78{
79 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
80
81 clrbits_le32(&dram->ccr, DRAM_CCR_ITM_OFF);
82}
83
84static void mctl_enable_dll0(u32 phase)
85{
86 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
87
88 clrsetbits_le32(&dram->dllcr[0], 0x3f << 6,
89 ((phase >> 16) & 0x3f) << 6);
90 clrsetbits_le32(&dram->dllcr[0], DRAM_DLLCR_NRESET, DRAM_DLLCR_DISABLE);
91 udelay(2);
92
93 clrbits_le32(&dram->dllcr[0], DRAM_DLLCR_NRESET | DRAM_DLLCR_DISABLE);
94 udelay(22);
95
96 clrsetbits_le32(&dram->dllcr[0], DRAM_DLLCR_DISABLE, DRAM_DLLCR_NRESET);
97 udelay(22);
98}
99
100/*
101 * Note: This differs from pm/standby in that it checks the bus width
102 */
103static void mctl_enable_dllx(u32 phase)
104{
105 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
106 u32 i, n, bus_width;
107
108 bus_width = readl(&dram->dcr);
109
110 if ((bus_width & DRAM_DCR_BUS_WIDTH_MASK) ==
111 DRAM_DCR_BUS_WIDTH(DRAM_DCR_BUS_WIDTH_32BIT))
112 n = DRAM_DCR_NR_DLLCR_32BIT;
113 else
114 n = DRAM_DCR_NR_DLLCR_16BIT;
115
116 for (i = 1; i < n; i++) {
117 clrsetbits_le32(&dram->dllcr[i], 0xf << 14,
118 (phase & 0xf) << 14);
119 clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET,
120 DRAM_DLLCR_DISABLE);
121 phase >>= 4;
122 }
123 udelay(2);
124
125 for (i = 1; i < n; i++)
126 clrbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET |
127 DRAM_DLLCR_DISABLE);
128 udelay(22);
129
130 for (i = 1; i < n; i++)
131 clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_DISABLE,
132 DRAM_DLLCR_NRESET);
133 udelay(22);
134}
135
136static u32 hpcr_value[32] = {
137#ifdef CONFIG_SUN7I
138 0x0301, 0x0301, 0x0301, 0x0301,
139 0x0301, 0x0301, 0x0301, 0x0301,
140 0, 0, 0, 0,
141 0, 0, 0, 0,
142 0x1031, 0x1031, 0x0735, 0x1035,
143 0x1035, 0x0731, 0x1031, 0x0735,
144 0x1035, 0x1031, 0x0731, 0x1035,
145 0x0001, 0x1031, 0, 0x1031
146 /* last row differs from boot0 source table
147 * 0x1031, 0x0301, 0x0301, 0x0731
148 * but boot0 code skips #28 and #30, and sets #29 and #31 to the
149 * value from #28 entry (0x1031)
150 */
151#endif
152};
153
154static void mctl_configure_hostport(void)
155{
156 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
157 u32 i;
158
159 for (i = 0; i < 32; i++)
160 writel(hpcr_value[i], &dram->hpcr[i]);
161}
162
163static void mctl_setup_dram_clock(u32 clk)
164{
165 u32 reg_val;
166 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
167
168 /* setup DRAM PLL */
169 reg_val = readl(&ccm->pll5_cfg);
170 reg_val &= ~CCM_PLL5_CTRL_M_MASK; /* set M to 0 (x1) */
171 reg_val &= ~CCM_PLL5_CTRL_K_MASK; /* set K to 0 (x1) */
172 reg_val &= ~CCM_PLL5_CTRL_N_MASK; /* set N to 0 (x0) */
173 reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */
174 if (clk >= 540 && clk < 552) {
175 /* dram = 540MHz, pll5p = 540MHz */
176 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
177 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
178 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(15));
179 reg_val |= CCM_PLL5_CTRL_P(1);
180 } else if (clk >= 512 && clk < 528) {
181 /* dram = 512MHz, pll5p = 384MHz */
182 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
183 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(4));
184 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(16));
185 reg_val |= CCM_PLL5_CTRL_P(2);
186 } else if (clk >= 496 && clk < 504) {
187 /* dram = 496MHz, pll5p = 372MHz */
188 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
189 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
190 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(31));
191 reg_val |= CCM_PLL5_CTRL_P(2);
192 } else if (clk >= 468 && clk < 480) {
193 /* dram = 468MHz, pll5p = 468MHz */
194 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
195 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
196 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(13));
197 reg_val |= CCM_PLL5_CTRL_P(1);
198 } else if (clk >= 396 && clk < 408) {
199 /* dram = 396MHz, pll5p = 396MHz */
200 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
201 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
202 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(11));
203 reg_val |= CCM_PLL5_CTRL_P(1);
204 } else {
205 /* any other frequency that is a multiple of 24 */
206 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
207 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
208 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24));
209 reg_val |= CCM_PLL5_CTRL_P(CCM_PLL5_CTRL_P_X(2));
210 }
211 reg_val &= ~CCM_PLL5_CTRL_VCO_GAIN; /* PLL VCO Gain off */
212 reg_val |= CCM_PLL5_CTRL_EN; /* PLL On */
213 writel(reg_val, &ccm->pll5_cfg);
214 udelay(5500);
215
216 setbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_DDR_CLK);
217
218#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)
219 /* reset GPS */
220 clrbits_le32(&ccm->gps_clk_cfg, CCM_GPS_CTRL_RESET | CCM_GPS_CTRL_GATE);
221 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
222 udelay(1);
223 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
224#endif
225
226 /* setup MBUS clock */
227 reg_val = CCM_MBUS_CTRL_GATE |
228 CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) |
229 CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(2)) |
230 CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2));
231 writel(reg_val, &ccm->mbus_clk_cfg);
232
233 /*
234 * open DRAMC AHB & DLL register clock
235 * close it first
236 */
237 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
238 udelay(22);
239
240 /* then open it */
241 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
242 udelay(22);
243}
244
245static int dramc_scan_readpipe(void)
246{
247 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
248 u32 reg_val;
249
250 /* data training trigger */
251#ifdef CONFIG_SUN7I
252 clrbits_le32(&dram->csr, DRAM_CSR_FAILED);
253#endif
254 setbits_le32(&dram->ccr, DRAM_CCR_DATA_TRAINING);
255
256 /* check whether data training process has completed */
257 await_completion(&dram->ccr, DRAM_CCR_DATA_TRAINING);
258
259 /* check data training result */
260 reg_val = readl(&dram->csr);
261 if (reg_val & DRAM_CSR_FAILED)
262 return -1;
263
264 return 0;
265}
266
267static int dramc_scan_dll_para(void)
268{
269 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
270 const u32 dqs_dly[7] = {0x3, 0x2, 0x1, 0x0, 0xe, 0xd, 0xc};
271 const u32 clk_dly[15] = {0x07, 0x06, 0x05, 0x04, 0x03,
272 0x02, 0x01, 0x00, 0x08, 0x10,
273 0x18, 0x20, 0x28, 0x30, 0x38};
274 u32 clk_dqs_count[15];
275 u32 dqs_i, clk_i, cr_i;
276 u32 max_val, min_val;
277 u32 dqs_index, clk_index;
278
279 /* Find DQS_DLY Pass Count for every CLK_DLY */
280 for (clk_i = 0; clk_i < 15; clk_i++) {
281 clk_dqs_count[clk_i] = 0;
282 clrsetbits_le32(&dram->dllcr[0], 0x3f << 6,
283 (clk_dly[clk_i] & 0x3f) << 6);
284 for (dqs_i = 0; dqs_i < 7; dqs_i++) {
285 for (cr_i = 1; cr_i < 5; cr_i++) {
286 clrsetbits_le32(&dram->dllcr[cr_i],
287 0x4f << 14,
288 (dqs_dly[dqs_i] & 0x4f) << 14);
289 }
290 udelay(2);
291 if (dramc_scan_readpipe() == 0)
292 clk_dqs_count[clk_i]++;
293 }
294 }
295 /* Test DQS_DLY Pass Count for every CLK_DLY from up to down */
296 for (dqs_i = 15; dqs_i > 0; dqs_i--) {
297 max_val = 15;
298 min_val = 15;
299 for (clk_i = 0; clk_i < 15; clk_i++) {
300 if (clk_dqs_count[clk_i] == dqs_i) {
301 max_val = clk_i;
302 if (min_val == 15)
303 min_val = clk_i;
304 }
305 }
306 if (max_val < 15)
307 break;
308 }
309
310 /* Check if Find a CLK_DLY failed */
311 if (!dqs_i)
312 goto fail;
313
314 /* Find the middle index of CLK_DLY */
315 clk_index = (max_val + min_val) >> 1;
316 if ((max_val == (15 - 1)) && (min_val > 0))
317 /* if CLK_DLY[MCTL_CLK_DLY_COUNT] is very good, then the middle
318 * value can be more close to the max_val
319 */
320 clk_index = (15 + clk_index) >> 1;
321 else if ((max_val < (15 - 1)) && (min_val == 0))
322 /* if CLK_DLY[0] is very good, then the middle value can be more
323 * close to the min_val
324 */
325 clk_index >>= 1;
326 if (clk_dqs_count[clk_index] < dqs_i)
327 clk_index = min_val;
328
329 /* Find the middle index of DQS_DLY for the CLK_DLY got above, and Scan
330 * read pipe again
331 */
332 clrsetbits_le32(&dram->dllcr[0], 0x3f << 6,
333 (clk_dly[clk_index] & 0x3f) << 6);
334 max_val = 7;
335 min_val = 7;
336 for (dqs_i = 0; dqs_i < 7; dqs_i++) {
337 clk_dqs_count[dqs_i] = 0;
338 for (cr_i = 1; cr_i < 5; cr_i++) {
339 clrsetbits_le32(&dram->dllcr[cr_i],
340 0x4f << 14,
341 (dqs_dly[dqs_i] & 0x4f) << 14);
342 }
343 udelay(2);
344 if (dramc_scan_readpipe() == 0) {
345 clk_dqs_count[dqs_i] = 1;
346 max_val = dqs_i;
347 if (min_val == 7)
348 min_val = dqs_i;
349 }
350 }
351
352 if (max_val < 7) {
353 dqs_index = (max_val + min_val) >> 1;
354 if ((max_val == (7-1)) && (min_val > 0))
355 dqs_index = (7 + dqs_index) >> 1;
356 else if ((max_val < (7-1)) && (min_val == 0))
357 dqs_index >>= 1;
358 if (!clk_dqs_count[dqs_index])
359 dqs_index = min_val;
360 for (cr_i = 1; cr_i < 5; cr_i++) {
361 clrsetbits_le32(&dram->dllcr[cr_i],
362 0x4f << 14,
363 (dqs_dly[dqs_index] & 0x4f) << 14);
364 }
365 udelay(2);
366 return dramc_scan_readpipe();
367 }
368
369fail:
370 clrbits_le32(&dram->dllcr[0], 0x3f << 6);
371 for (cr_i = 1; cr_i < 5; cr_i++)
372 clrbits_le32(&dram->dllcr[cr_i], 0x4f << 14);
373 udelay(2);
374
375 return dramc_scan_readpipe();
376}
377
378static void dramc_clock_output_en(u32 on)
379{
380#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
381 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
382
383 if (on)
384 setbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
385 else
386 clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
387#endif
388}
389
390static const u16 tRFC_table[2][6] = {
391 /* 256Mb 512Mb 1Gb 2Gb 4Gb 8Gb */
392 /* DDR2 75ns 105ns 127.5ns 195ns 327.5ns invalid */
393 { 77, 108, 131, 200, 336, 336 },
394 /* DDR3 invalid 90ns 110ns 160ns 300ns 350ns */
395 { 93, 93, 113, 164, 308, 359 }
396};
397
398static void dramc_set_autorefresh_cycle(u32 clk, u32 type, u32 density)
399{
400 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
401 u32 tRFC, tREFI;
402
403 tRFC = (tRFC_table[type][density] * clk + 1023) >> 10;
404 tREFI = (7987 * clk) >> 10; /* <= 7.8us */
405
406 writel(DRAM_DRR_TREFI(tREFI) | DRAM_DRR_TRFC(tRFC), &dram->drr);
407}
408
409unsigned long dramc_init(struct dram_para *para)
410{
411 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
412 u32 reg_val;
413 u32 density;
414 int ret_val;
415
416 /* check input dram parameter structure */
417 if (!para)
418 return 0;
419
420 /* setup DRAM relative clock */
421 mctl_setup_dram_clock(para->clock);
422
423 /* reset external DRAM */
424 mctl_set_drive();
425
426 /* dram clock off */
427 dramc_clock_output_en(0);
428
429 mctl_itm_disable();
430 mctl_enable_dll0(para->tpr3);
431
432 /* configure external DRAM */
433 reg_val = 0x0;
434 if (para->type == DRAM_MEMORY_TYPE_DDR3)
435 reg_val |= DRAM_DCR_TYPE_DDR3;
436 reg_val |= DRAM_DCR_IO_WIDTH(para->io_width >> 3);
437
438 if (para->density == 256)
439 density = DRAM_DCR_CHIP_DENSITY_256M;
440 else if (para->density == 512)
441 density = DRAM_DCR_CHIP_DENSITY_512M;
442 else if (para->density == 1024)
443 density = DRAM_DCR_CHIP_DENSITY_1024M;
444 else if (para->density == 2048)
445 density = DRAM_DCR_CHIP_DENSITY_2048M;
446 else if (para->density == 4096)
447 density = DRAM_DCR_CHIP_DENSITY_4096M;
448 else if (para->density == 8192)
449 density = DRAM_DCR_CHIP_DENSITY_8192M;
450 else
451 density = DRAM_DCR_CHIP_DENSITY_256M;
452
453 reg_val |= DRAM_DCR_CHIP_DENSITY(density);
454 reg_val |= DRAM_DCR_BUS_WIDTH((para->bus_width >> 3) - 1);
455 reg_val |= DRAM_DCR_RANK_SEL(para->rank_num - 1);
456 reg_val |= DRAM_DCR_CMD_RANK_ALL;
457 reg_val |= DRAM_DCR_MODE(DRAM_DCR_MODE_INTERLEAVE);
458 writel(reg_val, &dram->dcr);
459
460#ifdef CONFIG_SUN7I
461 setbits_le32(&dram->zqcr1, (0x1 << 24) | (0x1 << 1));
462 if (para->tpr4 & 0x2)
463 clrsetbits_le32(&dram->zqcr1, (0x1 << 24), (0x1 << 1));
464 dramc_clock_output_en(1);
465#endif
466
467#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I))
468 /* set odt impendance divide ratio */
469 reg_val = ((para->zq) >> 8) & 0xfffff;
470 reg_val |= ((para->zq) & 0xff) << 20;
471 reg_val |= (para->zq) & 0xf0000000;
472 writel(reg_val, &dram->zqcr0);
473#endif
474
475#ifdef CONFIG_SUN7I
476 /* Set CKE Delay to about 1ms */
477 setbits_le32(&dram->idcr, 0x1ffff);
478#endif
479
480#ifdef CONFIG_SUN7I
481 if ((readl(&dram->ppwrsctl) & 0x1) != 0x1)
482 mctl_ddr3_reset();
483 else
484 setbits_le32(&dram->mcr, DRAM_MCR_RESET);
485#endif
486
487 udelay(1);
488
489 await_completion(&dram->ccr, DRAM_CCR_INIT);
490
491 mctl_enable_dllx(para->tpr3);
492
493 /* set refresh period */
494 dramc_set_autorefresh_cycle(para->clock, para->type - 2, density);
495
496 /* set timing parameters */
497 writel(para->tpr0, &dram->tpr0);
498 writel(para->tpr1, &dram->tpr1);
499 writel(para->tpr2, &dram->tpr2);
500
501 if (para->type == DRAM_MEMORY_TYPE_DDR3) {
502 reg_val = DRAM_MR_BURST_LENGTH(0x0);
503#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I))
504 reg_val |= DRAM_MR_POWER_DOWN;
505#endif
506 reg_val |= DRAM_MR_CAS_LAT(para->cas - 4);
507 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
508 } else if (para->type == DRAM_MEMORY_TYPE_DDR2) {
509 reg_val = DRAM_MR_BURST_LENGTH(0x2);
510 reg_val |= DRAM_MR_CAS_LAT(para->cas);
511 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
512 }
513 writel(reg_val, &dram->mr);
514
515 writel(para->emr1, &dram->emr);
516 writel(para->emr2, &dram->emr2);
517 writel(para->emr3, &dram->emr3);
518
519 /* set DQS window mode */
520 clrsetbits_le32(&dram->ccr, DRAM_CCR_DQS_DRIFT_COMP, DRAM_CCR_DQS_GATE);
521
522#ifdef CONFIG_SUN7I
523 /* Command rate timing mode 2T & 1T */
524 if (para->tpr4 & 0x1)
525 setbits_le32(&dram->ccr, DRAM_CCR_COMMAND_RATE_1T);
526#endif
527 /* reset external DRAM */
528 setbits_le32(&dram->ccr, DRAM_CCR_INIT);
529 await_completion(&dram->ccr, DRAM_CCR_INIT);
530
531#ifdef CONFIG_SUN7I
532 /* setup zq calibration manual */
533 reg_val = readl(&dram->ppwrsctl);
534 if ((reg_val & 0x1) == 1) {
535 /* super_standby_flag = 1 */
536
537 reg_val = readl(0x01c20c00 + 0x120); /* rtc */
538 reg_val &= 0x000fffff;
539 reg_val |= 0x17b00000;
540 writel(reg_val, &dram->zqcr0);
541
542 /* exit self-refresh state */
543 clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27);
544 /* check whether command has been executed */
545 await_completion(&dram->dcr, 0x1 << 31);
546
547 udelay(2);
548
549 /* dram pad hold off */
550 setbits_le32(&dram->ppwrsctl, 0x16510000);
551
552 await_completion(&dram->ppwrsctl, 0x1);
553
554 /* exit self-refresh state */
555 clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27);
556
557 /* check whether command has been executed */
558 await_completion(&dram->dcr, 0x1 << 31);
559
560 udelay(2);
561
562 /* issue a refresh command */
563 clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x13 << 27);
564 await_completion(&dram->dcr, 0x1 << 31);
565
566 udelay(2);
567 }
568#endif
569
570 /* scan read pipe value */
571 mctl_itm_enable();
572 if (para->tpr3 & (0x1 << 31)) {
573 ret_val = dramc_scan_dll_para();
574 if (ret_val == 0)
575 para->tpr3 =
576 (((readl(&dram->dllcr[0]) >> 6) & 0x3f) << 16) |
577 (((readl(&dram->dllcr[1]) >> 14) & 0xf) << 0) |
578 (((readl(&dram->dllcr[2]) >> 14) & 0xf) << 4) |
579 (((readl(&dram->dllcr[3]) >> 14) & 0xf) << 8) |
580 (((readl(&dram->dllcr[4]) >> 14) & 0xf) << 12
581 );
582 } else {
583 ret_val = dramc_scan_readpipe();
584 }
585
586 if (ret_val < 0)
587 return 0;
588
589 /* configure all host port */
590 mctl_configure_hostport();
591
592 return get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE);
593}