blob: 6f98c6a3bb512f1e0698fe243c8564f079f00b99 [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/*
Siarhei Siamashka72ed8692014-08-03 05:32:45 +030039 * Wait up to 1s for value to be set in given part of reg.
Ian Campbell2f1afcc2014-05-05 11:52:25 +010040 */
Siarhei Siamashka72ed8692014-08-03 05:32:45 +030041static void await_completion(u32 *reg, u32 mask, u32 val)
Ian Campbell2f1afcc2014-05-05 11:52:25 +010042{
43 unsigned long tmo = timer_get_us() + 1000000;
44
Siarhei Siamashka72ed8692014-08-03 05:32:45 +030045 while ((readl(reg) & mask) != val) {
Ian Campbell2f1afcc2014-05-05 11:52:25 +010046 if (timer_get_us() > tmo)
47 panic("Timeout initialising DRAM\n");
48 }
49}
50
Siarhei Siamashkaa1d9f032014-08-03 05:32:41 +030051/*
Siarhei Siamashka72ed8692014-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 Siamashkaa1d9f032014-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 Campbell2f1afcc2014-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 Goede3ab9c232014-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 Siamashkaa1d9f032014-08-03 05:32:41 +030088 udelay(200);
Hans de Goede3ab9c232014-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 Siamashkaa1d9f032014-08-03 05:32:41 +030094 udelay(200);
Hans de Goede3ab9c232014-06-09 11:36:57 +020095 setbits_le32(&dram->mcr, DRAM_MCR_RESET);
96 }
Siarhei Siamashkace4d21c2014-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 Campbell2f1afcc2014-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 Goede3ab9c232014-06-09 11:36:57 +0200116#ifdef CONFIG_SUN7I
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100117 clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3) | (0x3 << 28),
Hans de Goede3ab9c232014-06-09 11:36:57 +0200118#else
119 clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3),
120#endif
Ian Campbell2f1afcc2014-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 Goede8c1c7822014-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 Goede3ab9c232014-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 Campbell2f1afcc2014-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
Siarhei Siamashka586757a2014-08-03 05:32:47 +0300238static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100239{
240 u32 reg_val;
241 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
242
Siarhei Siamashka586757a2014-08-03 05:32:47 +0300243 /* PLL5P and PLL6 are the potential clock sources for MBUS */
244 u32 pll6x_div, pll5p_div;
245 u32 pll6x_clk = clock_get_pll6() / 1000000;
Siarhei Siamashka020a6342014-08-03 05:32:48 +0300246 u32 pll5p_clk = clk / 24 * 48;
Siarhei Siamashka586757a2014-08-03 05:32:47 +0300247 u32 pll5p_rate, pll6x_rate;
248#ifdef CONFIG_SUN7I
249 pll6x_clk *= 2; /* sun7i uses PLL6*2, sun5i uses just PLL6 */
250#endif
251
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100252 /* setup DRAM PLL */
253 reg_val = readl(&ccm->pll5_cfg);
254 reg_val &= ~CCM_PLL5_CTRL_M_MASK; /* set M to 0 (x1) */
255 reg_val &= ~CCM_PLL5_CTRL_K_MASK; /* set K to 0 (x1) */
256 reg_val &= ~CCM_PLL5_CTRL_N_MASK; /* set N to 0 (x0) */
257 reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */
258 if (clk >= 540 && clk < 552) {
Siarhei Siamashka020a6342014-08-03 05:32:48 +0300259 /* dram = 540MHz, pll5p = 1080MHz */
260 pll5p_clk = 1080;
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100261 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
262 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
263 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(15));
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100264 } else if (clk >= 512 && clk < 528) {
Siarhei Siamashka020a6342014-08-03 05:32:48 +0300265 /* dram = 512MHz, pll5p = 1536MHz */
266 pll5p_clk = 1536;
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100267 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
268 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(4));
269 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(16));
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100270 } else if (clk >= 496 && clk < 504) {
Siarhei Siamashka020a6342014-08-03 05:32:48 +0300271 /* dram = 496MHz, pll5p = 1488MHz */
272 pll5p_clk = 1488;
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100273 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
274 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
275 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(31));
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100276 } else if (clk >= 468 && clk < 480) {
Siarhei Siamashka020a6342014-08-03 05:32:48 +0300277 /* dram = 468MHz, pll5p = 936MHz */
278 pll5p_clk = 936;
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100279 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
280 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
281 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(13));
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100282 } else if (clk >= 396 && clk < 408) {
Siarhei Siamashka020a6342014-08-03 05:32:48 +0300283 /* dram = 396MHz, pll5p = 792MHz */
284 pll5p_clk = 792;
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100285 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
286 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
287 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(11));
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100288 } else {
289 /* any other frequency that is a multiple of 24 */
290 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
291 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
292 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24));
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100293 }
294 reg_val &= ~CCM_PLL5_CTRL_VCO_GAIN; /* PLL VCO Gain off */
295 reg_val |= CCM_PLL5_CTRL_EN; /* PLL On */
296 writel(reg_val, &ccm->pll5_cfg);
297 udelay(5500);
298
299 setbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_DDR_CLK);
300
301#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)
302 /* reset GPS */
303 clrbits_le32(&ccm->gps_clk_cfg, CCM_GPS_CTRL_RESET | CCM_GPS_CTRL_GATE);
304 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
305 udelay(1);
306 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
307#endif
308
309 /* setup MBUS clock */
Siarhei Siamashka586757a2014-08-03 05:32:47 +0300310 if (!mbus_clk)
311 mbus_clk = 300;
312 pll6x_div = DIV_ROUND_UP(pll6x_clk, mbus_clk);
313 pll5p_div = DIV_ROUND_UP(pll5p_clk, mbus_clk);
314 pll6x_rate = pll6x_clk / pll6x_div;
315 pll5p_rate = pll5p_clk / pll5p_div;
316
317 if (pll6x_div <= 16 && pll6x_rate > pll5p_rate) {
318 /* use PLL6 as the MBUS clock source */
319 reg_val = CCM_MBUS_CTRL_GATE |
320 CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) |
321 CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(1)) |
322 CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(pll6x_div));
323 } else if (pll5p_div <= 16) {
324 /* use PLL5P as the MBUS clock source */
325 reg_val = CCM_MBUS_CTRL_GATE |
326 CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL5) |
327 CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(1)) |
328 CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(pll5p_div));
329 } else {
330 panic("Bad mbus_clk\n");
331 }
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100332 writel(reg_val, &ccm->mbus_clk_cfg);
333
334 /*
335 * open DRAMC AHB & DLL register clock
336 * close it first
337 */
Hans de Goede3ab9c232014-06-09 11:36:57 +0200338#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100339 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
Hans de Goede3ab9c232014-06-09 11:36:57 +0200340#else
341 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
342#endif
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100343 udelay(22);
344
345 /* then open it */
Hans de Goede3ab9c232014-06-09 11:36:57 +0200346#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100347 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
Hans de Goede3ab9c232014-06-09 11:36:57 +0200348#else
349 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
350#endif
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100351 udelay(22);
352}
353
354static int dramc_scan_readpipe(void)
355{
356 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
357 u32 reg_val;
358
359 /* data training trigger */
360#ifdef CONFIG_SUN7I
361 clrbits_le32(&dram->csr, DRAM_CSR_FAILED);
362#endif
363 setbits_le32(&dram->ccr, DRAM_CCR_DATA_TRAINING);
364
365 /* check whether data training process has completed */
Siarhei Siamashka72ed8692014-08-03 05:32:45 +0300366 await_bits_clear(&dram->ccr, DRAM_CCR_DATA_TRAINING);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100367
368 /* check data training result */
369 reg_val = readl(&dram->csr);
370 if (reg_val & DRAM_CSR_FAILED)
371 return -1;
372
373 return 0;
374}
375
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100376static void dramc_clock_output_en(u32 on)
377{
378#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
379 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
380
381 if (on)
382 setbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
383 else
384 clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
385#endif
Hans de Goede3ab9c232014-06-09 11:36:57 +0200386#ifdef CONFIG_SUN4I
387 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
388 if (on)
389 setbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
390 else
391 clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
392#endif
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100393}
394
395static const u16 tRFC_table[2][6] = {
396 /* 256Mb 512Mb 1Gb 2Gb 4Gb 8Gb */
397 /* DDR2 75ns 105ns 127.5ns 195ns 327.5ns invalid */
398 { 77, 108, 131, 200, 336, 336 },
399 /* DDR3 invalid 90ns 110ns 160ns 300ns 350ns */
400 { 93, 93, 113, 164, 308, 359 }
401};
402
403static void dramc_set_autorefresh_cycle(u32 clk, u32 type, u32 density)
404{
405 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
406 u32 tRFC, tREFI;
407
408 tRFC = (tRFC_table[type][density] * clk + 1023) >> 10;
409 tREFI = (7987 * clk) >> 10; /* <= 7.8us */
410
411 writel(DRAM_DRR_TREFI(tREFI) | DRAM_DRR_TRFC(tRFC), &dram->drr);
412}
413
Siarhei Siamashka551bfb92014-08-03 05:32:40 +0300414/*
415 * If the dram->ppwrsctl (SDR_DPCR) register has the lowest bit set to 1, this
416 * means that DRAM is currently in self-refresh mode and retaining the old
417 * data. Since we have no idea what to do in this situation yet, just set this
418 * register to 0 and initialize DRAM in the same way as on any normal reboot
419 * (discarding whatever was stored there).
420 *
421 * Note: on sun7i hardware, the highest 16 bits need to be set to 0x1651 magic
422 * value for this write operation to have any effect. On sun5i hadware this
423 * magic value is not necessary. And on sun4i hardware the writes to this
424 * register seem to have no effect at all.
425 */
426static void mctl_disable_power_save(void)
427{
428 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
429 writel(0x16510000, &dram->ppwrsctl);
430}
431
Siarhei Siamashkace4d21c2014-08-03 05:32:42 +0300432/*
433 * After the DRAM is powered up or reset, the DDR3 spec requires to wait at
434 * least 500 us before driving the CKE pin (Clock Enable) high. The dram->idct
435 * (SDR_IDCR) register appears to configure this delay, which gets applied
436 * right at the time when the DRAM initialization is activated in the
437 * 'mctl_ddr3_initialize' function.
438 */
439static void mctl_set_cke_delay(void)
440{
441 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
442
443 /* The CKE delay is represented in DRAM clock cycles, multiplied by N
444 * (where N=2 for sun4i/sun5i and N=3 for sun7i). Here it is set to
445 * the maximum possible value 0x1ffff, just like in the Allwinner's
446 * boot0 bootloader. The resulting delay value is somewhere between
447 * ~0.4 ms (sun5i with 648 MHz DRAM clock speed) and ~1.1 ms (sun7i
448 * with 360 MHz DRAM clock speed). */
449 setbits_le32(&dram->idcr, 0x1ffff);
450}
451
452/*
453 * This triggers the DRAM initialization. It performs sending the mode registers
454 * to the DRAM among other things. Very likely the ZQCL command is also getting
455 * executed (to do the initial impedance calibration on the DRAM side of the
456 * wire). The memory controller and the PHY must be already configured before
457 * calling this function.
458 */
459static void mctl_ddr3_initialize(void)
460{
461 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
462 setbits_le32(&dram->ccr, DRAM_CCR_INIT);
Siarhei Siamashka72ed8692014-08-03 05:32:45 +0300463 await_bits_clear(&dram->ccr, DRAM_CCR_INIT);
Siarhei Siamashkace4d21c2014-08-03 05:32:42 +0300464}
465
Siarhei Siamashka3ad063a2014-08-03 05:32:46 +0300466/*
467 * Perform impedance calibration on the DRAM controller side of the wire.
468 */
469static void mctl_set_impedance(u32 zq, u32 odt_en)
470{
471 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
472 u32 reg_val;
473 u32 zprog = zq & 0xFF, zdata = (zq >> 8) & 0xFFFFF;
474
475#ifndef CONFIG_SUN7I
476 /* Appears that some kind of automatically initiated default
477 * ZQ calibration is already in progress at this point on sun4i/sun5i
478 * hardware, but not on sun7i. So it is reasonable to wait for its
479 * completion before doing anything else. */
480 await_bits_set(&dram->zqsr, DRAM_ZQSR_ZDONE);
481#endif
482
483 /* ZQ calibration is not really useful unless ODT is enabled */
484 if (!odt_en)
485 return;
486
487#ifdef CONFIG_SUN7I
488 /* Enabling ODT in SDR_IOCR on sun7i hardware results in a deadlock
489 * unless bit 24 is set in SDR_ZQCR1. Not much is known about the
490 * SDR_ZQCR1 register, but there are hints indicating that it might
491 * be related to periodic impedance re-calibration. This particular
492 * magic value is borrowed from the Allwinner boot0 bootloader, and
493 * using it helps to avoid troubles */
494 writel((1 << 24) | (1 << 1), &dram->zqcr1);
495#endif
496
497 /* Needed at least for sun5i, because it does not self clear there */
498 clrbits_le32(&dram->zqcr0, DRAM_ZQCR0_ZCAL);
499
500 if (zdata) {
501 /* Set the user supplied impedance data */
502 reg_val = DRAM_ZQCR0_ZDEN | zdata;
503 writel(reg_val, &dram->zqcr0);
504 /* no need to wait, this takes effect immediately */
505 } else {
506 /* Do the calibration using the external resistor */
507 reg_val = DRAM_ZQCR0_ZCAL | DRAM_ZQCR0_IMP_DIV(zprog);
508 writel(reg_val, &dram->zqcr0);
509 /* Wait for the new impedance configuration to settle */
510 await_bits_set(&dram->zqsr, DRAM_ZQSR_ZDONE);
511 }
512
513 /* Needed at least for sun5i, because it does not self clear there */
514 clrbits_le32(&dram->zqcr0, DRAM_ZQCR0_ZCAL);
515
516 /* Set I/O configure register */
517 writel(DRAM_IOCR_ODT_EN(odt_en), &dram->iocr);
518}
519
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100520unsigned long dramc_init(struct dram_para *para)
521{
522 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
523 u32 reg_val;
524 u32 density;
525 int ret_val;
526
527 /* check input dram parameter structure */
528 if (!para)
529 return 0;
530
531 /* setup DRAM relative clock */
Siarhei Siamashka586757a2014-08-03 05:32:47 +0300532 mctl_setup_dram_clock(para->clock, para->mbus_clock);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100533
Hans de Goede8c1c7822014-06-09 11:36:58 +0200534 /* Disable any pad power save control */
Siarhei Siamashka551bfb92014-08-03 05:32:40 +0300535 mctl_disable_power_save();
Hans de Goede8c1c7822014-06-09 11:36:58 +0200536
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100537 mctl_set_drive();
538
539 /* dram clock off */
540 dramc_clock_output_en(0);
541
Hans de Goede3ab9c232014-06-09 11:36:57 +0200542#ifdef CONFIG_SUN4I
543 /* select dram controller 1 */
544 writel(DRAM_CSEL_MAGIC, &dram->csel);
545#endif
546
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100547 mctl_itm_disable();
548 mctl_enable_dll0(para->tpr3);
549
550 /* configure external DRAM */
551 reg_val = 0x0;
552 if (para->type == DRAM_MEMORY_TYPE_DDR3)
553 reg_val |= DRAM_DCR_TYPE_DDR3;
554 reg_val |= DRAM_DCR_IO_WIDTH(para->io_width >> 3);
555
556 if (para->density == 256)
557 density = DRAM_DCR_CHIP_DENSITY_256M;
558 else if (para->density == 512)
559 density = DRAM_DCR_CHIP_DENSITY_512M;
560 else if (para->density == 1024)
561 density = DRAM_DCR_CHIP_DENSITY_1024M;
562 else if (para->density == 2048)
563 density = DRAM_DCR_CHIP_DENSITY_2048M;
564 else if (para->density == 4096)
565 density = DRAM_DCR_CHIP_DENSITY_4096M;
566 else if (para->density == 8192)
567 density = DRAM_DCR_CHIP_DENSITY_8192M;
568 else
569 density = DRAM_DCR_CHIP_DENSITY_256M;
570
571 reg_val |= DRAM_DCR_CHIP_DENSITY(density);
572 reg_val |= DRAM_DCR_BUS_WIDTH((para->bus_width >> 3) - 1);
573 reg_val |= DRAM_DCR_RANK_SEL(para->rank_num - 1);
574 reg_val |= DRAM_DCR_CMD_RANK_ALL;
575 reg_val |= DRAM_DCR_MODE(DRAM_DCR_MODE_INTERLEAVE);
576 writel(reg_val, &dram->dcr);
577
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100578 dramc_clock_output_en(1);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100579
Siarhei Siamashka3ad063a2014-08-03 05:32:46 +0300580 mctl_set_impedance(para->zq, para->odt_en);
581
Siarhei Siamashkace4d21c2014-08-03 05:32:42 +0300582 mctl_set_cke_delay();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100583
Siarhei Siamashka551bfb92014-08-03 05:32:40 +0300584 mctl_ddr3_reset();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100585
586 udelay(1);
587
Siarhei Siamashka72ed8692014-08-03 05:32:45 +0300588 await_bits_clear(&dram->ccr, DRAM_CCR_INIT);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100589
590 mctl_enable_dllx(para->tpr3);
591
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100592 /* set refresh period */
593 dramc_set_autorefresh_cycle(para->clock, para->type - 2, density);
594
595 /* set timing parameters */
596 writel(para->tpr0, &dram->tpr0);
597 writel(para->tpr1, &dram->tpr1);
598 writel(para->tpr2, &dram->tpr2);
599
600 if (para->type == DRAM_MEMORY_TYPE_DDR3) {
601 reg_val = DRAM_MR_BURST_LENGTH(0x0);
602#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I))
603 reg_val |= DRAM_MR_POWER_DOWN;
604#endif
605 reg_val |= DRAM_MR_CAS_LAT(para->cas - 4);
606 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
607 } else if (para->type == DRAM_MEMORY_TYPE_DDR2) {
608 reg_val = DRAM_MR_BURST_LENGTH(0x2);
609 reg_val |= DRAM_MR_CAS_LAT(para->cas);
610 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
611 }
612 writel(reg_val, &dram->mr);
613
614 writel(para->emr1, &dram->emr);
615 writel(para->emr2, &dram->emr2);
616 writel(para->emr3, &dram->emr3);
617
618 /* set DQS window mode */
619 clrsetbits_le32(&dram->ccr, DRAM_CCR_DQS_DRIFT_COMP, DRAM_CCR_DQS_GATE);
620
621#ifdef CONFIG_SUN7I
622 /* Command rate timing mode 2T & 1T */
623 if (para->tpr4 & 0x1)
624 setbits_le32(&dram->ccr, DRAM_CCR_COMMAND_RATE_1T);
625#endif
Siarhei Siamashkace4d21c2014-08-03 05:32:42 +0300626 /* initialize external DRAM */
627 mctl_ddr3_initialize();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100628
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100629 /* scan read pipe value */
630 mctl_itm_enable();
Siarhei Siamashka27942f12014-08-03 05:32:39 +0300631 ret_val = dramc_scan_readpipe();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100632
633 if (ret_val < 0)
634 return 0;
635
636 /* configure all host port */
637 mctl_configure_hostport();
638
639 return get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE);
640}