blob: 0f1ceecc1d4e72a47ee576a92456d8674c33805c [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
Hans de Goede3ab9c232014-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 Campbell2f1afcc2014-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 Goede3ab9c232014-06-09 11:36:57 +020082#ifdef CONFIG_SUN7I
Ian Campbell2f1afcc2014-05-05 11:52:25 +010083 clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3) | (0x3 << 28),
Hans de Goede3ab9c232014-06-09 11:36:57 +020084#else
85 clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3),
86#endif
Ian Campbell2f1afcc2014-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 Goede8c1c7822014-06-09 11:36:58 +0200158#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
Hans de Goede3ab9c232014-06-09 11:36:57 +0200168#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
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100178#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
195static 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
204static 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
Hans de Goede3ab9c232014-06-09 11:36:57 +0200267#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100268 /* setup MBUS clock */
269 reg_val = CCM_MBUS_CTRL_GATE |
Hans de Goede8c1c7822014-06-09 11:36:58 +0200270#ifdef CONFIG_SUN7I
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100271 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));
Hans de Goede8c1c7822014-06-09 11:36:58 +0200274#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
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100279 writel(reg_val, &ccm->mbus_clk_cfg);
Hans de Goede3ab9c232014-06-09 11:36:57 +0200280#endif
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100281
282 /*
283 * open DRAMC AHB & DLL register clock
284 * close it first
285 */
Hans de Goede3ab9c232014-06-09 11:36:57 +0200286#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100287 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
Hans de Goede3ab9c232014-06-09 11:36:57 +0200288#else
289 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
290#endif
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100291 udelay(22);
292
293 /* then open it */
Hans de Goede3ab9c232014-06-09 11:36:57 +0200294#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100295 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
Hans de Goede3ab9c232014-06-09 11:36:57 +0200296#else
297 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
298#endif
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100299 udelay(22);
300}
301
302static 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
324static 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
426fail:
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
435static 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
Hans de Goede3ab9c232014-06-09 11:36:57 +0200445#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
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100452}
453
454static 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
462static 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
473unsigned 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
Hans de Goede8c1c7822014-06-09 11:36:58 +0200487#ifdef CONFIG_SUN5I
488 /* Disable any pad power save control */
489 writel(0, &dram->ppwrsctl);
490#endif
491
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100492 /* reset external DRAM */
Hans de Goede3ab9c232014-06-09 11:36:57 +0200493#ifndef CONFIG_SUN7I
494 mctl_ddr3_reset();
495#endif
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100496 mctl_set_drive();
497
498 /* dram clock off */
499 dramc_clock_output_en(0);
500
Hans de Goede3ab9c232014-06-09 11:36:57 +0200501#ifdef CONFIG_SUN4I
502 /* select dram controller 1 */
503 writel(DRAM_CSEL_MAGIC, &dram->csel);
504#endif
505
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100506 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);
Hans de Goede3ab9c232014-06-09 11:36:57 +0200562#else
563 /* dram clock on */
564 dramc_clock_output_en(1);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100565#endif
566
567 udelay(1);
568
569 await_completion(&dram->ccr, DRAM_CCR_INIT);
570
571 mctl_enable_dllx(para->tpr3);
572
Hans de Goede3ab9c232014-06-09 11:36:57 +0200573#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
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100589 /* 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}