]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/sunxi/dram.c
mx6sxsabresd: Add Ethernet support
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / sunxi / dram.c
1 /*
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  */
41 static 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
51 static void mctl_ddr3_reset(void)
52 {
53         struct sunxi_dram_reg *dram =
54                         (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
55
56 #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         }
76 }
77
78 static void mctl_set_drive(void)
79 {
80         struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
81
82 #ifdef CONFIG_SUN7I
83         clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3) | (0x3 << 28),
84 #else
85         clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3),
86 #endif
87                         DRAM_MCR_MODE_EN(0x3) |
88                         0xffc);
89 }
90
91 static 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
98 static 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
105 static 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  */
124 static 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
157 static u32 hpcr_value[32] = {
158 #ifdef CONFIG_SUN5I
159         0, 0, 0, 0,
160         0, 0, 0, 0,
161         0, 0, 0, 0,
162         0, 0, 0, 0,
163         0x1031, 0x1031, 0x0735, 0x1035,
164         0x1035, 0x0731, 0x1031, 0,
165         0x0301, 0x0301, 0x0301, 0x0301,
166         0x0301, 0x0301, 0x0301, 0
167 #endif
168 #ifdef CONFIG_SUN4I
169         0x0301, 0x0301, 0x0301, 0x0301,
170         0x0301, 0x0301, 0, 0,
171         0, 0, 0, 0,
172         0, 0, 0, 0,
173         0x1031, 0x1031, 0x0735, 0x5031,
174         0x1035, 0x0731, 0x1031, 0x0735,
175         0x1035, 0x1031, 0x0731, 0x1035,
176         0x1031, 0x0301, 0x0301, 0x0731
177 #endif
178 #ifdef CONFIG_SUN7I
179         0x0301, 0x0301, 0x0301, 0x0301,
180         0x0301, 0x0301, 0x0301, 0x0301,
181         0, 0, 0, 0,
182         0, 0, 0, 0,
183         0x1031, 0x1031, 0x0735, 0x1035,
184         0x1035, 0x0731, 0x1031, 0x0735,
185         0x1035, 0x1031, 0x0731, 0x1035,
186         0x0001, 0x1031, 0, 0x1031
187         /* last row differs from boot0 source table
188          * 0x1031, 0x0301, 0x0301, 0x0731
189          * but boot0 code skips #28 and #30, and sets #29 and #31 to the
190          * value from #28 entry (0x1031)
191          */
192 #endif
193 };
194
195 static void mctl_configure_hostport(void)
196 {
197         struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
198         u32 i;
199
200         for (i = 0; i < 32; i++)
201                 writel(hpcr_value[i], &dram->hpcr[i]);
202 }
203
204 static void mctl_setup_dram_clock(u32 clk)
205 {
206         u32 reg_val;
207         struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
208
209         /* setup DRAM PLL */
210         reg_val = readl(&ccm->pll5_cfg);
211         reg_val &= ~CCM_PLL5_CTRL_M_MASK;               /* set M to 0 (x1) */
212         reg_val &= ~CCM_PLL5_CTRL_K_MASK;               /* set K to 0 (x1) */
213         reg_val &= ~CCM_PLL5_CTRL_N_MASK;               /* set N to 0 (x0) */
214         reg_val &= ~CCM_PLL5_CTRL_P_MASK;               /* set P to 0 (x1) */
215         if (clk >= 540 && clk < 552) {
216                 /* dram = 540MHz, pll5p = 540MHz */
217                 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
218                 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
219                 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(15));
220                 reg_val |= CCM_PLL5_CTRL_P(1);
221         } else if (clk >= 512 && clk < 528) {
222                 /* dram = 512MHz, pll5p = 384MHz */
223                 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
224                 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(4));
225                 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(16));
226                 reg_val |= CCM_PLL5_CTRL_P(2);
227         } else if (clk >= 496 && clk < 504) {
228                 /* dram = 496MHz, pll5p = 372MHz */
229                 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
230                 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
231                 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(31));
232                 reg_val |= CCM_PLL5_CTRL_P(2);
233         } else if (clk >= 468 && clk < 480) {
234                 /* dram = 468MHz, pll5p = 468MHz */
235                 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
236                 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
237                 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(13));
238                 reg_val |= CCM_PLL5_CTRL_P(1);
239         } else if (clk >= 396 && clk < 408) {
240                 /* dram = 396MHz, pll5p = 396MHz */
241                 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
242                 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
243                 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(11));
244                 reg_val |= CCM_PLL5_CTRL_P(1);
245         } else  {
246                 /* any other frequency that is a multiple of 24 */
247                 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
248                 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
249                 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24));
250                 reg_val |= CCM_PLL5_CTRL_P(CCM_PLL5_CTRL_P_X(2));
251         }
252         reg_val &= ~CCM_PLL5_CTRL_VCO_GAIN;             /* PLL VCO Gain off */
253         reg_val |= CCM_PLL5_CTRL_EN;                    /* PLL On */
254         writel(reg_val, &ccm->pll5_cfg);
255         udelay(5500);
256
257         setbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_DDR_CLK);
258
259 #if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)
260         /* reset GPS */
261         clrbits_le32(&ccm->gps_clk_cfg, CCM_GPS_CTRL_RESET | CCM_GPS_CTRL_GATE);
262         setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
263         udelay(1);
264         clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
265 #endif
266
267 #if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
268         /* setup MBUS clock */
269         reg_val = CCM_MBUS_CTRL_GATE |
270 #ifdef CONFIG_SUN7I
271                   CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) |
272                   CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(2)) |
273                   CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2));
274 #else /* defined(CONFIG_SUN5I) */
275                   CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL5) |
276                   CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(1)) |
277                   CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2));
278 #endif
279         writel(reg_val, &ccm->mbus_clk_cfg);
280 #endif
281
282         /*
283          * open DRAMC AHB & DLL register clock
284          * close it first
285          */
286 #if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
287         clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
288 #else
289         clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
290 #endif
291         udelay(22);
292
293         /* then open it */
294 #if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
295         setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
296 #else
297         setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
298 #endif
299         udelay(22);
300 }
301
302 static int dramc_scan_readpipe(void)
303 {
304         struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
305         u32 reg_val;
306
307         /* data training trigger */
308 #ifdef CONFIG_SUN7I
309         clrbits_le32(&dram->csr, DRAM_CSR_FAILED);
310 #endif
311         setbits_le32(&dram->ccr, DRAM_CCR_DATA_TRAINING);
312
313         /* check whether data training process has completed */
314         await_completion(&dram->ccr, DRAM_CCR_DATA_TRAINING);
315
316         /* check data training result */
317         reg_val = readl(&dram->csr);
318         if (reg_val & DRAM_CSR_FAILED)
319                 return -1;
320
321         return 0;
322 }
323
324 static int dramc_scan_dll_para(void)
325 {
326         struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
327         const u32 dqs_dly[7] = {0x3, 0x2, 0x1, 0x0, 0xe, 0xd, 0xc};
328         const u32 clk_dly[15] = {0x07, 0x06, 0x05, 0x04, 0x03,
329                                  0x02, 0x01, 0x00, 0x08, 0x10,
330                                  0x18, 0x20, 0x28, 0x30, 0x38};
331         u32 clk_dqs_count[15];
332         u32 dqs_i, clk_i, cr_i;
333         u32 max_val, min_val;
334         u32 dqs_index, clk_index;
335
336         /* Find DQS_DLY Pass Count for every CLK_DLY */
337         for (clk_i = 0; clk_i < 15; clk_i++) {
338                 clk_dqs_count[clk_i] = 0;
339                 clrsetbits_le32(&dram->dllcr[0], 0x3f << 6,
340                                 (clk_dly[clk_i] & 0x3f) << 6);
341                 for (dqs_i = 0; dqs_i < 7; dqs_i++) {
342                         for (cr_i = 1; cr_i < 5; cr_i++) {
343                                 clrsetbits_le32(&dram->dllcr[cr_i],
344                                                 0x4f << 14,
345                                                 (dqs_dly[dqs_i] & 0x4f) << 14);
346                         }
347                         udelay(2);
348                         if (dramc_scan_readpipe() == 0)
349                                 clk_dqs_count[clk_i]++;
350                 }
351         }
352         /* Test DQS_DLY Pass Count for every CLK_DLY from up to down */
353         for (dqs_i = 15; dqs_i > 0; dqs_i--) {
354                 max_val = 15;
355                 min_val = 15;
356                 for (clk_i = 0; clk_i < 15; clk_i++) {
357                         if (clk_dqs_count[clk_i] == dqs_i) {
358                                 max_val = clk_i;
359                                 if (min_val == 15)
360                                         min_val = clk_i;
361                         }
362                 }
363                 if (max_val < 15)
364                         break;
365         }
366
367         /* Check if Find a CLK_DLY failed */
368         if (!dqs_i)
369                 goto fail;
370
371         /* Find the middle index of CLK_DLY */
372         clk_index = (max_val + min_val) >> 1;
373         if ((max_val == (15 - 1)) && (min_val > 0))
374                 /* if CLK_DLY[MCTL_CLK_DLY_COUNT] is very good, then the middle
375                  * value can be more close to the max_val
376                  */
377                 clk_index = (15 + clk_index) >> 1;
378         else if ((max_val < (15 - 1)) && (min_val == 0))
379                 /* if CLK_DLY[0] is very good, then the middle value can be more
380                  * close to the min_val
381                  */
382                 clk_index >>= 1;
383         if (clk_dqs_count[clk_index] < dqs_i)
384                 clk_index = min_val;
385
386         /* Find the middle index of DQS_DLY for the CLK_DLY got above, and Scan
387          * read pipe again
388          */
389         clrsetbits_le32(&dram->dllcr[0], 0x3f << 6,
390                         (clk_dly[clk_index] & 0x3f) << 6);
391         max_val = 7;
392         min_val = 7;
393         for (dqs_i = 0; dqs_i < 7; dqs_i++) {
394                 clk_dqs_count[dqs_i] = 0;
395                 for (cr_i = 1; cr_i < 5; cr_i++) {
396                         clrsetbits_le32(&dram->dllcr[cr_i],
397                                         0x4f << 14,
398                                         (dqs_dly[dqs_i] & 0x4f) << 14);
399                 }
400                 udelay(2);
401                 if (dramc_scan_readpipe() == 0) {
402                         clk_dqs_count[dqs_i] = 1;
403                         max_val = dqs_i;
404                         if (min_val == 7)
405                                 min_val = dqs_i;
406                 }
407         }
408
409         if (max_val < 7) {
410                 dqs_index = (max_val + min_val) >> 1;
411                 if ((max_val == (7-1)) && (min_val > 0))
412                         dqs_index = (7 + dqs_index) >> 1;
413                 else if ((max_val < (7-1)) && (min_val == 0))
414                         dqs_index >>= 1;
415                 if (!clk_dqs_count[dqs_index])
416                         dqs_index = min_val;
417                 for (cr_i = 1; cr_i < 5; cr_i++) {
418                         clrsetbits_le32(&dram->dllcr[cr_i],
419                                         0x4f << 14,
420                                         (dqs_dly[dqs_index] & 0x4f) << 14);
421                 }
422                 udelay(2);
423                 return dramc_scan_readpipe();
424         }
425
426 fail:
427         clrbits_le32(&dram->dllcr[0], 0x3f << 6);
428         for (cr_i = 1; cr_i < 5; cr_i++)
429                 clrbits_le32(&dram->dllcr[cr_i], 0x4f << 14);
430         udelay(2);
431
432         return dramc_scan_readpipe();
433 }
434
435 static void dramc_clock_output_en(u32 on)
436 {
437 #if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
438         struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
439
440         if (on)
441                 setbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
442         else
443                 clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
444 #endif
445 #ifdef CONFIG_SUN4I
446         struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
447         if (on)
448                 setbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
449         else
450                 clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
451 #endif
452 }
453
454 static const u16 tRFC_table[2][6] = {
455         /*       256Mb    512Mb    1Gb      2Gb      4Gb      8Gb      */
456         /* DDR2  75ns     105ns    127.5ns  195ns    327.5ns  invalid  */
457         {        77,      108,     131,     200,     336,     336 },
458         /* DDR3  invalid  90ns     110ns    160ns    300ns    350ns    */
459         {        93,      93,      113,     164,     308,     359 }
460 };
461
462 static void dramc_set_autorefresh_cycle(u32 clk, u32 type, u32 density)
463 {
464         struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
465         u32 tRFC, tREFI;
466
467         tRFC = (tRFC_table[type][density] * clk + 1023) >> 10;
468         tREFI = (7987 * clk) >> 10;     /* <= 7.8us */
469
470         writel(DRAM_DRR_TREFI(tREFI) | DRAM_DRR_TRFC(tRFC), &dram->drr);
471 }
472
473 unsigned long dramc_init(struct dram_para *para)
474 {
475         struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
476         u32 reg_val;
477         u32 density;
478         int ret_val;
479
480         /* check input dram parameter structure */
481         if (!para)
482                 return 0;
483
484         /* setup DRAM relative clock */
485         mctl_setup_dram_clock(para->clock);
486
487 #ifdef CONFIG_SUN5I
488         /* Disable any pad power save control */
489         writel(0, &dram->ppwrsctl);
490 #endif
491
492         /* reset external DRAM */
493 #ifndef CONFIG_SUN7I
494         mctl_ddr3_reset();
495 #endif
496         mctl_set_drive();
497
498         /* dram clock off */
499         dramc_clock_output_en(0);
500
501 #ifdef CONFIG_SUN4I
502         /* select dram controller 1 */
503         writel(DRAM_CSEL_MAGIC, &dram->csel);
504 #endif
505
506         mctl_itm_disable();
507         mctl_enable_dll0(para->tpr3);
508
509         /* configure external DRAM */
510         reg_val = 0x0;
511         if (para->type == DRAM_MEMORY_TYPE_DDR3)
512                 reg_val |= DRAM_DCR_TYPE_DDR3;
513         reg_val |= DRAM_DCR_IO_WIDTH(para->io_width >> 3);
514
515         if (para->density == 256)
516                 density = DRAM_DCR_CHIP_DENSITY_256M;
517         else if (para->density == 512)
518                 density = DRAM_DCR_CHIP_DENSITY_512M;
519         else if (para->density == 1024)
520                 density = DRAM_DCR_CHIP_DENSITY_1024M;
521         else if (para->density == 2048)
522                 density = DRAM_DCR_CHIP_DENSITY_2048M;
523         else if (para->density == 4096)
524                 density = DRAM_DCR_CHIP_DENSITY_4096M;
525         else if (para->density == 8192)
526                 density = DRAM_DCR_CHIP_DENSITY_8192M;
527         else
528                 density = DRAM_DCR_CHIP_DENSITY_256M;
529
530         reg_val |= DRAM_DCR_CHIP_DENSITY(density);
531         reg_val |= DRAM_DCR_BUS_WIDTH((para->bus_width >> 3) - 1);
532         reg_val |= DRAM_DCR_RANK_SEL(para->rank_num - 1);
533         reg_val |= DRAM_DCR_CMD_RANK_ALL;
534         reg_val |= DRAM_DCR_MODE(DRAM_DCR_MODE_INTERLEAVE);
535         writel(reg_val, &dram->dcr);
536
537 #ifdef CONFIG_SUN7I
538         setbits_le32(&dram->zqcr1, (0x1 << 24) | (0x1 << 1));
539         if (para->tpr4 & 0x2)
540                 clrsetbits_le32(&dram->zqcr1, (0x1 << 24), (0x1 << 1));
541         dramc_clock_output_en(1);
542 #endif
543
544 #if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I))
545         /* set odt impendance divide ratio */
546         reg_val = ((para->zq) >> 8) & 0xfffff;
547         reg_val |= ((para->zq) & 0xff) << 20;
548         reg_val |= (para->zq) & 0xf0000000;
549         writel(reg_val, &dram->zqcr0);
550 #endif
551
552 #ifdef CONFIG_SUN7I
553         /* Set CKE Delay to about 1ms */
554         setbits_le32(&dram->idcr, 0x1ffff);
555 #endif
556
557 #ifdef CONFIG_SUN7I
558         if ((readl(&dram->ppwrsctl) & 0x1) != 0x1)
559                 mctl_ddr3_reset();
560         else
561                 setbits_le32(&dram->mcr, DRAM_MCR_RESET);
562 #else
563         /* dram clock on */
564         dramc_clock_output_en(1);
565 #endif
566
567         udelay(1);
568
569         await_completion(&dram->ccr, DRAM_CCR_INIT);
570
571         mctl_enable_dllx(para->tpr3);
572
573 #ifdef CONFIG_SUN4I
574         /* set odt impedance divide ratio */
575         reg_val = ((para->zq) >> 8) & 0xfffff;
576         reg_val |= ((para->zq) & 0xff) << 20;
577         reg_val |= (para->zq) & 0xf0000000;
578         writel(reg_val, &dram->zqcr0);
579 #endif
580
581 #ifdef CONFIG_SUN4I
582         /* set I/O configure register */
583         reg_val = 0x00cc0000;
584         reg_val |= (para->odt_en) & 0x3;
585         reg_val |= ((para->odt_en) & 0x3) << 30;
586         writel(reg_val, &dram->iocr);
587 #endif
588
589         /* set refresh period */
590         dramc_set_autorefresh_cycle(para->clock, para->type - 2, density);
591
592         /* set timing parameters */
593         writel(para->tpr0, &dram->tpr0);
594         writel(para->tpr1, &dram->tpr1);
595         writel(para->tpr2, &dram->tpr2);
596
597         if (para->type == DRAM_MEMORY_TYPE_DDR3) {
598                 reg_val = DRAM_MR_BURST_LENGTH(0x0);
599 #if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I))
600                 reg_val |= DRAM_MR_POWER_DOWN;
601 #endif
602                 reg_val |= DRAM_MR_CAS_LAT(para->cas - 4);
603                 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
604         } else if (para->type == DRAM_MEMORY_TYPE_DDR2) {
605                 reg_val = DRAM_MR_BURST_LENGTH(0x2);
606                 reg_val |= DRAM_MR_CAS_LAT(para->cas);
607                 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
608         }
609         writel(reg_val, &dram->mr);
610
611         writel(para->emr1, &dram->emr);
612         writel(para->emr2, &dram->emr2);
613         writel(para->emr3, &dram->emr3);
614
615         /* set DQS window mode */
616         clrsetbits_le32(&dram->ccr, DRAM_CCR_DQS_DRIFT_COMP, DRAM_CCR_DQS_GATE);
617
618 #ifdef CONFIG_SUN7I
619         /* Command rate timing mode 2T & 1T */
620         if (para->tpr4 & 0x1)
621                 setbits_le32(&dram->ccr, DRAM_CCR_COMMAND_RATE_1T);
622 #endif
623         /* reset external DRAM */
624         setbits_le32(&dram->ccr, DRAM_CCR_INIT);
625         await_completion(&dram->ccr, DRAM_CCR_INIT);
626
627 #ifdef CONFIG_SUN7I
628         /* setup zq calibration manual */
629         reg_val = readl(&dram->ppwrsctl);
630         if ((reg_val & 0x1) == 1) {
631                 /* super_standby_flag = 1 */
632
633                 reg_val = readl(0x01c20c00 + 0x120); /* rtc */
634                 reg_val &= 0x000fffff;
635                 reg_val |= 0x17b00000;
636                 writel(reg_val, &dram->zqcr0);
637
638                 /* exit self-refresh state */
639                 clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27);
640                 /* check whether command has been executed */
641                 await_completion(&dram->dcr, 0x1 << 31);
642
643                 udelay(2);
644
645                 /* dram pad hold off */
646                 setbits_le32(&dram->ppwrsctl, 0x16510000);
647
648                 await_completion(&dram->ppwrsctl, 0x1);
649
650                 /* exit self-refresh state */
651                 clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27);
652
653                 /* check whether command has been executed */
654                 await_completion(&dram->dcr, 0x1 << 31);
655
656                 udelay(2);
657
658                 /* issue a refresh command */
659                 clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x13 << 27);
660                 await_completion(&dram->dcr, 0x1 << 31);
661
662                 udelay(2);
663         }
664 #endif
665
666         /* scan read pipe value */
667         mctl_itm_enable();
668         if (para->tpr3 & (0x1 << 31)) {
669                 ret_val = dramc_scan_dll_para();
670                 if (ret_val == 0)
671                         para->tpr3 =
672                                 (((readl(&dram->dllcr[0]) >> 6) & 0x3f) << 16) |
673                                 (((readl(&dram->dllcr[1]) >> 14) & 0xf) << 0) |
674                                 (((readl(&dram->dllcr[2]) >> 14) & 0xf) << 4) |
675                                 (((readl(&dram->dllcr[3]) >> 14) & 0xf) << 8) |
676                                 (((readl(&dram->dllcr[4]) >> 14) & 0xf) << 12
677                                 );
678         } else {
679                 ret_val = dramc_scan_readpipe();
680         }
681
682         if (ret_val < 0)
683                 return 0;
684
685         /* configure all host port */
686         mctl_configure_hostport();
687
688         return get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE);
689 }