blob: 47017d2df18bf1a4c4b9ef3709823694db118cae [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 */
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100360 clrbits_le32(&dram->csr, DRAM_CSR_FAILED);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100361 setbits_le32(&dram->ccr, DRAM_CCR_DATA_TRAINING);
362
363 /* check whether data training process has completed */
Siarhei Siamashka72ed8692014-08-03 05:32:45 +0300364 await_bits_clear(&dram->ccr, DRAM_CCR_DATA_TRAINING);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100365
366 /* check data training result */
367 reg_val = readl(&dram->csr);
368 if (reg_val & DRAM_CSR_FAILED)
369 return -1;
370
371 return 0;
372}
373
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100374static void dramc_clock_output_en(u32 on)
375{
376#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)
377 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
378
379 if (on)
380 setbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
381 else
382 clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT);
383#endif
Hans de Goede3ab9c232014-06-09 11:36:57 +0200384#ifdef CONFIG_SUN4I
385 struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
386 if (on)
387 setbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
388 else
389 clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT);
390#endif
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100391}
392
393static const u16 tRFC_table[2][6] = {
394 /* 256Mb 512Mb 1Gb 2Gb 4Gb 8Gb */
395 /* DDR2 75ns 105ns 127.5ns 195ns 327.5ns invalid */
396 { 77, 108, 131, 200, 336, 336 },
397 /* DDR3 invalid 90ns 110ns 160ns 300ns 350ns */
398 { 93, 93, 113, 164, 308, 359 }
399};
400
401static void dramc_set_autorefresh_cycle(u32 clk, u32 type, u32 density)
402{
403 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
404 u32 tRFC, tREFI;
405
406 tRFC = (tRFC_table[type][density] * clk + 1023) >> 10;
407 tREFI = (7987 * clk) >> 10; /* <= 7.8us */
408
409 writel(DRAM_DRR_TREFI(tREFI) | DRAM_DRR_TRFC(tRFC), &dram->drr);
410}
411
Siarhei Siamashka551bfb92014-08-03 05:32:40 +0300412/*
413 * If the dram->ppwrsctl (SDR_DPCR) register has the lowest bit set to 1, this
414 * means that DRAM is currently in self-refresh mode and retaining the old
415 * data. Since we have no idea what to do in this situation yet, just set this
416 * register to 0 and initialize DRAM in the same way as on any normal reboot
417 * (discarding whatever was stored there).
418 *
419 * Note: on sun7i hardware, the highest 16 bits need to be set to 0x1651 magic
420 * value for this write operation to have any effect. On sun5i hadware this
421 * magic value is not necessary. And on sun4i hardware the writes to this
422 * register seem to have no effect at all.
423 */
424static void mctl_disable_power_save(void)
425{
426 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
427 writel(0x16510000, &dram->ppwrsctl);
428}
429
Siarhei Siamashkace4d21c2014-08-03 05:32:42 +0300430/*
431 * After the DRAM is powered up or reset, the DDR3 spec requires to wait at
432 * least 500 us before driving the CKE pin (Clock Enable) high. The dram->idct
433 * (SDR_IDCR) register appears to configure this delay, which gets applied
434 * right at the time when the DRAM initialization is activated in the
435 * 'mctl_ddr3_initialize' function.
436 */
437static void mctl_set_cke_delay(void)
438{
439 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
440
441 /* The CKE delay is represented in DRAM clock cycles, multiplied by N
442 * (where N=2 for sun4i/sun5i and N=3 for sun7i). Here it is set to
443 * the maximum possible value 0x1ffff, just like in the Allwinner's
444 * boot0 bootloader. The resulting delay value is somewhere between
445 * ~0.4 ms (sun5i with 648 MHz DRAM clock speed) and ~1.1 ms (sun7i
446 * with 360 MHz DRAM clock speed). */
447 setbits_le32(&dram->idcr, 0x1ffff);
448}
449
450/*
451 * This triggers the DRAM initialization. It performs sending the mode registers
452 * to the DRAM among other things. Very likely the ZQCL command is also getting
453 * executed (to do the initial impedance calibration on the DRAM side of the
454 * wire). The memory controller and the PHY must be already configured before
455 * calling this function.
456 */
457static void mctl_ddr3_initialize(void)
458{
459 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
460 setbits_le32(&dram->ccr, DRAM_CCR_INIT);
Siarhei Siamashka72ed8692014-08-03 05:32:45 +0300461 await_bits_clear(&dram->ccr, DRAM_CCR_INIT);
Siarhei Siamashkace4d21c2014-08-03 05:32:42 +0300462}
463
Siarhei Siamashka3ad063a2014-08-03 05:32:46 +0300464/*
465 * Perform impedance calibration on the DRAM controller side of the wire.
466 */
467static void mctl_set_impedance(u32 zq, u32 odt_en)
468{
469 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
470 u32 reg_val;
471 u32 zprog = zq & 0xFF, zdata = (zq >> 8) & 0xFFFFF;
472
473#ifndef CONFIG_SUN7I
474 /* Appears that some kind of automatically initiated default
475 * ZQ calibration is already in progress at this point on sun4i/sun5i
476 * hardware, but not on sun7i. So it is reasonable to wait for its
477 * completion before doing anything else. */
478 await_bits_set(&dram->zqsr, DRAM_ZQSR_ZDONE);
479#endif
480
481 /* ZQ calibration is not really useful unless ODT is enabled */
482 if (!odt_en)
483 return;
484
485#ifdef CONFIG_SUN7I
486 /* Enabling ODT in SDR_IOCR on sun7i hardware results in a deadlock
487 * unless bit 24 is set in SDR_ZQCR1. Not much is known about the
488 * SDR_ZQCR1 register, but there are hints indicating that it might
489 * be related to periodic impedance re-calibration. This particular
490 * magic value is borrowed from the Allwinner boot0 bootloader, and
491 * using it helps to avoid troubles */
492 writel((1 << 24) | (1 << 1), &dram->zqcr1);
493#endif
494
495 /* Needed at least for sun5i, because it does not self clear there */
496 clrbits_le32(&dram->zqcr0, DRAM_ZQCR0_ZCAL);
497
498 if (zdata) {
499 /* Set the user supplied impedance data */
500 reg_val = DRAM_ZQCR0_ZDEN | zdata;
501 writel(reg_val, &dram->zqcr0);
502 /* no need to wait, this takes effect immediately */
503 } else {
504 /* Do the calibration using the external resistor */
505 reg_val = DRAM_ZQCR0_ZCAL | DRAM_ZQCR0_IMP_DIV(zprog);
506 writel(reg_val, &dram->zqcr0);
507 /* Wait for the new impedance configuration to settle */
508 await_bits_set(&dram->zqsr, DRAM_ZQSR_ZDONE);
509 }
510
511 /* Needed at least for sun5i, because it does not self clear there */
512 clrbits_le32(&dram->zqcr0, DRAM_ZQCR0_ZCAL);
513
514 /* Set I/O configure register */
515 writel(DRAM_IOCR_ODT_EN(odt_en), &dram->iocr);
516}
517
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100518unsigned long dramc_init(struct dram_para *para)
519{
520 struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
521 u32 reg_val;
522 u32 density;
523 int ret_val;
524
525 /* check input dram parameter structure */
526 if (!para)
527 return 0;
528
529 /* setup DRAM relative clock */
Siarhei Siamashka586757a2014-08-03 05:32:47 +0300530 mctl_setup_dram_clock(para->clock, para->mbus_clock);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100531
Hans de Goede8c1c7822014-06-09 11:36:58 +0200532 /* Disable any pad power save control */
Siarhei Siamashka551bfb92014-08-03 05:32:40 +0300533 mctl_disable_power_save();
Hans de Goede8c1c7822014-06-09 11:36:58 +0200534
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100535 mctl_set_drive();
536
537 /* dram clock off */
538 dramc_clock_output_en(0);
539
Hans de Goede3ab9c232014-06-09 11:36:57 +0200540#ifdef CONFIG_SUN4I
541 /* select dram controller 1 */
542 writel(DRAM_CSEL_MAGIC, &dram->csel);
543#endif
544
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100545 mctl_itm_disable();
546 mctl_enable_dll0(para->tpr3);
547
548 /* configure external DRAM */
549 reg_val = 0x0;
550 if (para->type == DRAM_MEMORY_TYPE_DDR3)
551 reg_val |= DRAM_DCR_TYPE_DDR3;
552 reg_val |= DRAM_DCR_IO_WIDTH(para->io_width >> 3);
553
554 if (para->density == 256)
555 density = DRAM_DCR_CHIP_DENSITY_256M;
556 else if (para->density == 512)
557 density = DRAM_DCR_CHIP_DENSITY_512M;
558 else if (para->density == 1024)
559 density = DRAM_DCR_CHIP_DENSITY_1024M;
560 else if (para->density == 2048)
561 density = DRAM_DCR_CHIP_DENSITY_2048M;
562 else if (para->density == 4096)
563 density = DRAM_DCR_CHIP_DENSITY_4096M;
564 else if (para->density == 8192)
565 density = DRAM_DCR_CHIP_DENSITY_8192M;
566 else
567 density = DRAM_DCR_CHIP_DENSITY_256M;
568
569 reg_val |= DRAM_DCR_CHIP_DENSITY(density);
570 reg_val |= DRAM_DCR_BUS_WIDTH((para->bus_width >> 3) - 1);
571 reg_val |= DRAM_DCR_RANK_SEL(para->rank_num - 1);
572 reg_val |= DRAM_DCR_CMD_RANK_ALL;
573 reg_val |= DRAM_DCR_MODE(DRAM_DCR_MODE_INTERLEAVE);
574 writel(reg_val, &dram->dcr);
575
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100576 dramc_clock_output_en(1);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100577
Siarhei Siamashka3ad063a2014-08-03 05:32:46 +0300578 mctl_set_impedance(para->zq, para->odt_en);
579
Siarhei Siamashkace4d21c2014-08-03 05:32:42 +0300580 mctl_set_cke_delay();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100581
Siarhei Siamashka551bfb92014-08-03 05:32:40 +0300582 mctl_ddr3_reset();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100583
584 udelay(1);
585
Siarhei Siamashka72ed8692014-08-03 05:32:45 +0300586 await_bits_clear(&dram->ccr, DRAM_CCR_INIT);
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100587
588 mctl_enable_dllx(para->tpr3);
589
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100590 /* set refresh period */
591 dramc_set_autorefresh_cycle(para->clock, para->type - 2, density);
592
593 /* set timing parameters */
594 writel(para->tpr0, &dram->tpr0);
595 writel(para->tpr1, &dram->tpr1);
596 writel(para->tpr2, &dram->tpr2);
597
598 if (para->type == DRAM_MEMORY_TYPE_DDR3) {
599 reg_val = DRAM_MR_BURST_LENGTH(0x0);
600#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I))
601 reg_val |= DRAM_MR_POWER_DOWN;
602#endif
603 reg_val |= DRAM_MR_CAS_LAT(para->cas - 4);
604 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
605 } else if (para->type == DRAM_MEMORY_TYPE_DDR2) {
606 reg_val = DRAM_MR_BURST_LENGTH(0x2);
607 reg_val |= DRAM_MR_CAS_LAT(para->cas);
608 reg_val |= DRAM_MR_WRITE_RECOVERY(0x5);
609 }
610 writel(reg_val, &dram->mr);
611
612 writel(para->emr1, &dram->emr);
613 writel(para->emr2, &dram->emr2);
614 writel(para->emr3, &dram->emr3);
615
616 /* set DQS window mode */
617 clrsetbits_le32(&dram->ccr, DRAM_CCR_DQS_DRIFT_COMP, DRAM_CCR_DQS_GATE);
618
619#ifdef CONFIG_SUN7I
620 /* Command rate timing mode 2T & 1T */
621 if (para->tpr4 & 0x1)
622 setbits_le32(&dram->ccr, DRAM_CCR_COMMAND_RATE_1T);
623#endif
Siarhei Siamashkace4d21c2014-08-03 05:32:42 +0300624 /* initialize external DRAM */
625 mctl_ddr3_initialize();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100626
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100627 /* scan read pipe value */
628 mctl_itm_enable();
Siarhei Siamashka27942f12014-08-03 05:32:39 +0300629 ret_val = dramc_scan_readpipe();
Ian Campbell2f1afcc2014-05-05 11:52:25 +0100630
631 if (ret_val < 0)
632 return 0;
633
634 /* configure all host port */
635 mctl_configure_hostport();
636
637 return get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE);
638}