blob: 4a72480425d290a536470067f4770a7c71100265 [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/*
Siarhei Siamashka94cd3012014-08-03 05:32:45 +030039 * Wait up to 1s for value to be set in given part of reg.
Ian Campbell286c3c32014-05-05 11:52:25 +010040 */
Siarhei Siamashka94cd3012014-08-03 05:32:45 +030041static void await_completion(u32 *reg, u32 mask, u32 val)
Ian Campbell286c3c32014-05-05 11:52:25 +010042{
43 unsigned long tmo = timer_get_us() + 1000000;
44
Siarhei Siamashka94cd3012014-08-03 05:32:45 +030045 while ((readl(reg) & mask) != val) {
Ian Campbell286c3c32014-05-05 11:52:25 +010046 if (timer_get_us() > tmo)
47 panic("Timeout initialising DRAM\n");
48 }
49}
50
Siarhei Siamashkae626d2d2014-08-03 05:32:41 +030051/*
Siarhei Siamashka94cd3012014-08-03 05:32:45 +030052 * Wait up to 1s for mask to be clear in given reg.
53 */
54static inline void await_bits_clear(u32 *reg, u32 mask)
55{
56 await_completion(reg, mask, 0);
57}
58
59/*
60 * Wait up to 1s for mask to be set in given reg.
61 */
62static inline void await_bits_set(u32 *reg, u32 mask)
63{
64 await_completion(reg, mask, mask);
65}
66
67/*
Siarhei Siamashkae626d2d2014-08-03 05:32:41 +030068 * This performs the external DRAM reset by driving the RESET pin low and
69 * then high again. According to the DDR3 spec, the RESET pin needs to be
70 * kept low for at least 200 us.
71 */
Ian Campbell286c3c32014-05-05 11:52:25 +010072static void mctl_ddr3_reset(void)
73{
74 struct sunxi_dram_reg *dram =
75 (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
76
Hans de Goede745325a2014-06-09 11:36:57 +020077#ifdef CONFIG_SUN4I
78 struct sunxi_timer_reg *timer =
79 (struct sunxi_timer_reg *)SUNXI_TIMER_BASE;
80 u32 reg_val;
81
82 writel(0, &timer->cpu_cfg);
83 reg_val = readl(&timer->cpu_cfg);
84
85 if ((reg_val & CPU_CFG_CHIP_VER_MASK) !=
86 CPU_CFG_CHIP_VER(CPU_CFG_CHIP_REV_A)) {
87 setbits_le32(&dram->mcr, DRAM_MCR_RESET);
Siarhei Siamashkae626d2d2014-08-03 05:32:41 +030088 udelay(200);
Hans de Goede745325a2014-06-09 11:36:57 +020089 clrbits_le32(&dram->mcr, DRAM_MCR_RESET);
90 } else
91#endif
92 {
93 clrbits_le32(&dram->mcr, DRAM_MCR_RESET);
Siarhei Siamashkae626d2d2014-08-03 05:32:41 +030094 udelay(200);
Hans de Goede745325a2014-06-09 11:36:57 +020095 setbits_le32(&dram->mcr, DRAM_MCR_RESET);
96 }
Siarhei Siamashkaf8e88b62014-08-03 05:32:42 +030097 /* After the RESET pin is de-asserted, the DDR3 spec requires to wait
98 * for additional 500 us before driving the CKE pin (Clock Enable)
99 * high. The duration of this delay can be configured in the SDR_IDCR
100 * (Initialization Delay Configuration Register) and applied
101 * automatically by the DRAM controller during the DDR3 initialization
102 * step. But SDR_IDCR has limited range on sun4i/sun5i hardware and
103 * can't provide sufficient delay at DRAM clock frequencies higher than
104 * 524 MHz (while Allwinner A13 supports DRAM clock frequency up to
105 * 533 MHz according to the datasheet). Additionally, there is no
106 * official documentation for the SDR_IDCR register anywhere, and
107 * there is always a chance that we are interpreting it wrong.
108 * Better be safe than sorry, so add an explicit delay here. */
109 udelay(500);
Ian Campbell286c3c32014-05-05 11:52:25 +0100110}
111
112static void mctl_set_drive(void)
113{
114 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
115
Hans de Goede745325a2014-06-09 11:36:57 +0200116#ifdef CONFIG_SUN7I
Ian Campbell286c3c32014-05-05 11:52:25 +0100117 clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3) | (0x3 << 28),
Hans de Goede745325a2014-06-09 11:36:57 +0200118#else
119 clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3),
120#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100121 DRAM_MCR_MODE_EN(0x3) |
122 0xffc);
123}
124
125static void mctl_itm_disable(void)
126{
127 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
128
129 clrsetbits_le32(&dram->ccr, DRAM_CCR_INIT, DRAM_CCR_ITM_OFF);
130}
131
132static void mctl_itm_enable(void)
133{
134 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
135
136 clrbits_le32(&dram->ccr, DRAM_CCR_ITM_OFF);
137}
138
139static void mctl_enable_dll0(u32 phase)
140{
141 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
142
143 clrsetbits_le32(&dram->dllcr[0], 0x3f << 6,
144 ((phase >> 16) & 0x3f) << 6);
145 clrsetbits_le32(&dram->dllcr[0], DRAM_DLLCR_NRESET, DRAM_DLLCR_DISABLE);
146 udelay(2);
147
148 clrbits_le32(&dram->dllcr[0], DRAM_DLLCR_NRESET | DRAM_DLLCR_DISABLE);
149 udelay(22);
150
151 clrsetbits_le32(&dram->dllcr[0], DRAM_DLLCR_DISABLE, DRAM_DLLCR_NRESET);
152 udelay(22);
153}
154
155/*
156 * Note: This differs from pm/standby in that it checks the bus width
157 */
158static void mctl_enable_dllx(u32 phase)
159{
160 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
161 u32 i, n, bus_width;
162
163 bus_width = readl(&dram->dcr);
164
165 if ((bus_width & DRAM_DCR_BUS_WIDTH_MASK) ==
166 DRAM_DCR_BUS_WIDTH(DRAM_DCR_BUS_WIDTH_32BIT))
167 n = DRAM_DCR_NR_DLLCR_32BIT;
168 else
169 n = DRAM_DCR_NR_DLLCR_16BIT;
170
171 for (i = 1; i < n; i++) {
172 clrsetbits_le32(&dram->dllcr[i], 0xf << 14,
173 (phase & 0xf) << 14);
174 clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET,
175 DRAM_DLLCR_DISABLE);
176 phase >>= 4;
177 }
178 udelay(2);
179
180 for (i = 1; i < n; i++)
181 clrbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET |
182 DRAM_DLLCR_DISABLE);
183 udelay(22);
184
185 for (i = 1; i < n; i++)
186 clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_DISABLE,
187 DRAM_DLLCR_NRESET);
188 udelay(22);
189}
190
191static u32 hpcr_value[32] = {
Hans de Goedef84269c2014-06-09 11:36:58 +0200192#ifdef CONFIG_SUN5I
193 0, 0, 0, 0,
194 0, 0, 0, 0,
195 0, 0, 0, 0,
196 0, 0, 0, 0,
197 0x1031, 0x1031, 0x0735, 0x1035,
198 0x1035, 0x0731, 0x1031, 0,
199 0x0301, 0x0301, 0x0301, 0x0301,
200 0x0301, 0x0301, 0x0301, 0
201#endif
Hans de Goede745325a2014-06-09 11:36:57 +0200202#ifdef CONFIG_SUN4I
203 0x0301, 0x0301, 0x0301, 0x0301,
204 0x0301, 0x0301, 0, 0,
205 0, 0, 0, 0,
206 0, 0, 0, 0,
207 0x1031, 0x1031, 0x0735, 0x5031,
208 0x1035, 0x0731, 0x1031, 0x0735,
209 0x1035, 0x1031, 0x0731, 0x1035,
210 0x1031, 0x0301, 0x0301, 0x0731
211#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100212#ifdef CONFIG_SUN7I
213 0x0301, 0x0301, 0x0301, 0x0301,
214 0x0301, 0x0301, 0x0301, 0x0301,
215 0, 0, 0, 0,
216 0, 0, 0, 0,
217 0x1031, 0x1031, 0x0735, 0x1035,
218 0x1035, 0x0731, 0x1031, 0x0735,
219 0x1035, 0x1031, 0x0731, 0x1035,
220 0x0001, 0x1031, 0, 0x1031
221 /* last row differs from boot0 source table
222 * 0x1031, 0x0301, 0x0301, 0x0731
223 * but boot0 code skips #28 and #30, and sets #29 and #31 to the
224 * value from #28 entry (0x1031)
225 */
226#endif
227};
228
229static void mctl_configure_hostport(void)
230{
231 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
232 u32 i;
233
234 for (i = 0; i < 32; i++)
235 writel(hpcr_value[i], &dram->hpcr[i]);
236}
237
238static void mctl_setup_dram_clock(u32 clk)
239{
240 u32 reg_val;
241 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
242
243 /* setup DRAM PLL */
244 reg_val = readl(&ccm->pll5_cfg);
245 reg_val &= ~CCM_PLL5_CTRL_M_MASK; /* set M to 0 (x1) */
246 reg_val &= ~CCM_PLL5_CTRL_K_MASK; /* set K to 0 (x1) */
247 reg_val &= ~CCM_PLL5_CTRL_N_MASK; /* set N to 0 (x0) */
248 reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */
249 if (clk >= 540 && clk < 552) {
250 /* dram = 540MHz, pll5p = 540MHz */
251 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
252 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
253 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(15));
254 reg_val |= CCM_PLL5_CTRL_P(1);
255 } else if (clk >= 512 && clk < 528) {
256 /* dram = 512MHz, pll5p = 384MHz */
257 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
258 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(4));
259 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(16));
260 reg_val |= CCM_PLL5_CTRL_P(2);
261 } else if (clk >= 496 && clk < 504) {
262 /* dram = 496MHz, pll5p = 372MHz */
263 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
264 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
265 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(31));
266 reg_val |= CCM_PLL5_CTRL_P(2);
267 } else if (clk >= 468 && clk < 480) {
268 /* dram = 468MHz, pll5p = 468MHz */
269 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
270 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
271 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(13));
272 reg_val |= CCM_PLL5_CTRL_P(1);
273 } else if (clk >= 396 && clk < 408) {
274 /* dram = 396MHz, pll5p = 396MHz */
275 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
276 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
277 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(11));
278 reg_val |= CCM_PLL5_CTRL_P(1);
279 } else {
280 /* any other frequency that is a multiple of 24 */
281 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
282 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
283 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24));
284 reg_val |= CCM_PLL5_CTRL_P(CCM_PLL5_CTRL_P_X(2));
285 }
286 reg_val &= ~CCM_PLL5_CTRL_VCO_GAIN; /* PLL VCO Gain off */
287 reg_val |= CCM_PLL5_CTRL_EN; /* PLL On */
288 writel(reg_val, &ccm->pll5_cfg);
289 udelay(5500);
290
291 setbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_DDR_CLK);
292
293#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)
294 /* reset GPS */
295 clrbits_le32(&ccm->gps_clk_cfg, CCM_GPS_CTRL_RESET | CCM_GPS_CTRL_GATE);
296 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
297 udelay(1);
298 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
299#endif
300
Hans de Goede745325a2014-06-09 11:36:57 +0200301#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell286c3c32014-05-05 11:52:25 +0100302 /* setup MBUS clock */
303 reg_val = CCM_MBUS_CTRL_GATE |
Hans de Goedef84269c2014-06-09 11:36:58 +0200304#ifdef CONFIG_SUN7I
Ian Campbell286c3c32014-05-05 11:52:25 +0100305 CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) |
306 CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(2)) |
307 CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2));
Hans de Goedef84269c2014-06-09 11:36:58 +0200308#else /* defined(CONFIG_SUN5I) */
309 CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL5) |
310 CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(1)) |
311 CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2));
312#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100313 writel(reg_val, &ccm->mbus_clk_cfg);
Hans de Goede745325a2014-06-09 11:36:57 +0200314#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100315
316 /*
317 * open DRAMC AHB & DLL register clock
318 * close it first
319 */
Hans de Goede745325a2014-06-09 11:36:57 +0200320#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell286c3c32014-05-05 11:52:25 +0100321 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
Hans de Goede745325a2014-06-09 11:36:57 +0200322#else
323 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
324#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100325 udelay(22);
326
327 /* then open it */
Hans de Goede745325a2014-06-09 11:36:57 +0200328#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell286c3c32014-05-05 11:52:25 +0100329 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
Hans de Goede745325a2014-06-09 11:36:57 +0200330#else
331 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
332#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100333 udelay(22);
334}
335
336static int dramc_scan_readpipe(void)
337{
338 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
339 u32 reg_val;
340
341 /* data training trigger */
342#ifdef CONFIG_SUN7I
343 clrbits_le32(&dram->csr, DRAM_CSR_FAILED);
344#endif
345 setbits_le32(&dram->ccr, DRAM_CCR_DATA_TRAINING);
346
347 /* check whether data training process has completed */
Siarhei Siamashka94cd3012014-08-03 05:32:45 +0300348 await_bits_clear(&dram->ccr, DRAM_CCR_DATA_TRAINING);
Ian Campbell286c3c32014-05-05 11:52:25 +0100349
350 /* check data training result */
351 reg_val = readl(&dram->csr);
352 if (reg_val & DRAM_CSR_FAILED)
353 return -1;
354
355 return 0;
356}
357
Ian Campbell286c3c32014-05-05 11:52:25 +0100358static void dramc_clock_output_en(u32 on)
359{
360#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
361 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
362
363 if (on)
364 setbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
365 else
366 clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
367#endif
Hans de Goede745325a2014-06-09 11:36:57 +0200368#ifdef CONFIG_SUN4I
369 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
370 if (on)
371 setbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
372 else
373 clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
374#endif
Ian Campbell286c3c32014-05-05 11:52:25 +0100375}
376
377static const u16 tRFC_table[2][6] = {
378 /* 256Mb 512Mb 1Gb 2Gb 4Gb 8Gb */
379 /* DDR2 75ns 105ns 127.5ns 195ns 327.5ns invalid */
380 { 77, 108, 131, 200, 336, 336 },
381 /* DDR3 invalid 90ns 110ns 160ns 300ns 350ns */
382 { 93, 93, 113, 164, 308, 359 }
383};
384
385static void dramc_set_autorefresh_cycle(u32 clk, u32 type, u32 density)
386{
387 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
388 u32 tRFC, tREFI;
389
390 tRFC = (tRFC_table[type][density] * clk + 1023) >> 10;
391 tREFI = (7987 * clk) >> 10; /* <= 7.8us */
392
393 writel(DRAM_DRR_TREFI(tREFI) | DRAM_DRR_TRFC(tRFC), &dram->drr);
394}
395
Siarhei Siamashkaf2577962014-08-03 05:32:40 +0300396/*
397 * If the dram->ppwrsctl (SDR_DPCR) register has the lowest bit set to 1, this
398 * means that DRAM is currently in self-refresh mode and retaining the old
399 * data. Since we have no idea what to do in this situation yet, just set this
400 * register to 0 and initialize DRAM in the same way as on any normal reboot
401 * (discarding whatever was stored there).
402 *
403 * Note: on sun7i hardware, the highest 16 bits need to be set to 0x1651 magic
404 * value for this write operation to have any effect. On sun5i hadware this
405 * magic value is not necessary. And on sun4i hardware the writes to this
406 * register seem to have no effect at all.
407 */
408static void mctl_disable_power_save(void)
409{
410 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
411 writel(0x16510000, &dram->ppwrsctl);
412}
413
Siarhei Siamashkaf8e88b62014-08-03 05:32:42 +0300414/*
415 * After the DRAM is powered up or reset, the DDR3 spec requires to wait at
416 * least 500 us before driving the CKE pin (Clock Enable) high. The dram->idct
417 * (SDR_IDCR) register appears to configure this delay, which gets applied
418 * right at the time when the DRAM initialization is activated in the
419 * 'mctl_ddr3_initialize' function.
420 */
421static void mctl_set_cke_delay(void)
422{
423 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
424
425 /* The CKE delay is represented in DRAM clock cycles, multiplied by N
426 * (where N=2 for sun4i/sun5i and N=3 for sun7i). Here it is set to
427 * the maximum possible value 0x1ffff, just like in the Allwinner's
428 * boot0 bootloader. The resulting delay value is somewhere between
429 * ~0.4 ms (sun5i with 648 MHz DRAM clock speed) and ~1.1 ms (sun7i
430 * with 360 MHz DRAM clock speed). */
431 setbits_le32(&dram->idcr, 0x1ffff);
432}
433
434/*
435 * This triggers the DRAM initialization. It performs sending the mode registers
436 * to the DRAM among other things. Very likely the ZQCL command is also getting
437 * executed (to do the initial impedance calibration on the DRAM side of the
438 * wire). The memory controller and the PHY must be already configured before
439 * calling this function.
440 */
441static void mctl_ddr3_initialize(void)
442{
443 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
444 setbits_le32(&dram->ccr, DRAM_CCR_INIT);
Siarhei Siamashka94cd3012014-08-03 05:32:45 +0300445 await_bits_clear(&dram->ccr, DRAM_CCR_INIT);
Siarhei Siamashkaf8e88b62014-08-03 05:32:42 +0300446}
447
Ian Campbell286c3c32014-05-05 11:52:25 +0100448unsigned long dramc_init(struct dram_para *para)
449{
450 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
451 u32 reg_val;
452 u32 density;
453 int ret_val;
454
455 /* check input dram parameter structure */
456 if (!para)
457 return 0;
458
459 /* setup DRAM relative clock */
460 mctl_setup_dram_clock(para->clock);
461
Hans de Goedef84269c2014-06-09 11:36:58 +0200462 /* Disable any pad power save control */
Siarhei Siamashkaf2577962014-08-03 05:32:40 +0300463 mctl_disable_power_save();
Hans de Goedef84269c2014-06-09 11:36:58 +0200464
Ian Campbell286c3c32014-05-05 11:52:25 +0100465 mctl_set_drive();
466
467 /* dram clock off */
468 dramc_clock_output_en(0);
469
Hans de Goede745325a2014-06-09 11:36:57 +0200470#ifdef CONFIG_SUN4I
471 /* select dram controller 1 */
472 writel(DRAM_CSEL_MAGIC, &dram->csel);
473#endif
474
Ian Campbell286c3c32014-05-05 11:52:25 +0100475 mctl_itm_disable();
476 mctl_enable_dll0(para->tpr3);
477
478 /* configure external DRAM */
479 reg_val = 0x0;
480 if (para->type == DRAM_MEMORY_TYPE_DDR3)
481 reg_val |= DRAM_DCR_TYPE_DDR3;
482 reg_val |= DRAM_DCR_IO_WIDTH(para->io_width >> 3);
483
484 if (para->density == 256)
485 density = DRAM_DCR_CHIP_DENSITY_256M;
486 else if (para->density == 512)
487 density = DRAM_DCR_CHIP_DENSITY_512M;
488 else if (para->density == 1024)
489 density = DRAM_DCR_CHIP_DENSITY_1024M;
490 else if (para->density == 2048)
491 density = DRAM_DCR_CHIP_DENSITY_2048M;
492 else if (para->density == 4096)
493 density = DRAM_DCR_CHIP_DENSITY_4096M;
494 else if (para->density == 8192)
495 density = DRAM_DCR_CHIP_DENSITY_8192M;
496 else
497 density = DRAM_DCR_CHIP_DENSITY_256M;
498
499 reg_val |= DRAM_DCR_CHIP_DENSITY(density);
500 reg_val |= DRAM_DCR_BUS_WIDTH((para->bus_width >> 3) - 1);
501 reg_val |= DRAM_DCR_RANK_SEL(para->rank_num - 1);
502 reg_val |= DRAM_DCR_CMD_RANK_ALL;
503 reg_val |= DRAM_DCR_MODE(DRAM_DCR_MODE_INTERLEAVE);
504 writel(reg_val, &dram->dcr);
505
Ian Campbell286c3c32014-05-05 11:52:25 +0100506 dramc_clock_output_en(1);
Ian Campbell286c3c32014-05-05 11:52:25 +0100507
Siarhei Siamashkaf8e88b62014-08-03 05:32:42 +0300508 mctl_set_cke_delay();
Ian Campbell286c3c32014-05-05 11:52:25 +0100509
Siarhei Siamashkaf2577962014-08-03 05:32:40 +0300510 mctl_ddr3_reset();
Ian Campbell286c3c32014-05-05 11:52:25 +0100511
512 udelay(1);
513
Siarhei Siamashka94cd3012014-08-03 05:32:45 +0300514 await_bits_clear(&dram->ccr, DRAM_CCR_INIT);
Ian Campbell286c3c32014-05-05 11:52:25 +0100515
516 mctl_enable_dllx(para->tpr3);
517
Ian Campbell286c3c32014-05-05 11:52:25 +0100518 /* set refresh period */
519 dramc_set_autorefresh_cycle(para->clock, para->type - 2, density);
520
521 /* set timing parameters */
522 writel(para->tpr0, &dram->tpr0);
523 writel(para->tpr1, &dram->tpr1);
524 writel(para->tpr2, &dram->tpr2);
525
526 if (para->type == DRAM_MEMORY_TYPE_DDR3) {
527 reg_val = DRAM_MR_BURST_LENGTH(0x0);
528#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I))
529 reg_val |= DRAM_MR_POWER_DOWN;
530#endif
531 reg_val |= DRAM_MR_CAS_LAT(para->cas - 4);
532 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
533 } else if (para->type == DRAM_MEMORY_TYPE_DDR2) {
534 reg_val = DRAM_MR_BURST_LENGTH(0x2);
535 reg_val |= DRAM_MR_CAS_LAT(para->cas);
536 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
537 }
538 writel(reg_val, &dram->mr);
539
540 writel(para->emr1, &dram->emr);
541 writel(para->emr2, &dram->emr2);
542 writel(para->emr3, &dram->emr3);
543
544 /* set DQS window mode */
545 clrsetbits_le32(&dram->ccr, DRAM_CCR_DQS_DRIFT_COMP, DRAM_CCR_DQS_GATE);
546
547#ifdef CONFIG_SUN7I
548 /* Command rate timing mode 2T & 1T */
549 if (para->tpr4 & 0x1)
550 setbits_le32(&dram->ccr, DRAM_CCR_COMMAND_RATE_1T);
551#endif
Siarhei Siamashkaf8e88b62014-08-03 05:32:42 +0300552 /* initialize external DRAM */
553 mctl_ddr3_initialize();
Ian Campbell286c3c32014-05-05 11:52:25 +0100554
Ian Campbell286c3c32014-05-05 11:52:25 +0100555 /* scan read pipe value */
556 mctl_itm_enable();
Siarhei Siamashka34759d72014-08-03 05:32:39 +0300557 ret_val = dramc_scan_readpipe();
Ian Campbell286c3c32014-05-05 11:52:25 +0100558
559 if (ret_val < 0)
560 return 0;
561
562 /* configure all host port */
563 mctl_configure_hostport();
564
565 return get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE);
566}