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