]> git.sur5r.net Git - u-boot/blob - arch/arm/mach-sunxi/dram_sunxi_dw.c
sunxi: Add selective DRAM type and timing
[u-boot] / arch / arm / mach-sunxi / dram_sunxi_dw.c
1 /*
2  * sun8i H3 platform dram controller init
3  *
4  * (C) Copyright 2007-2015 Allwinner Technology Co.
5  *                         Jerry Wang <wangflord@allwinnertech.com>
6  * (C) Copyright 2015      Vishnu Patekar <vishnupatekar0510@gmail.com>
7  * (C) Copyright 2015      Hans de Goede <hdegoede@redhat.com>
8  * (C) Copyright 2015      Jens Kuske <jenskuske@gmail.com>
9  *
10  * SPDX-License-Identifier:     GPL-2.0+
11  */
12 #include <common.h>
13 #include <asm/io.h>
14 #include <asm/arch/clock.h>
15 #include <asm/arch/dram.h>
16 #include <asm/arch/cpu.h>
17 #include <linux/kconfig.h>
18
19 static void mctl_phy_init(u32 val)
20 {
21         struct sunxi_mctl_ctl_reg * const mctl_ctl =
22                         (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
23
24         writel(val | PIR_INIT, &mctl_ctl->pir);
25         mctl_await_completion(&mctl_ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
26 }
27
28 static void mctl_set_bit_delays(struct dram_para *para)
29 {
30         struct sunxi_mctl_ctl_reg * const mctl_ctl =
31                         (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
32         int i, j;
33
34         clrbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
35
36         for (i = 0; i < NR_OF_BYTE_LANES; i++)
37                 for (j = 0; j < LINES_PER_BYTE_LANE; j++)
38                         writel(DXBDLR_WRITE_DELAY(para->dx_write_delays[i][j]) |
39                                DXBDLR_READ_DELAY(para->dx_read_delays[i][j]),
40                                &mctl_ctl->dx[i].bdlr[j]);
41
42         for (i = 0; i < 31; i++)
43                 writel(ACBDLR_WRITE_DELAY(para->ac_delays[i]),
44                        &mctl_ctl->acbdlr[i]);
45
46 #ifdef CONFIG_MACH_SUN8I_R40
47         /* DQSn, DMn, DQn output enable bit delay */
48         for (i = 0; i < 4; i++)
49                 writel(0x6 << 24, &mctl_ctl->dx[i].sdlr);
50 #endif
51
52         setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
53 }
54
55 enum {
56         MBUS_PORT_CPU           = 0,
57         MBUS_PORT_GPU           = 1,
58         MBUS_PORT_UNUSED        = 2,
59         MBUS_PORT_DMA           = 3,
60         MBUS_PORT_VE            = 4,
61         MBUS_PORT_CSI           = 5,
62         MBUS_PORT_NAND          = 6,
63         MBUS_PORT_SS            = 7,
64         MBUS_PORT_TS            = 8,
65         MBUS_PORT_DI            = 9,
66         MBUS_PORT_DE            = 10,
67         MBUS_PORT_DE_CFD        = 11,
68         MBUS_PORT_UNKNOWN1      = 12,
69         MBUS_PORT_UNKNOWN2      = 13,
70         MBUS_PORT_UNKNOWN3      = 14,
71 };
72
73 enum {
74         MBUS_QOS_LOWEST = 0,
75         MBUS_QOS_LOW,
76         MBUS_QOS_HIGH,
77         MBUS_QOS_HIGHEST
78 };
79
80 inline void mbus_configure_port(u8 port,
81                                 bool bwlimit,
82                                 bool priority,
83                                 u8 qos,         /* MBUS_QOS_LOWEST .. MBUS_QOS_HIGEST */
84                                 u8 waittime,    /* 0 .. 0xf */
85                                 u8 acs,         /* 0 .. 0xff */
86                                 u16 bwl0,       /* 0 .. 0xffff, bandwidth limit in MB/s */
87                                 u16 bwl1,
88                                 u16 bwl2)
89 {
90         struct sunxi_mctl_com_reg * const mctl_com =
91                         (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
92
93         const u32 cfg0 = ( (bwlimit ? (1 << 0) : 0)
94                            | (priority ? (1 << 1) : 0)
95                            | ((qos & 0x3) << 2)
96                            | ((waittime & 0xf) << 4)
97                            | ((acs & 0xff) << 8)
98                            | (bwl0 << 16) );
99         const u32 cfg1 = ((u32)bwl2 << 16) | (bwl1 & 0xffff);
100
101         debug("MBUS port %d cfg0 %08x cfg1 %08x\n", port, cfg0, cfg1);
102         writel(cfg0, &mctl_com->mcr[port][0]);
103         writel(cfg1, &mctl_com->mcr[port][1]);
104 }
105
106 #define MBUS_CONF(port, bwlimit, qos, acs, bwl0, bwl1, bwl2)    \
107         mbus_configure_port(MBUS_PORT_ ## port, bwlimit, false, \
108                             MBUS_QOS_ ## qos, 0, acs, bwl0, bwl1, bwl2)
109
110 static void mctl_set_master_priority_h3(void)
111 {
112         struct sunxi_mctl_com_reg * const mctl_com =
113                         (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
114
115         /* enable bandwidth limit windows and set windows size 1us */
116         writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
117
118         /* set cpu high priority */
119         writel(0x00000001, &mctl_com->mapr);
120
121         MBUS_CONF(   CPU,  true, HIGHEST, 0,  512,  256,  128);
122         MBUS_CONF(   GPU,  true,    HIGH, 0, 1536, 1024,  256);
123         MBUS_CONF(UNUSED,  true, HIGHEST, 0,  512,  256,   96);
124         MBUS_CONF(   DMA,  true, HIGHEST, 0,  256,  128,   32);
125         MBUS_CONF(    VE,  true,    HIGH, 0, 1792, 1600,  256);
126         MBUS_CONF(   CSI,  true, HIGHEST, 0,  256,  128,   32);
127         MBUS_CONF(  NAND,  true,    HIGH, 0,  256,  128,   64);
128         MBUS_CONF(    SS,  true, HIGHEST, 0,  256,  128,   64);
129         MBUS_CONF(    TS,  true, HIGHEST, 0,  256,  128,   64);
130         MBUS_CONF(    DI,  true,    HIGH, 0, 1024,  256,   64);
131         MBUS_CONF(    DE,  true, HIGHEST, 3, 8192, 6120, 1024);
132         MBUS_CONF(DE_CFD,  true,    HIGH, 0, 1024,  288,   64);
133 }
134
135 static void mctl_set_master_priority_a64(void)
136 {
137         struct sunxi_mctl_com_reg * const mctl_com =
138                         (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
139
140         /* enable bandwidth limit windows and set windows size 1us */
141         writel(399, &mctl_com->tmr);
142         writel((1 << 16), &mctl_com->bwcr);
143
144         /* Port 2 is reserved per Allwinner's linux-3.10 source, yet they
145          * initialise it */
146         MBUS_CONF(   CPU,  true, HIGHEST, 0,  160,  100,   80);
147         MBUS_CONF(   GPU, false,    HIGH, 0, 1536, 1400,  256);
148         MBUS_CONF(UNUSED,  true, HIGHEST, 0,  512,  256,   96);
149         MBUS_CONF(   DMA,  true,    HIGH, 0,  256,   80,  100);
150         MBUS_CONF(    VE,  true,    HIGH, 0, 1792, 1600,  256);
151         MBUS_CONF(   CSI,  true,    HIGH, 0,  256,  128,    0);
152         MBUS_CONF(  NAND,  true,    HIGH, 0,  256,  128,   64);
153         MBUS_CONF(    SS,  true, HIGHEST, 0,  256,  128,   64);
154         MBUS_CONF(    TS,  true, HIGHEST, 0,  256,  128,   64);
155         MBUS_CONF(    DI,  true,    HIGH, 0, 1024,  256,   64);
156         MBUS_CONF(    DE,  true,    HIGH, 2, 8192, 6144, 2048);
157         MBUS_CONF(DE_CFD,  true,    HIGH, 0, 1280,  144,   64);
158
159         writel(0x81000004, &mctl_com->mdfs_bwlr[2]);
160 }
161
162 static void mctl_set_master_priority_h5(void)
163 {
164         struct sunxi_mctl_com_reg * const mctl_com =
165                         (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
166
167         /* enable bandwidth limit windows and set windows size 1us */
168         writel(399, &mctl_com->tmr);
169         writel((1 << 16), &mctl_com->bwcr);
170
171         /* set cpu high priority */
172         writel(0x00000001, &mctl_com->mapr);
173
174         /* Port 2 is reserved per Allwinner's linux-3.10 source, yet
175          * they initialise it */
176         MBUS_CONF(   CPU, true, HIGHEST, 0,  300,  260,  150);
177         MBUS_CONF(   GPU, true, HIGHEST, 0,  600,  400,  200);
178         MBUS_CONF(UNUSED, true, HIGHEST, 0,  512,  256,   96);
179         MBUS_CONF(   DMA, true, HIGHEST, 0,  256,  128,   32);
180         MBUS_CONF(    VE, true, HIGHEST, 0, 1900, 1500, 1000);
181         MBUS_CONF(   CSI, true, HIGHEST, 0,  150,  120,  100);
182         MBUS_CONF(  NAND, true,    HIGH, 0,  256,  128,   64);
183         MBUS_CONF(    SS, true, HIGHEST, 0,  256,  128,   64);
184         MBUS_CONF(    TS, true, HIGHEST, 0,  256,  128,   64);
185         MBUS_CONF(    DI, true,    HIGH, 0, 1024,  256,   64);
186         MBUS_CONF(    DE, true, HIGHEST, 3, 3400, 2400, 1024);
187         MBUS_CONF(DE_CFD, true, HIGHEST, 0,  600,  400,  200);
188 }
189
190 static void mctl_set_master_priority_r40(void)
191 {
192         struct sunxi_mctl_com_reg * const mctl_com =
193                         (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
194
195         /* enable bandwidth limit windows and set windows size 1us */
196         writel(399, &mctl_com->tmr);
197         writel((1 << 16), &mctl_com->bwcr);
198
199         /* set cpu high priority */
200         writel(0x00000001, &mctl_com->mapr);
201
202         /* Port 2 is reserved per Allwinner's linux-3.10 source, yet
203          * they initialise it */
204         MBUS_CONF(     CPU, true, HIGHEST, 0,  300,  260,  150);
205         MBUS_CONF(     GPU, true, HIGHEST, 0,  600,  400,  200);
206         MBUS_CONF(  UNUSED, true, HIGHEST, 0,  512,  256,   96);
207         MBUS_CONF(     DMA, true, HIGHEST, 0,  256,  128,   32);
208         MBUS_CONF(      VE, true, HIGHEST, 0, 1900, 1500, 1000);
209         MBUS_CONF(     CSI, true, HIGHEST, 0,  150,  120,  100);
210         MBUS_CONF(    NAND, true,    HIGH, 0,  256,  128,   64);
211         MBUS_CONF(      SS, true, HIGHEST, 0,  256,  128,   64);
212         MBUS_CONF(      TS, true, HIGHEST, 0,  256,  128,   64);
213         MBUS_CONF(      DI, true,    HIGH, 0, 1024,  256,   64);
214
215         /*
216          * The port names are probably wrong, but no correct sources
217          * are available.
218          */
219         MBUS_CONF(      DE, true,    HIGH, 0,  128,   48,    0);
220         MBUS_CONF(  DE_CFD, true,    HIGH, 0,  384,  256,    0);
221         MBUS_CONF(UNKNOWN1, true, HIGHEST, 0,  512,  384,  256);
222         MBUS_CONF(UNKNOWN2, true, HIGHEST, 2, 8192, 6144, 1024);
223         MBUS_CONF(UNKNOWN3, true,    HIGH, 0, 1280,  144,   64);
224 }
225
226 static void mctl_set_master_priority(uint16_t socid)
227 {
228         switch (socid) {
229         case SOCID_H3:
230                 mctl_set_master_priority_h3();
231                 return;
232         case SOCID_A64:
233                 mctl_set_master_priority_a64();
234                 return;
235         case SOCID_H5:
236                 mctl_set_master_priority_h5();
237                 return;
238         case SOCID_R40:
239                 mctl_set_master_priority_r40();
240                 return;
241         }
242 }
243
244 static u32 bin_to_mgray(int val)
245 {
246         static const u8 lookup_table[32] = {
247                 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
248                 0x0c, 0x0d, 0x0e, 0x0f, 0x0a, 0x0b, 0x08, 0x09,
249                 0x18, 0x19, 0x1a, 0x1b, 0x1e, 0x1f, 0x1c, 0x1d,
250                 0x14, 0x15, 0x16, 0x17, 0x12, 0x13, 0x10, 0x11,
251         };
252
253         return lookup_table[clamp(val, 0, 31)];
254 }
255
256 static int mgray_to_bin(u32 val)
257 {
258         static const u8 lookup_table[32] = {
259                 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
260                 0x0e, 0x0f, 0x0c, 0x0d, 0x08, 0x09, 0x0a, 0x0b,
261                 0x1e, 0x1f, 0x1c, 0x1d, 0x18, 0x19, 0x1a, 0x1b,
262                 0x10, 0x11, 0x12, 0x13, 0x16, 0x17, 0x14, 0x15,
263         };
264
265         return lookup_table[val & 0x1f];
266 }
267
268 static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
269 {
270         struct sunxi_mctl_ctl_reg * const mctl_ctl =
271                         (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
272         int zq_count;
273
274 #if defined CONFIG_SUNXI_DRAM_DW_16BIT
275         zq_count = 4;
276 #else
277         zq_count = 6;
278 #endif
279
280         if ((readl(SUNXI_SRAMC_BASE + 0x24) & 0xff) == 0 &&
281             (readl(SUNXI_SRAMC_BASE + 0xf0) & 0x1) == 0) {
282                 u32 reg_val;
283
284                 clrsetbits_le32(&mctl_ctl->zqcr, 0xffff,
285                                 CONFIG_DRAM_ZQ & 0xffff);
286
287                 writel(PIR_CLRSR, &mctl_ctl->pir);
288                 mctl_phy_init(PIR_ZCAL);
289
290                 reg_val = readl(&mctl_ctl->zqdr[0]);
291                 reg_val &= (0x1f << 16) | (0x1f << 0);
292                 reg_val |= reg_val << 8;
293                 writel(reg_val, &mctl_ctl->zqdr[0]);
294
295                 reg_val = readl(&mctl_ctl->zqdr[1]);
296                 reg_val &= (0x1f << 16) | (0x1f << 0);
297                 reg_val |= reg_val << 8;
298                 writel(reg_val, &mctl_ctl->zqdr[1]);
299                 writel(reg_val, &mctl_ctl->zqdr[2]);
300         } else {
301                 int i;
302                 u16 zq_val[6];
303                 u8 val;
304
305                 writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
306
307                 for (i = 0; i < zq_count; i++) {
308                         u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
309
310                         writel((zq << 20) | (zq << 16) | (zq << 12) |
311                                         (zq << 8) | (zq << 4) | (zq << 0),
312                                         &mctl_ctl->zqcr);
313
314                         writel(PIR_CLRSR, &mctl_ctl->pir);
315                         mctl_phy_init(PIR_ZCAL);
316
317                         zq_val[i] = readl(&mctl_ctl->zqdr[0]) & 0xff;
318                         writel(REPEAT_BYTE(zq_val[i]), &mctl_ctl->zqdr[2]);
319
320                         writel(PIR_CLRSR, &mctl_ctl->pir);
321                         mctl_phy_init(PIR_ZCAL);
322
323                         val = readl(&mctl_ctl->zqdr[0]) >> 24;
324                         zq_val[i] |= bin_to_mgray(mgray_to_bin(val) - 1) << 8;
325                 }
326
327                 writel((zq_val[1] << 16) | zq_val[0], &mctl_ctl->zqdr[0]);
328                 writel((zq_val[3] << 16) | zq_val[2], &mctl_ctl->zqdr[1]);
329                 if (zq_count > 4)
330                         writel((zq_val[5] << 16) | zq_val[4],
331                                &mctl_ctl->zqdr[2]);
332         }
333 }
334
335 static void mctl_set_cr(uint16_t socid, struct dram_para *para)
336 {
337         struct sunxi_mctl_com_reg * const mctl_com =
338                         (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
339
340         writel(MCTL_CR_BL8 | MCTL_CR_INTERLEAVED |
341 #if defined CONFIG_SUNXI_DRAM_DDR3
342                MCTL_CR_DDR3 | MCTL_CR_2T |
343 #else
344 #error Unsupported DRAM type!
345 #endif
346                (para->bank_bits == 3 ? MCTL_CR_EIGHT_BANKS : MCTL_CR_FOUR_BANKS) |
347                MCTL_CR_BUS_FULL_WIDTH(para->bus_full_width) |
348                (para->dual_rank ? MCTL_CR_DUAL_RANK : MCTL_CR_SINGLE_RANK) |
349                MCTL_CR_PAGE_SIZE(para->page_size) |
350                MCTL_CR_ROW_BITS(para->row_bits), &mctl_com->cr);
351
352         if (socid == SOCID_R40) {
353                 if (para->dual_rank)
354                         panic("Dual rank memory not supported\n");
355
356                 /* Mux pin to A15 address line for single rank memory. */
357                 setbits_le32(&mctl_com->cr_r1, MCTL_CR_R1_MUX_A15);
358         }
359 }
360
361 static void mctl_sys_init(uint16_t socid, struct dram_para *para)
362 {
363         struct sunxi_ccm_reg * const ccm =
364                         (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
365         struct sunxi_mctl_ctl_reg * const mctl_ctl =
366                         (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
367
368         clrbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
369         clrbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
370         clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
371         clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
372         clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
373         if (socid == SOCID_A64 || socid == SOCID_R40)
374                 clrbits_le32(&ccm->pll11_cfg, CCM_PLL11_CTRL_EN);
375         udelay(10);
376
377         clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
378         udelay(1000);
379
380         if (socid == SOCID_A64 || socid == SOCID_R40) {
381                 clock_set_pll11(CONFIG_DRAM_CLK * 2 * 1000000, false);
382                 clrsetbits_le32(&ccm->dram_clk_cfg,
383                                 CCM_DRAMCLK_CFG_DIV_MASK |
384                                 CCM_DRAMCLK_CFG_SRC_MASK,
385                                 CCM_DRAMCLK_CFG_DIV(1) |
386                                 CCM_DRAMCLK_CFG_SRC_PLL11 |
387                                 CCM_DRAMCLK_CFG_UPD);
388         } else if (socid == SOCID_H3 || socid == SOCID_H5) {
389                 clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false);
390                 clrsetbits_le32(&ccm->dram_clk_cfg,
391                                 CCM_DRAMCLK_CFG_DIV_MASK |
392                                 CCM_DRAMCLK_CFG_SRC_MASK,
393                                 CCM_DRAMCLK_CFG_DIV(1) |
394                                 CCM_DRAMCLK_CFG_SRC_PLL5 |
395                                 CCM_DRAMCLK_CFG_UPD);
396         }
397         mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
398
399         setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
400         setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
401         setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
402         setbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
403
404         setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
405         udelay(10);
406
407         writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken);
408         udelay(500);
409 }
410
411 /* These are more guessed based on some Allwinner code. */
412 #define DX_GCR_ODT_DYNAMIC      (0x0 << 4)
413 #define DX_GCR_ODT_ALWAYS_ON    (0x1 << 4)
414 #define DX_GCR_ODT_OFF          (0x2 << 4)
415
416 static int mctl_channel_init(uint16_t socid, struct dram_para *para)
417 {
418         struct sunxi_mctl_com_reg * const mctl_com =
419                         (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
420         struct sunxi_mctl_ctl_reg * const mctl_ctl =
421                         (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
422
423         unsigned int i;
424
425         mctl_set_cr(socid, para);
426         mctl_set_timing_params(socid, para);
427         mctl_set_master_priority(socid);
428
429         /* setting VTC, default disable all VT */
430         clrbits_le32(&mctl_ctl->pgcr[0], (1 << 30) | 0x3f);
431         if (socid == SOCID_H5)
432                 setbits_le32(&mctl_ctl->pgcr[1], (1 << 24) | (1 << 26));
433         else
434                 clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
435
436         /* increase DFI_PHY_UPD clock */
437         writel(PROTECT_MAGIC, &mctl_com->protect);
438         udelay(100);
439         clrsetbits_le32(&mctl_ctl->upd2, 0xfff << 16, 0x50 << 16);
440         writel(0x0, &mctl_com->protect);
441         udelay(100);
442
443         /* set dramc odt */
444         for (i = 0; i < 4; i++) {
445                 u32 clearmask = (0x3 << 4) | (0x1 << 1) | (0x3 << 2) |
446                                 (0x3 << 12) | (0x3 << 14);
447                 u32 setmask = IS_ENABLED(CONFIG_DRAM_ODT_EN) ?
448                                 DX_GCR_ODT_DYNAMIC : DX_GCR_ODT_OFF;
449
450                 if (socid == SOCID_H5) {
451                         clearmask |= 0x2 << 8;
452                         setmask |= 0x4 << 8;
453                 }
454                 clrsetbits_le32(&mctl_ctl->dx[i].gcr, clearmask, setmask);
455         }
456
457         /* AC PDR should always ON */
458         clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0,
459                         0x1 << 1);
460
461         /* set DQS auto gating PD mode */
462         setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
463
464         if (socid == SOCID_H3) {
465                 /* dx ddr_clk & hdr_clk dynamic mode */
466                 clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
467
468                 /* dphy & aphy phase select 270 degree */
469                 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
470                                 (0x1 << 10) | (0x2 << 8));
471         } else if (socid == SOCID_A64 || socid == SOCID_H5) {
472                 /* dphy & aphy phase select ? */
473                 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
474                                 (0x0 << 10) | (0x3 << 8));
475         } else if (socid == SOCID_R40) {
476                 /* dx ddr_clk & hdr_clk dynamic mode (tpr13[9] == 0) */
477                 clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
478
479                 /* dphy & aphy phase select ? */
480                 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
481                                 (0x0 << 10) | (0x3 << 8));
482         }
483
484         /* set half DQ */
485         if (!para->bus_full_width) {
486 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
487                 writel(0x0, &mctl_ctl->dx[2].gcr);
488                 writel(0x0, &mctl_ctl->dx[3].gcr);
489 #elif defined CONFIG_SUNXI_DRAM_DW_16BIT
490                 writel(0x0, &mctl_ctl->dx[1].gcr);
491 #else
492 #error Unsupported DRAM bus width!
493 #endif
494         }
495
496         /* data training configuration */
497         clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24,
498                         (para->dual_rank ? 0x3 : 0x1) << 24);
499
500         mctl_set_bit_delays(para);
501         udelay(50);
502
503         if (socid == SOCID_H3) {
504                 mctl_h3_zq_calibration_quirk(para);
505
506                 mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
507                               PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
508         } else if (socid == SOCID_A64 || socid == SOCID_H5) {
509                 clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
510
511                 mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
512                               PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
513                 /* no PIR_QSGATE for H5 ???? */
514         } else if (socid == SOCID_R40) {
515                 clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
516
517                 mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
518                               PIR_DRAMRST | PIR_DRAMINIT);
519         }
520
521         /* detect ranks and bus width */
522         if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
523                 /* only one rank */
524                 if (((readl(&mctl_ctl->dx[0].gsr[0]) >> 24) & 0x2)
525 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
526                     || ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x2)
527 #endif
528                     ) {
529                         clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
530                         para->dual_rank = 0;
531                 }
532
533                 /* only half DQ width */
534 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
535                 if (((readl(&mctl_ctl->dx[2].gsr[0]) >> 24) & 0x1) ||
536                     ((readl(&mctl_ctl->dx[3].gsr[0]) >> 24) & 0x1)) {
537                         writel(0x0, &mctl_ctl->dx[2].gcr);
538                         writel(0x0, &mctl_ctl->dx[3].gcr);
539                         para->bus_full_width = 0;
540                 }
541 #elif defined CONFIG_SUNXI_DRAM_DW_16BIT
542                 if ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x1) {
543                         writel(0x0, &mctl_ctl->dx[1].gcr);
544                         para->bus_full_width = 0;
545                 }
546 #endif
547
548                 mctl_set_cr(socid, para);
549                 udelay(20);
550
551                 /* re-train */
552                 mctl_phy_init(PIR_QSGATE);
553                 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20))
554                         return 1;
555         }
556
557         /* check the dramc status */
558         mctl_await_completion(&mctl_ctl->statr, 0x1, 0x1);
559
560         /* liuke added for refresh debug */
561         setbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
562         udelay(10);
563         clrbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
564         udelay(10);
565
566         /* set PGCR3, CKE polarity */
567         if (socid == SOCID_H3)
568                 writel(0x00aa0060, &mctl_ctl->pgcr[3]);
569         else if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40)
570                 writel(0xc0aa0060, &mctl_ctl->pgcr[3]);
571
572         /* power down zq calibration module for power save */
573         setbits_le32(&mctl_ctl->zqcr, ZQCR_PWRDOWN);
574
575         /* enable master access */
576         writel(0xffffffff, &mctl_com->maer);
577
578         return 0;
579 }
580
581 static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
582 {
583         /* detect row address bits */
584         para->page_size = 512;
585         para->row_bits = 16;
586         para->bank_bits = 2;
587         mctl_set_cr(socid, para);
588
589         for (para->row_bits = 11; para->row_bits < 16; para->row_bits++)
590                 if (mctl_mem_matches((1 << (para->row_bits + para->bank_bits)) * para->page_size))
591                         break;
592
593         /* detect bank address bits */
594         para->bank_bits = 3;
595         mctl_set_cr(socid, para);
596
597         for (para->bank_bits = 2; para->bank_bits < 3; para->bank_bits++)
598                 if (mctl_mem_matches((1 << para->bank_bits) * para->page_size))
599                         break;
600
601         /* detect page size */
602         para->page_size = 8192;
603         mctl_set_cr(socid, para);
604
605         for (para->page_size = 512; para->page_size < 8192; para->page_size *= 2)
606                 if (mctl_mem_matches(para->page_size))
607                         break;
608 }
609
610 /*
611  * The actual values used here are taken from Allwinner provided boot0
612  * binaries, though they are probably board specific, so would likely benefit
613  * from invidual tuning for each board. Apparently a lot of boards copy from
614  * some Allwinner reference design, so we go with those generic values for now
615  * in the hope that they are reasonable for most (all?) boards.
616  */
617 #define SUN8I_H3_DX_READ_DELAYS                                 \
618         {{ 18, 18, 18, 18, 18, 18, 18, 18, 18,  0,  0 },        \
619          { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 },        \
620          { 18, 18, 18, 18, 18, 18, 18, 18, 18,  0,  0 },        \
621          { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 }}
622 #define SUN8I_H3_DX_WRITE_DELAYS                                \
623         {{  0,  0,  0,  0,  0,  0,  0,  0,  0, 10, 10 },        \
624          {  0,  0,  0,  0,  0,  0,  0,  0,  0, 10, 10 },        \
625          {  0,  0,  0,  0,  0,  0,  0,  0,  0, 10, 10 },        \
626          {  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  6 }}
627 #define SUN8I_H3_AC_DELAYS                                      \
628         {  0,  0,  0,  0,  0,  0,  0,  0,                       \
629            0,  0,  0,  0,  0,  0,  0,  0,                       \
630            0,  0,  0,  0,  0,  0,  0,  0,                       \
631            0,  0,  0,  0,  0,  0,  0      }
632
633 #define SUN8I_R40_DX_READ_DELAYS                                \
634         {{ 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 },        \
635          { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 },        \
636          { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 },        \
637          { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 } }
638 #define SUN8I_R40_DX_WRITE_DELAYS                               \
639         {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0 },        \
640          {  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0 },        \
641          {  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0 },        \
642          {  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0 } }
643 #define SUN8I_R40_AC_DELAYS                                     \
644         {  0,  0,  3,  0,  0,  0,  0,  0,                       \
645            0,  0,  0,  0,  0,  0,  0,  0,                       \
646            0,  0,  0,  0,  0,  0,  0,  0,                       \
647            0,  0,  0,  0,  0,  0,  0      }
648
649 #define SUN50I_A64_DX_READ_DELAYS                               \
650         {{ 16, 16, 16, 16, 17, 16, 16, 17, 16,  1,  0 },        \
651          { 17, 17, 17, 17, 17, 17, 17, 17, 17,  1,  0 },        \
652          { 16, 17, 17, 16, 16, 16, 16, 16, 16,  0,  0 },        \
653          { 17, 17, 17, 17, 17, 17, 17, 17, 17,  1,  0 }}
654 #define SUN50I_A64_DX_WRITE_DELAYS                              \
655         {{  0,  0,  0,  0,  0,  0,  0,  0,  0, 15, 15 },        \
656          {  0,  0,  0,  0,  1,  1,  1,  1,  0, 10, 10 },        \
657          {  1,  0,  1,  1,  1,  1,  1,  1,  0, 11, 11 },        \
658          {  1,  0,  0,  1,  1,  1,  1,  1,  0, 12, 12 }}
659 #define SUN50I_A64_AC_DELAYS                                    \
660         {  5,  5, 13, 10,  2,  5,  3,  3,                       \
661            0,  3,  3,  3,  1,  0,  0,  0,                       \
662            3,  4,  0,  3,  4,  1,  4,  0,                       \
663            1,  1,  0,  1, 13,  5,  4      }
664
665 #define SUN8I_H5_DX_READ_DELAYS                                 \
666         {{ 14, 15, 17, 17, 17, 17, 17, 18, 17,  3,  3 },        \
667          { 21, 21, 12, 22, 21, 21, 21, 21, 21,  3,  3 },        \
668          { 16, 19, 19, 17, 22, 22, 21, 22, 19,  3,  3 },        \
669          { 21, 21, 22, 22, 20, 21, 19, 19, 19,  3,  3 } }
670 #define SUN8I_H5_DX_WRITE_DELAYS                                \
671         {{  1,  2,  3,  4,  3,  4,  4,  4,  6,  6,  6 },        \
672          {  6,  6,  6,  5,  5,  5,  5,  5,  6,  6,  6 },        \
673          {  0,  2,  4,  2,  6,  5,  5,  5,  6,  6,  6 },        \
674          {  3,  3,  3,  2,  2,  1,  1,  1,  4,  4,  4 } }
675 #define SUN8I_H5_AC_DELAYS                                      \
676         {  0,  0,  5,  5,  0,  0,  0,  0,                       \
677            0,  0,  0,  0,  3,  3,  3,  3,                       \
678            3,  3,  3,  3,  3,  3,  3,  3,                       \
679            3,  3,  3,  3,  2,  0,  0      }
680
681 unsigned long sunxi_dram_init(void)
682 {
683         struct sunxi_mctl_com_reg * const mctl_com =
684                         (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
685         struct sunxi_mctl_ctl_reg * const mctl_ctl =
686                         (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
687
688         struct dram_para para = {
689                 .dual_rank = 0,
690                 .bus_full_width = 1,
691                 .row_bits = 15,
692                 .bank_bits = 3,
693                 .page_size = 4096,
694
695 #if defined(CONFIG_MACH_SUN8I_H3)
696                 .dx_read_delays  = SUN8I_H3_DX_READ_DELAYS,
697                 .dx_write_delays = SUN8I_H3_DX_WRITE_DELAYS,
698                 .ac_delays       = SUN8I_H3_AC_DELAYS,
699 #elif defined(CONFIG_MACH_SUN8I_R40)
700                 .dx_read_delays  = SUN8I_R40_DX_READ_DELAYS,
701                 .dx_write_delays = SUN8I_R40_DX_WRITE_DELAYS,
702                 .ac_delays       = SUN8I_R40_AC_DELAYS,
703 #elif defined(CONFIG_MACH_SUN50I)
704                 .dx_read_delays  = SUN50I_A64_DX_READ_DELAYS,
705                 .dx_write_delays = SUN50I_A64_DX_WRITE_DELAYS,
706                 .ac_delays       = SUN50I_A64_AC_DELAYS,
707 #elif defined(CONFIG_MACH_SUN50I_H5)
708                 .dx_read_delays  = SUN8I_H5_DX_READ_DELAYS,
709                 .dx_write_delays = SUN8I_H5_DX_WRITE_DELAYS,
710                 .ac_delays       = SUN8I_H5_AC_DELAYS,
711 #endif
712         };
713 /*
714  * Let the compiler optimize alternatives away by passing this value into
715  * the static functions. This saves us #ifdefs, but still keeps the binary
716  * small.
717  */
718 #if defined(CONFIG_MACH_SUN8I_H3)
719         uint16_t socid = SOCID_H3;
720 #elif defined(CONFIG_MACH_SUN8I_R40)
721         uint16_t socid = SOCID_R40;
722 #elif defined(CONFIG_MACH_SUN50I)
723         uint16_t socid = SOCID_A64;
724 #elif defined(CONFIG_MACH_SUN50I_H5)
725         uint16_t socid = SOCID_H5;
726 #endif
727
728         mctl_sys_init(socid, &para);
729         if (mctl_channel_init(socid, &para))
730                 return 0;
731
732         if (para.dual_rank)
733                 writel(0x00000303, &mctl_ctl->odtmap);
734         else
735                 writel(0x00000201, &mctl_ctl->odtmap);
736         udelay(1);
737
738         /* odt delay */
739         if (socid == SOCID_H3)
740                 writel(0x0c000400, &mctl_ctl->odtcfg);
741
742         if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40) {
743                 /* VTF enable (tpr13[8] == 1) */
744                 setbits_le32(&mctl_ctl->vtfcr,
745                              (socid != SOCID_A64 ? 3 : 2) << 8);
746                 /* DQ hold disable (tpr13[26] == 1) */
747                 clrbits_le32(&mctl_ctl->pgcr[2], (1 << 13));
748         }
749
750         /* clear credit value */
751         setbits_le32(&mctl_com->cccr, 1 << 31);
752         udelay(10);
753
754         mctl_auto_detect_dram_size(socid, &para);
755         mctl_set_cr(socid, &para);
756
757         return (1UL << (para.row_bits + para.bank_bits)) * para.page_size *
758                (para.dual_rank ? 2 : 1);
759 }