blob: 30483913b3544d3926c8779101bf3314d817e958 [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
Siarhei Siamashkac4f0aa52014-08-03 05:32:50 +0300155/* Get the number of DDR byte lanes */
156static u32 mctl_get_number_of_lanes(void)
157{
158 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
159 if ((readl(&dram->dcr) & DRAM_DCR_BUS_WIDTH_MASK) ==
160 DRAM_DCR_BUS_WIDTH(DRAM_DCR_BUS_WIDTH_32BIT))
161 return 4;
162 else
163 return 2;
164}
165
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100166/*
167 * Note: This differs from pm/standby in that it checks the bus width
168 */
169static void mctl_enable_dllx(u32 phase)
170{
171 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
Siarhei Siamashkac4f0aa52014-08-03 05:32:50 +0300172 u32 i, number_of_lanes;
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100173
Siarhei Siamashkac4f0aa52014-08-03 05:32:50 +0300174 number_of_lanes = mctl_get_number_of_lanes();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100175
Siarhei Siamashkac4f0aa52014-08-03 05:32:50 +0300176 for (i = 1; i <= number_of_lanes; i++) {
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100177 clrsetbits_le32(&dram->dllcr[i], 0xf << 14,
178 (phase & 0xf) << 14);
179 clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET,
180 DRAM_DLLCR_DISABLE);
181 phase >>= 4;
182 }
183 udelay(2);
184
Siarhei Siamashkac4f0aa52014-08-03 05:32:50 +0300185 for (i = 1; i <= number_of_lanes; i++)
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100186 clrbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET |
187 DRAM_DLLCR_DISABLE);
188 udelay(22);
189
Siarhei Siamashkac4f0aa52014-08-03 05:32:50 +0300190 for (i = 1; i <= number_of_lanes; i++)
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100191 clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_DISABLE,
192 DRAM_DLLCR_NRESET);
193 udelay(22);
194}
195
196static u32 hpcr_value[32] = {
Hans de Goede8c1c7822014-06-09 11:36:58 +0200197#ifdef CONFIG_SUN5I
198 0, 0, 0, 0,
199 0, 0, 0, 0,
200 0, 0, 0, 0,
201 0, 0, 0, 0,
202 0x1031, 0x1031, 0x0735, 0x1035,
203 0x1035, 0x0731, 0x1031, 0,
204 0x0301, 0x0301, 0x0301, 0x0301,
205 0x0301, 0x0301, 0x0301, 0
206#endif
Hans de Goede3ab9c232014-06-09 11:36:57 +0200207#ifdef CONFIG_SUN4I
208 0x0301, 0x0301, 0x0301, 0x0301,
209 0x0301, 0x0301, 0, 0,
210 0, 0, 0, 0,
211 0, 0, 0, 0,
212 0x1031, 0x1031, 0x0735, 0x5031,
213 0x1035, 0x0731, 0x1031, 0x0735,
214 0x1035, 0x1031, 0x0731, 0x1035,
215 0x1031, 0x0301, 0x0301, 0x0731
216#endif
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100217#ifdef CONFIG_SUN7I
218 0x0301, 0x0301, 0x0301, 0x0301,
219 0x0301, 0x0301, 0x0301, 0x0301,
220 0, 0, 0, 0,
221 0, 0, 0, 0,
222 0x1031, 0x1031, 0x0735, 0x1035,
223 0x1035, 0x0731, 0x1031, 0x0735,
224 0x1035, 0x1031, 0x0731, 0x1035,
225 0x0001, 0x1031, 0, 0x1031
226 /* last row differs from boot0 source table
227 * 0x1031, 0x0301, 0x0301, 0x0731
228 * but boot0 code skips #28 and #30, and sets #29 and #31 to the
229 * value from #28 entry (0x1031)
230 */
231#endif
232};
233
234static void mctl_configure_hostport(void)
235{
236 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
237 u32 i;
238
239 for (i = 0; i < 32; i++)
240 writel(hpcr_value[i], &dram->hpcr[i]);
241}
242
Siarhei Siamashka586757a2014-08-03 05:32:47 +0300243static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk)
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100244{
245 u32 reg_val;
246 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
247
Siarhei Siamashka586757a2014-08-03 05:32:47 +0300248 /* PLL5P and PLL6 are the potential clock sources for MBUS */
249 u32 pll6x_div, pll5p_div;
250 u32 pll6x_clk = clock_get_pll6() / 1000000;
Siarhei Siamashka020a6342014-08-03 05:32:48 +0300251 u32 pll5p_clk = clk / 24 * 48;
Siarhei Siamashka586757a2014-08-03 05:32:47 +0300252 u32 pll5p_rate, pll6x_rate;
253#ifdef CONFIG_SUN7I
254 pll6x_clk *= 2; /* sun7i uses PLL6*2, sun5i uses just PLL6 */
255#endif
256
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100257 /* setup DRAM PLL */
258 reg_val = readl(&ccm->pll5_cfg);
259 reg_val &= ~CCM_PLL5_CTRL_M_MASK; /* set M to 0 (x1) */
260 reg_val &= ~CCM_PLL5_CTRL_K_MASK; /* set K to 0 (x1) */
261 reg_val &= ~CCM_PLL5_CTRL_N_MASK; /* set N to 0 (x0) */
262 reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */
263 if (clk >= 540 && clk < 552) {
Siarhei Siamashka020a6342014-08-03 05:32:48 +0300264 /* dram = 540MHz, pll5p = 1080MHz */
265 pll5p_clk = 1080;
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100266 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
267 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
268 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(15));
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100269 } else if (clk >= 512 && clk < 528) {
Siarhei Siamashka020a6342014-08-03 05:32:48 +0300270 /* dram = 512MHz, pll5p = 1536MHz */
271 pll5p_clk = 1536;
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100272 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
273 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(4));
274 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(16));
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100275 } else if (clk >= 496 && clk < 504) {
Siarhei Siamashka020a6342014-08-03 05:32:48 +0300276 /* dram = 496MHz, pll5p = 1488MHz */
277 pll5p_clk = 1488;
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100278 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3));
279 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
280 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(31));
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100281 } else if (clk >= 468 && clk < 480) {
Siarhei Siamashka020a6342014-08-03 05:32:48 +0300282 /* dram = 468MHz, pll5p = 936MHz */
283 pll5p_clk = 936;
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100284 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
285 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
286 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(13));
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100287 } else if (clk >= 396 && clk < 408) {
Siarhei Siamashka020a6342014-08-03 05:32:48 +0300288 /* dram = 396MHz, pll5p = 792MHz */
289 pll5p_clk = 792;
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100290 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
291 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3));
292 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(11));
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100293 } else {
294 /* any other frequency that is a multiple of 24 */
295 reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2));
296 reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2));
297 reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24));
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100298 }
299 reg_val &= ~CCM_PLL5_CTRL_VCO_GAIN; /* PLL VCO Gain off */
300 reg_val |= CCM_PLL5_CTRL_EN; /* PLL On */
301 writel(reg_val, &ccm->pll5_cfg);
302 udelay(5500);
303
304 setbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_DDR_CLK);
305
306#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)
307 /* reset GPS */
308 clrbits_le32(&ccm->gps_clk_cfg, CCM_GPS_CTRL_RESET | CCM_GPS_CTRL_GATE);
309 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
310 udelay(1);
311 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS);
312#endif
313
314 /* setup MBUS clock */
Siarhei Siamashka586757a2014-08-03 05:32:47 +0300315 if (!mbus_clk)
316 mbus_clk = 300;
317 pll6x_div = DIV_ROUND_UP(pll6x_clk, mbus_clk);
318 pll5p_div = DIV_ROUND_UP(pll5p_clk, mbus_clk);
319 pll6x_rate = pll6x_clk / pll6x_div;
320 pll5p_rate = pll5p_clk / pll5p_div;
321
322 if (pll6x_div <= 16 && pll6x_rate > pll5p_rate) {
323 /* use PLL6 as the MBUS clock source */
324 reg_val = CCM_MBUS_CTRL_GATE |
325 CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) |
326 CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(1)) |
327 CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(pll6x_div));
328 } else if (pll5p_div <= 16) {
329 /* use PLL5P as the MBUS clock source */
330 reg_val = CCM_MBUS_CTRL_GATE |
331 CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL5) |
332 CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(1)) |
333 CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(pll5p_div));
334 } else {
335 panic("Bad mbus_clk\n");
336 }
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100337 writel(reg_val, &ccm->mbus_clk_cfg);
338
339 /*
340 * open DRAMC AHB & DLL register clock
341 * close it first
342 */
Hans de Goede3ab9c232014-06-09 11:36:57 +0200343#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100344 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
Hans de Goede3ab9c232014-06-09 11:36:57 +0200345#else
346 clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
347#endif
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100348 udelay(22);
349
350 /* then open it */
Hans de Goede3ab9c232014-06-09 11:36:57 +0200351#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100352 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL);
Hans de Goede3ab9c232014-06-09 11:36:57 +0200353#else
354 setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM);
355#endif
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100356 udelay(22);
357}
358
359static int dramc_scan_readpipe(void)
360{
361 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
362 u32 reg_val;
363
364 /* data training trigger */
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100365 clrbits_le32(&dram->csr, DRAM_CSR_FAILED);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100366 setbits_le32(&dram->ccr, DRAM_CCR_DATA_TRAINING);
367
368 /* check whether data training process has completed */
Siarhei Siamashka72ed8692014-08-03 05:32:45 +0300369 await_bits_clear(&dram->ccr, DRAM_CCR_DATA_TRAINING);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100370
371 /* check data training result */
372 reg_val = readl(&dram->csr);
373 if (reg_val & DRAM_CSR_FAILED)
374 return -1;
375
376 return 0;
377}
378
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100379static void dramc_clock_output_en(u32 on)
380{
381#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
382 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
383
384 if (on)
385 setbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
386 else
387 clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
388#endif
Hans de Goede3ab9c232014-06-09 11:36:57 +0200389#ifdef CONFIG_SUN4I
390 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
391 if (on)
392 setbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
393 else
394 clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
395#endif
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100396}
397
398static const u16 tRFC_table[2][6] = {
399 /* 256Mb 512Mb 1Gb 2Gb 4Gb 8Gb */
400 /* DDR2 75ns 105ns 127.5ns 195ns 327.5ns invalid */
401 { 77, 108, 131, 200, 336, 336 },
402 /* DDR3 invalid 90ns 110ns 160ns 300ns 350ns */
403 { 93, 93, 113, 164, 308, 359 }
404};
405
406static void dramc_set_autorefresh_cycle(u32 clk, u32 type, u32 density)
407{
408 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
409 u32 tRFC, tREFI;
410
411 tRFC = (tRFC_table[type][density] * clk + 1023) >> 10;
412 tREFI = (7987 * clk) >> 10; /* <= 7.8us */
413
414 writel(DRAM_DRR_TREFI(tREFI) | DRAM_DRR_TRFC(tRFC), &dram->drr);
415}
416
Siarhei Siamashka551bfb92014-08-03 05:32:40 +0300417/*
418 * If the dram->ppwrsctl (SDR_DPCR) register has the lowest bit set to 1, this
419 * means that DRAM is currently in self-refresh mode and retaining the old
420 * data. Since we have no idea what to do in this situation yet, just set this
421 * register to 0 and initialize DRAM in the same way as on any normal reboot
422 * (discarding whatever was stored there).
423 *
424 * Note: on sun7i hardware, the highest 16 bits need to be set to 0x1651 magic
425 * value for this write operation to have any effect. On sun5i hadware this
426 * magic value is not necessary. And on sun4i hardware the writes to this
427 * register seem to have no effect at all.
428 */
429static void mctl_disable_power_save(void)
430{
431 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
432 writel(0x16510000, &dram->ppwrsctl);
433}
434
Siarhei Siamashkace4d21c2014-08-03 05:32:42 +0300435/*
436 * After the DRAM is powered up or reset, the DDR3 spec requires to wait at
437 * least 500 us before driving the CKE pin (Clock Enable) high. The dram->idct
438 * (SDR_IDCR) register appears to configure this delay, which gets applied
439 * right at the time when the DRAM initialization is activated in the
440 * 'mctl_ddr3_initialize' function.
441 */
442static void mctl_set_cke_delay(void)
443{
444 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
445
446 /* The CKE delay is represented in DRAM clock cycles, multiplied by N
447 * (where N=2 for sun4i/sun5i and N=3 for sun7i). Here it is set to
448 * the maximum possible value 0x1ffff, just like in the Allwinner's
449 * boot0 bootloader. The resulting delay value is somewhere between
450 * ~0.4 ms (sun5i with 648 MHz DRAM clock speed) and ~1.1 ms (sun7i
451 * with 360 MHz DRAM clock speed). */
452 setbits_le32(&dram->idcr, 0x1ffff);
453}
454
455/*
456 * This triggers the DRAM initialization. It performs sending the mode registers
457 * to the DRAM among other things. Very likely the ZQCL command is also getting
458 * executed (to do the initial impedance calibration on the DRAM side of the
459 * wire). The memory controller and the PHY must be already configured before
460 * calling this function.
461 */
462static void mctl_ddr3_initialize(void)
463{
464 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
465 setbits_le32(&dram->ccr, DRAM_CCR_INIT);
Siarhei Siamashka72ed8692014-08-03 05:32:45 +0300466 await_bits_clear(&dram->ccr, DRAM_CCR_INIT);
Siarhei Siamashkace4d21c2014-08-03 05:32:42 +0300467}
468
Siarhei Siamashka3ad063a2014-08-03 05:32:46 +0300469/*
470 * Perform impedance calibration on the DRAM controller side of the wire.
471 */
472static void mctl_set_impedance(u32 zq, u32 odt_en)
473{
474 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
475 u32 reg_val;
476 u32 zprog = zq & 0xFF, zdata = (zq >> 8) & 0xFFFFF;
477
478#ifndef CONFIG_SUN7I
479 /* Appears that some kind of automatically initiated default
480 * ZQ calibration is already in progress at this point on sun4i/sun5i
481 * hardware, but not on sun7i. So it is reasonable to wait for its
482 * completion before doing anything else. */
483 await_bits_set(&dram->zqsr, DRAM_ZQSR_ZDONE);
484#endif
485
486 /* ZQ calibration is not really useful unless ODT is enabled */
487 if (!odt_en)
488 return;
489
490#ifdef CONFIG_SUN7I
491 /* Enabling ODT in SDR_IOCR on sun7i hardware results in a deadlock
492 * unless bit 24 is set in SDR_ZQCR1. Not much is known about the
493 * SDR_ZQCR1 register, but there are hints indicating that it might
494 * be related to periodic impedance re-calibration. This particular
495 * magic value is borrowed from the Allwinner boot0 bootloader, and
496 * using it helps to avoid troubles */
497 writel((1 << 24) | (1 << 1), &dram->zqcr1);
498#endif
499
500 /* Needed at least for sun5i, because it does not self clear there */
501 clrbits_le32(&dram->zqcr0, DRAM_ZQCR0_ZCAL);
502
503 if (zdata) {
504 /* Set the user supplied impedance data */
505 reg_val = DRAM_ZQCR0_ZDEN | zdata;
506 writel(reg_val, &dram->zqcr0);
507 /* no need to wait, this takes effect immediately */
508 } else {
509 /* Do the calibration using the external resistor */
510 reg_val = DRAM_ZQCR0_ZCAL | DRAM_ZQCR0_IMP_DIV(zprog);
511 writel(reg_val, &dram->zqcr0);
512 /* Wait for the new impedance configuration to settle */
513 await_bits_set(&dram->zqsr, DRAM_ZQSR_ZDONE);
514 }
515
516 /* Needed at least for sun5i, because it does not self clear there */
517 clrbits_le32(&dram->zqcr0, DRAM_ZQCR0_ZCAL);
518
519 /* Set I/O configure register */
520 writel(DRAM_IOCR_ODT_EN(odt_en), &dram->iocr);
521}
522
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100523unsigned long dramc_init(struct dram_para *para)
524{
525 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
526 u32 reg_val;
527 u32 density;
528 int ret_val;
529
530 /* check input dram parameter structure */
531 if (!para)
532 return 0;
533
534 /* setup DRAM relative clock */
Siarhei Siamashka586757a2014-08-03 05:32:47 +0300535 mctl_setup_dram_clock(para->clock, para->mbus_clock);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100536
Hans de Goede8c1c7822014-06-09 11:36:58 +0200537 /* Disable any pad power save control */
Siarhei Siamashka551bfb92014-08-03 05:32:40 +0300538 mctl_disable_power_save();
Hans de Goede8c1c7822014-06-09 11:36:58 +0200539
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100540 mctl_set_drive();
541
542 /* dram clock off */
543 dramc_clock_output_en(0);
544
Hans de Goede3ab9c232014-06-09 11:36:57 +0200545#ifdef CONFIG_SUN4I
546 /* select dram controller 1 */
547 writel(DRAM_CSEL_MAGIC, &dram->csel);
548#endif
549
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100550 mctl_itm_disable();
551 mctl_enable_dll0(para->tpr3);
552
553 /* configure external DRAM */
554 reg_val = 0x0;
555 if (para->type == DRAM_MEMORY_TYPE_DDR3)
556 reg_val |= DRAM_DCR_TYPE_DDR3;
557 reg_val |= DRAM_DCR_IO_WIDTH(para->io_width >> 3);
558
559 if (para->density == 256)
560 density = DRAM_DCR_CHIP_DENSITY_256M;
561 else if (para->density == 512)
562 density = DRAM_DCR_CHIP_DENSITY_512M;
563 else if (para->density == 1024)
564 density = DRAM_DCR_CHIP_DENSITY_1024M;
565 else if (para->density == 2048)
566 density = DRAM_DCR_CHIP_DENSITY_2048M;
567 else if (para->density == 4096)
568 density = DRAM_DCR_CHIP_DENSITY_4096M;
569 else if (para->density == 8192)
570 density = DRAM_DCR_CHIP_DENSITY_8192M;
571 else
572 density = DRAM_DCR_CHIP_DENSITY_256M;
573
574 reg_val |= DRAM_DCR_CHIP_DENSITY(density);
575 reg_val |= DRAM_DCR_BUS_WIDTH((para->bus_width >> 3) - 1);
576 reg_val |= DRAM_DCR_RANK_SEL(para->rank_num - 1);
577 reg_val |= DRAM_DCR_CMD_RANK_ALL;
578 reg_val |= DRAM_DCR_MODE(DRAM_DCR_MODE_INTERLEAVE);
579 writel(reg_val, &dram->dcr);
580
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100581 dramc_clock_output_en(1);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100582
Siarhei Siamashka3ad063a2014-08-03 05:32:46 +0300583 mctl_set_impedance(para->zq, para->odt_en);
584
Siarhei Siamashkace4d21c2014-08-03 05:32:42 +0300585 mctl_set_cke_delay();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100586
Siarhei Siamashka551bfb92014-08-03 05:32:40 +0300587 mctl_ddr3_reset();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100588
589 udelay(1);
590
Siarhei Siamashka72ed8692014-08-03 05:32:45 +0300591 await_bits_clear(&dram->ccr, DRAM_CCR_INIT);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100592
593 mctl_enable_dllx(para->tpr3);
594
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100595 /* set refresh period */
596 dramc_set_autorefresh_cycle(para->clock, para->type - 2, density);
597
598 /* set timing parameters */
599 writel(para->tpr0, &dram->tpr0);
600 writel(para->tpr1, &dram->tpr1);
601 writel(para->tpr2, &dram->tpr2);
602
603 if (para->type == DRAM_MEMORY_TYPE_DDR3) {
604 reg_val = DRAM_MR_BURST_LENGTH(0x0);
605#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I))
606 reg_val |= DRAM_MR_POWER_DOWN;
607#endif
608 reg_val |= DRAM_MR_CAS_LAT(para->cas - 4);
609 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
610 } else if (para->type == DRAM_MEMORY_TYPE_DDR2) {
611 reg_val = DRAM_MR_BURST_LENGTH(0x2);
612 reg_val |= DRAM_MR_CAS_LAT(para->cas);
613 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
614 }
615 writel(reg_val, &dram->mr);
616
617 writel(para->emr1, &dram->emr);
618 writel(para->emr2, &dram->emr2);
619 writel(para->emr3, &dram->emr3);
620
621 /* set DQS window mode */
622 clrsetbits_le32(&dram->ccr, DRAM_CCR_DQS_DRIFT_COMP, DRAM_CCR_DQS_GATE);
623
624#ifdef CONFIG_SUN7I
625 /* Command rate timing mode 2T & 1T */
626 if (para->tpr4 & 0x1)
627 setbits_le32(&dram->ccr, DRAM_CCR_COMMAND_RATE_1T);
628#endif
Siarhei Siamashkace4d21c2014-08-03 05:32:42 +0300629 /* initialize external DRAM */
630 mctl_ddr3_initialize();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100631
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100632 /* scan read pipe value */
633 mctl_itm_enable();
Siarhei Siamashka27942f12014-08-03 05:32:39 +0300634 ret_val = dramc_scan_readpipe();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100635
636 if (ret_val < 0)
637 return 0;
638
639 /* configure all host port */
640 mctl_configure_hostport();
641
642 return get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE);
643}