1 // SPDX-License-Identifier: GPL-2.0+
3 * sun8i H3 platform dram controller init
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>
15 #include <asm/arch/clock.h>
16 #include <asm/arch/dram.h>
17 #include <asm/arch/cpu.h>
18 #include <linux/delay.h>
19 #include <linux/kconfig.h>
21 static void mctl_phy_init(u32 val)
23 struct sunxi_mctl_ctl_reg * const mctl_ctl =
24 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
26 writel(val | PIR_INIT, &mctl_ctl->pir);
27 mctl_await_completion(&mctl_ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
30 static void mctl_set_bit_delays(struct dram_para *para)
32 struct sunxi_mctl_ctl_reg * const mctl_ctl =
33 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
36 clrbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
38 for (i = 0; i < NR_OF_BYTE_LANES; i++)
39 for (j = 0; j < LINES_PER_BYTE_LANE; j++)
40 writel(DXBDLR_WRITE_DELAY(para->dx_write_delays[i][j]) |
41 DXBDLR_READ_DELAY(para->dx_read_delays[i][j]),
42 &mctl_ctl->dx[i].bdlr[j]);
44 for (i = 0; i < 31; i++)
45 writel(ACBDLR_WRITE_DELAY(para->ac_delays[i]),
46 &mctl_ctl->acbdlr[i]);
48 #ifdef CONFIG_MACH_SUN8I_R40
49 /* DQSn, DMn, DQn output enable bit delay */
50 for (i = 0; i < 4; i++)
51 writel(0x6 << 24, &mctl_ctl->dx[i].sdlr);
54 setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
69 MBUS_PORT_DE_CFD = 11,
70 MBUS_PORT_UNKNOWN1 = 12,
71 MBUS_PORT_UNKNOWN2 = 13,
72 MBUS_PORT_UNKNOWN3 = 14,
82 static inline void mbus_configure_port(u8 port,
85 u8 qos, /* MBUS_QOS_LOWEST .. MBUS_QOS_HIGEST */
86 u8 waittime, /* 0 .. 0xf */
87 u8 acs, /* 0 .. 0xff */
88 u16 bwl0, /* 0 .. 0xffff, bandwidth limit in MB/s */
92 struct sunxi_mctl_com_reg * const mctl_com =
93 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
95 const u32 cfg0 = ( (bwlimit ? (1 << 0) : 0)
96 | (priority ? (1 << 1) : 0)
98 | ((waittime & 0xf) << 4)
101 const u32 cfg1 = ((u32)bwl2 << 16) | (bwl1 & 0xffff);
103 debug("MBUS port %d cfg0 %08x cfg1 %08x\n", port, cfg0, cfg1);
104 writel(cfg0, &mctl_com->mcr[port][0]);
105 writel(cfg1, &mctl_com->mcr[port][1]);
108 #define MBUS_CONF(port, bwlimit, qos, acs, bwl0, bwl1, bwl2) \
109 mbus_configure_port(MBUS_PORT_ ## port, bwlimit, false, \
110 MBUS_QOS_ ## qos, 0, acs, bwl0, bwl1, bwl2)
112 static void mctl_set_master_priority_h3(void)
114 struct sunxi_mctl_com_reg * const mctl_com =
115 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
117 /* enable bandwidth limit windows and set windows size 1us */
118 writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
120 /* set cpu high priority */
121 writel(0x00000001, &mctl_com->mapr);
123 MBUS_CONF( CPU, true, HIGHEST, 0, 512, 256, 128);
124 MBUS_CONF( GPU, true, HIGH, 0, 1536, 1024, 256);
125 MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96);
126 MBUS_CONF( DMA, true, HIGHEST, 0, 256, 128, 32);
127 MBUS_CONF( VE, true, HIGH, 0, 1792, 1600, 256);
128 MBUS_CONF( CSI, true, HIGHEST, 0, 256, 128, 32);
129 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
130 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
131 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
132 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
133 MBUS_CONF( DE, true, HIGHEST, 3, 8192, 6120, 1024);
134 MBUS_CONF(DE_CFD, true, HIGH, 0, 1024, 288, 64);
137 static void mctl_set_master_priority_a64(void)
139 struct sunxi_mctl_com_reg * const mctl_com =
140 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
142 /* enable bandwidth limit windows and set windows size 1us */
143 writel(399, &mctl_com->tmr);
144 writel((1 << 16), &mctl_com->bwcr);
146 /* Port 2 is reserved per Allwinner's linux-3.10 source, yet they
148 MBUS_CONF( CPU, true, HIGHEST, 0, 160, 100, 80);
149 MBUS_CONF( GPU, false, HIGH, 0, 1536, 1400, 256);
150 MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96);
151 MBUS_CONF( DMA, true, HIGH, 0, 256, 80, 100);
152 MBUS_CONF( VE, true, HIGH, 0, 1792, 1600, 256);
153 MBUS_CONF( CSI, true, HIGH, 0, 256, 128, 0);
154 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
155 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
156 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
157 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
158 MBUS_CONF( DE, true, HIGH, 2, 8192, 6144, 2048);
159 MBUS_CONF(DE_CFD, true, HIGH, 0, 1280, 144, 64);
161 writel(0x81000004, &mctl_com->mdfs_bwlr[2]);
164 static void mctl_set_master_priority_h5(void)
166 struct sunxi_mctl_com_reg * const mctl_com =
167 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
169 /* enable bandwidth limit windows and set windows size 1us */
170 writel(399, &mctl_com->tmr);
171 writel((1 << 16), &mctl_com->bwcr);
173 /* set cpu high priority */
174 writel(0x00000001, &mctl_com->mapr);
176 /* Port 2 is reserved per Allwinner's linux-3.10 source, yet
177 * they initialise it */
178 MBUS_CONF( CPU, true, HIGHEST, 0, 300, 260, 150);
179 MBUS_CONF( GPU, true, HIGHEST, 0, 600, 400, 200);
180 MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96);
181 MBUS_CONF( DMA, true, HIGHEST, 0, 256, 128, 32);
182 MBUS_CONF( VE, true, HIGHEST, 0, 1900, 1500, 1000);
183 MBUS_CONF( CSI, true, HIGHEST, 0, 150, 120, 100);
184 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
185 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
186 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
187 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
188 MBUS_CONF( DE, true, HIGHEST, 3, 3400, 2400, 1024);
189 MBUS_CONF(DE_CFD, true, HIGHEST, 0, 600, 400, 200);
192 static void mctl_set_master_priority_r40(void)
194 struct sunxi_mctl_com_reg * const mctl_com =
195 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
197 /* enable bandwidth limit windows and set windows size 1us */
198 writel(399, &mctl_com->tmr);
199 writel((1 << 16), &mctl_com->bwcr);
201 /* set cpu high priority */
202 writel(0x00000001, &mctl_com->mapr);
204 /* Port 2 is reserved per Allwinner's linux-3.10 source, yet
205 * they initialise it */
206 MBUS_CONF( CPU, true, HIGHEST, 0, 300, 260, 150);
207 MBUS_CONF( GPU, true, HIGHEST, 0, 600, 400, 200);
208 MBUS_CONF( UNUSED, true, HIGHEST, 0, 512, 256, 96);
209 MBUS_CONF( DMA, true, HIGHEST, 0, 256, 128, 32);
210 MBUS_CONF( VE, true, HIGHEST, 0, 1900, 1500, 1000);
211 MBUS_CONF( CSI, true, HIGHEST, 0, 150, 120, 100);
212 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
213 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
214 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
215 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
218 * The port names are probably wrong, but no correct sources
221 MBUS_CONF( DE, true, HIGH, 0, 128, 48, 0);
222 MBUS_CONF( DE_CFD, true, HIGH, 0, 384, 256, 0);
223 MBUS_CONF(UNKNOWN1, true, HIGHEST, 0, 512, 384, 256);
224 MBUS_CONF(UNKNOWN2, true, HIGHEST, 2, 8192, 6144, 1024);
225 MBUS_CONF(UNKNOWN3, true, HIGH, 0, 1280, 144, 64);
228 static void mctl_set_master_priority(uint16_t socid)
232 mctl_set_master_priority_h3();
235 mctl_set_master_priority_a64();
238 mctl_set_master_priority_h5();
241 mctl_set_master_priority_r40();
246 static u32 bin_to_mgray(int val)
248 static const u8 lookup_table[32] = {
249 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
250 0x0c, 0x0d, 0x0e, 0x0f, 0x0a, 0x0b, 0x08, 0x09,
251 0x18, 0x19, 0x1a, 0x1b, 0x1e, 0x1f, 0x1c, 0x1d,
252 0x14, 0x15, 0x16, 0x17, 0x12, 0x13, 0x10, 0x11,
255 return lookup_table[clamp(val, 0, 31)];
258 static int mgray_to_bin(u32 val)
260 static const u8 lookup_table[32] = {
261 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
262 0x0e, 0x0f, 0x0c, 0x0d, 0x08, 0x09, 0x0a, 0x0b,
263 0x1e, 0x1f, 0x1c, 0x1d, 0x18, 0x19, 0x1a, 0x1b,
264 0x10, 0x11, 0x12, 0x13, 0x16, 0x17, 0x14, 0x15,
267 return lookup_table[val & 0x1f];
270 static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
272 struct sunxi_mctl_ctl_reg * const mctl_ctl =
273 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
276 #if defined CONFIG_SUNXI_DRAM_DW_16BIT
282 if ((readl(SUNXI_SRAMC_BASE + 0x24) & 0xff) == 0 &&
283 (readl(SUNXI_SRAMC_BASE + 0xf0) & 0x1) == 0) {
286 clrsetbits_le32(&mctl_ctl->zqcr, 0xffff,
287 CONFIG_DRAM_ZQ & 0xffff);
289 writel(PIR_CLRSR, &mctl_ctl->pir);
290 mctl_phy_init(PIR_ZCAL);
292 reg_val = readl(&mctl_ctl->zqdr[0]);
293 reg_val &= (0x1f << 16) | (0x1f << 0);
294 reg_val |= reg_val << 8;
295 writel(reg_val, &mctl_ctl->zqdr[0]);
297 reg_val = readl(&mctl_ctl->zqdr[1]);
298 reg_val &= (0x1f << 16) | (0x1f << 0);
299 reg_val |= reg_val << 8;
300 writel(reg_val, &mctl_ctl->zqdr[1]);
301 writel(reg_val, &mctl_ctl->zqdr[2]);
307 writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
309 for (i = 0; i < zq_count; i++) {
310 u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
312 writel((zq << 20) | (zq << 16) | (zq << 12) |
313 (zq << 8) | (zq << 4) | (zq << 0),
316 writel(PIR_CLRSR, &mctl_ctl->pir);
317 mctl_phy_init(PIR_ZCAL);
319 zq_val[i] = readl(&mctl_ctl->zqdr[0]) & 0xff;
320 writel(REPEAT_BYTE(zq_val[i]), &mctl_ctl->zqdr[2]);
322 writel(PIR_CLRSR, &mctl_ctl->pir);
323 mctl_phy_init(PIR_ZCAL);
325 val = readl(&mctl_ctl->zqdr[0]) >> 24;
326 zq_val[i] |= bin_to_mgray(mgray_to_bin(val) - 1) << 8;
329 writel((zq_val[1] << 16) | zq_val[0], &mctl_ctl->zqdr[0]);
330 writel((zq_val[3] << 16) | zq_val[2], &mctl_ctl->zqdr[1]);
332 writel((zq_val[5] << 16) | zq_val[4],
337 static void mctl_set_cr(uint16_t socid, struct dram_para *para)
339 struct sunxi_mctl_com_reg * const mctl_com =
340 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
342 writel(MCTL_CR_BL8 | MCTL_CR_INTERLEAVED |
343 #if defined CONFIG_SUNXI_DRAM_DDR3
344 MCTL_CR_DDR3 | MCTL_CR_2T |
345 #elif defined CONFIG_SUNXI_DRAM_DDR2
346 MCTL_CR_DDR2 | MCTL_CR_2T |
347 #elif defined CONFIG_SUNXI_DRAM_LPDDR3
348 MCTL_CR_LPDDR3 | MCTL_CR_1T |
350 #error Unsupported DRAM type!
352 (para->bank_bits == 3 ? MCTL_CR_EIGHT_BANKS : MCTL_CR_FOUR_BANKS) |
353 MCTL_CR_BUS_FULL_WIDTH(para->bus_full_width) |
354 (para->dual_rank ? MCTL_CR_DUAL_RANK : MCTL_CR_SINGLE_RANK) |
355 MCTL_CR_PAGE_SIZE(para->page_size) |
356 MCTL_CR_ROW_BITS(para->row_bits), &mctl_com->cr);
358 if (socid == SOCID_R40) {
360 panic("Dual rank memory not supported\n");
362 /* Mux pin to A15 address line for single rank memory. */
363 setbits_le32(&mctl_com->cr_r1, MCTL_CR_R1_MUX_A15);
367 static void mctl_sys_init(uint16_t socid, struct dram_para *para)
369 struct sunxi_ccm_reg * const ccm =
370 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
371 struct sunxi_mctl_ctl_reg * const mctl_ctl =
372 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
374 clrbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
375 clrbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
376 clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
377 clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
378 clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
379 if (socid == SOCID_A64 || socid == SOCID_R40)
380 clrbits_le32(&ccm->pll11_cfg, CCM_PLL11_CTRL_EN);
383 clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
386 if (socid == SOCID_A64 || socid == SOCID_R40) {
387 clock_set_pll11(CONFIG_DRAM_CLK * 2 * 1000000, false);
388 clrsetbits_le32(&ccm->dram_clk_cfg,
389 CCM_DRAMCLK_CFG_DIV_MASK |
390 CCM_DRAMCLK_CFG_SRC_MASK,
391 CCM_DRAMCLK_CFG_DIV(1) |
392 CCM_DRAMCLK_CFG_SRC_PLL11 |
393 CCM_DRAMCLK_CFG_UPD);
394 } else if (socid == SOCID_H3 || socid == SOCID_H5) {
395 clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false);
396 clrsetbits_le32(&ccm->dram_clk_cfg,
397 CCM_DRAMCLK_CFG_DIV_MASK |
398 CCM_DRAMCLK_CFG_SRC_MASK,
399 CCM_DRAMCLK_CFG_DIV(1) |
400 CCM_DRAMCLK_CFG_SRC_PLL5 |
401 CCM_DRAMCLK_CFG_UPD);
403 mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
405 setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
406 setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
407 setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
408 setbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
410 setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
413 writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken);
417 /* These are more guessed based on some Allwinner code. */
418 #define DX_GCR_ODT_DYNAMIC (0x0 << 4)
419 #define DX_GCR_ODT_ALWAYS_ON (0x1 << 4)
420 #define DX_GCR_ODT_OFF (0x2 << 4)
422 static int mctl_channel_init(uint16_t socid, struct dram_para *para)
424 struct sunxi_mctl_com_reg * const mctl_com =
425 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
426 struct sunxi_mctl_ctl_reg * const mctl_ctl =
427 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
431 mctl_set_cr(socid, para);
432 mctl_set_timing_params(socid, para);
433 mctl_set_master_priority(socid);
435 /* setting VTC, default disable all VT */
436 clrbits_le32(&mctl_ctl->pgcr[0], (1 << 30) | 0x3f);
437 if (socid == SOCID_H5)
438 setbits_le32(&mctl_ctl->pgcr[1], (1 << 24) | (1 << 26));
440 clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
442 /* increase DFI_PHY_UPD clock */
443 writel(PROTECT_MAGIC, &mctl_com->protect);
445 clrsetbits_le32(&mctl_ctl->upd2, 0xfff << 16, 0x50 << 16);
446 writel(0x0, &mctl_com->protect);
450 for (i = 0; i < 4; i++) {
451 u32 clearmask = (0x3 << 4) | (0x1 << 1) | (0x3 << 2) |
452 (0x3 << 12) | (0x3 << 14);
453 u32 setmask = IS_ENABLED(CONFIG_DRAM_ODT_EN) ?
454 DX_GCR_ODT_DYNAMIC : DX_GCR_ODT_OFF;
456 if (socid == SOCID_H5) {
457 clearmask |= 0x2 << 8;
460 clrsetbits_le32(&mctl_ctl->dx[i].gcr, clearmask, setmask);
463 /* AC PDR should always ON */
464 clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0,
467 /* set DQS auto gating PD mode */
468 setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
470 if (socid == SOCID_H3) {
471 /* dx ddr_clk & hdr_clk dynamic mode */
472 clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
474 /* dphy & aphy phase select 270 degree */
475 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
476 (0x1 << 10) | (0x2 << 8));
477 } else if (socid == SOCID_A64 || socid == SOCID_H5) {
478 /* dphy & aphy phase select ? */
479 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
480 (0x0 << 10) | (0x3 << 8));
481 } else if (socid == SOCID_R40) {
482 /* dx ddr_clk & hdr_clk dynamic mode (tpr13[9] == 0) */
483 clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
485 /* dphy & aphy phase select ? */
486 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
487 (0x0 << 10) | (0x3 << 8));
491 if (!para->bus_full_width) {
492 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
493 writel(0x0, &mctl_ctl->dx[2].gcr);
494 writel(0x0, &mctl_ctl->dx[3].gcr);
495 #elif defined CONFIG_SUNXI_DRAM_DW_16BIT
496 writel(0x0, &mctl_ctl->dx[1].gcr);
498 #error Unsupported DRAM bus width!
502 /* data training configuration */
503 clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24,
504 (para->dual_rank ? 0x3 : 0x1) << 24);
506 mctl_set_bit_delays(para);
509 if (socid == SOCID_H3) {
510 mctl_h3_zq_calibration_quirk(para);
512 mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
513 PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
514 } else if (socid == SOCID_A64 || socid == SOCID_H5) {
515 clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
517 mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
518 PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
519 /* no PIR_QSGATE for H5 ???? */
520 } else if (socid == SOCID_R40) {
521 clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
523 mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
524 PIR_DRAMRST | PIR_DRAMINIT);
527 /* detect ranks and bus width */
528 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
530 if (((readl(&mctl_ctl->dx[0].gsr[0]) >> 24) & 0x2)
531 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
532 || ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x2)
535 clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
539 /* only half DQ width */
540 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
541 if (((readl(&mctl_ctl->dx[2].gsr[0]) >> 24) & 0x1) ||
542 ((readl(&mctl_ctl->dx[3].gsr[0]) >> 24) & 0x1)) {
543 writel(0x0, &mctl_ctl->dx[2].gcr);
544 writel(0x0, &mctl_ctl->dx[3].gcr);
545 para->bus_full_width = 0;
547 #elif defined CONFIG_SUNXI_DRAM_DW_16BIT
548 if ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x1) {
549 writel(0x0, &mctl_ctl->dx[1].gcr);
550 para->bus_full_width = 0;
554 mctl_set_cr(socid, para);
558 mctl_phy_init(PIR_QSGATE);
559 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20))
563 /* check the dramc status */
564 mctl_await_completion(&mctl_ctl->statr, 0x1, 0x1);
566 /* liuke added for refresh debug */
567 setbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
569 clrbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
572 /* set PGCR3, CKE polarity */
573 if (socid == SOCID_H3)
574 writel(0x00aa0060, &mctl_ctl->pgcr[3]);
575 else if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40)
576 writel(0xc0aa0060, &mctl_ctl->pgcr[3]);
578 /* power down zq calibration module for power save */
579 setbits_le32(&mctl_ctl->zqcr, ZQCR_PWRDOWN);
581 /* enable master access */
582 writel(0xffffffff, &mctl_com->maer);
587 static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
589 /* detect row address bits */
590 para->page_size = 512;
593 mctl_set_cr(socid, para);
595 for (para->row_bits = 11; para->row_bits < 16; para->row_bits++)
596 if (mctl_mem_matches((1 << (para->row_bits + para->bank_bits)) * para->page_size))
599 /* detect bank address bits */
601 mctl_set_cr(socid, para);
603 for (para->bank_bits = 2; para->bank_bits < 3; para->bank_bits++)
604 if (mctl_mem_matches((1 << para->bank_bits) * para->page_size))
607 /* detect page size */
608 para->page_size = 8192;
609 mctl_set_cr(socid, para);
611 for (para->page_size = 512; para->page_size < 8192; para->page_size *= 2)
612 if (mctl_mem_matches(para->page_size))
617 * The actual values used here are taken from Allwinner provided boot0
618 * binaries, though they are probably board specific, so would likely benefit
619 * from invidual tuning for each board. Apparently a lot of boards copy from
620 * some Allwinner reference design, so we go with those generic values for now
621 * in the hope that they are reasonable for most (all?) boards.
623 #define SUN8I_H3_DX_READ_DELAYS \
624 {{ 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0 }, \
625 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
626 { 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0 }, \
627 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }}
628 #define SUN8I_H3_DX_WRITE_DELAYS \
629 {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10 }, \
630 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10 }, \
631 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10 }, \
632 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6 }}
633 #define SUN8I_H3_AC_DELAYS \
634 { 0, 0, 0, 0, 0, 0, 0, 0, \
635 0, 0, 0, 0, 0, 0, 0, 0, \
636 0, 0, 0, 0, 0, 0, 0, 0, \
637 0, 0, 0, 0, 0, 0, 0 }
639 #define SUN8I_R40_DX_READ_DELAYS \
640 {{ 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
641 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
642 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
643 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 } }
644 #define SUN8I_R40_DX_WRITE_DELAYS \
645 {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 }, \
646 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 }, \
647 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 }, \
648 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 } }
649 #define SUN8I_R40_AC_DELAYS \
650 { 0, 0, 3, 0, 0, 0, 0, 0, \
651 0, 0, 0, 0, 0, 0, 0, 0, \
652 0, 0, 0, 0, 0, 0, 0, 0, \
653 0, 0, 0, 0, 0, 0, 0 }
655 #define SUN50I_A64_DX_READ_DELAYS \
656 {{ 16, 16, 16, 16, 17, 16, 16, 17, 16, 1, 0 }, \
657 { 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0 }, \
658 { 16, 17, 17, 16, 16, 16, 16, 16, 16, 0, 0 }, \
659 { 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0 }}
660 #define SUN50I_A64_DX_WRITE_DELAYS \
661 {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15 }, \
662 { 0, 0, 0, 0, 1, 1, 1, 1, 0, 10, 10 }, \
663 { 1, 0, 1, 1, 1, 1, 1, 1, 0, 11, 11 }, \
664 { 1, 0, 0, 1, 1, 1, 1, 1, 0, 12, 12 }}
665 #define SUN50I_A64_AC_DELAYS \
666 { 5, 5, 13, 10, 2, 5, 3, 3, \
667 0, 3, 3, 3, 1, 0, 0, 0, \
668 3, 4, 0, 3, 4, 1, 4, 0, \
669 1, 1, 0, 1, 13, 5, 4 }
671 #define SUN8I_H5_DX_READ_DELAYS \
672 {{ 14, 15, 17, 17, 17, 17, 17, 18, 17, 3, 3 }, \
673 { 21, 21, 12, 22, 21, 21, 21, 21, 21, 3, 3 }, \
674 { 16, 19, 19, 17, 22, 22, 21, 22, 19, 3, 3 }, \
675 { 21, 21, 22, 22, 20, 21, 19, 19, 19, 3, 3 } }
676 #define SUN8I_H5_DX_WRITE_DELAYS \
677 {{ 1, 2, 3, 4, 3, 4, 4, 4, 6, 6, 6 }, \
678 { 6, 6, 6, 5, 5, 5, 5, 5, 6, 6, 6 }, \
679 { 0, 2, 4, 2, 6, 5, 5, 5, 6, 6, 6 }, \
680 { 3, 3, 3, 2, 2, 1, 1, 1, 4, 4, 4 } }
681 #define SUN8I_H5_AC_DELAYS \
682 { 0, 0, 5, 5, 0, 0, 0, 0, \
683 0, 0, 0, 0, 3, 3, 3, 3, \
684 3, 3, 3, 3, 3, 3, 3, 3, \
685 3, 3, 3, 3, 2, 0, 0 }
687 unsigned long sunxi_dram_init(void)
689 struct sunxi_mctl_com_reg * const mctl_com =
690 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
691 struct sunxi_mctl_ctl_reg * const mctl_ctl =
692 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
694 struct dram_para para = {
701 #if defined(CONFIG_MACH_SUN8I_H3)
702 .dx_read_delays = SUN8I_H3_DX_READ_DELAYS,
703 .dx_write_delays = SUN8I_H3_DX_WRITE_DELAYS,
704 .ac_delays = SUN8I_H3_AC_DELAYS,
705 #elif defined(CONFIG_MACH_SUN8I_R40)
706 .dx_read_delays = SUN8I_R40_DX_READ_DELAYS,
707 .dx_write_delays = SUN8I_R40_DX_WRITE_DELAYS,
708 .ac_delays = SUN8I_R40_AC_DELAYS,
709 #elif defined(CONFIG_MACH_SUN50I)
710 .dx_read_delays = SUN50I_A64_DX_READ_DELAYS,
711 .dx_write_delays = SUN50I_A64_DX_WRITE_DELAYS,
712 .ac_delays = SUN50I_A64_AC_DELAYS,
713 #elif defined(CONFIG_MACH_SUN50I_H5)
714 .dx_read_delays = SUN8I_H5_DX_READ_DELAYS,
715 .dx_write_delays = SUN8I_H5_DX_WRITE_DELAYS,
716 .ac_delays = SUN8I_H5_AC_DELAYS,
720 * Let the compiler optimize alternatives away by passing this value into
721 * the static functions. This saves us #ifdefs, but still keeps the binary
724 #if defined(CONFIG_MACH_SUN8I_H3)
725 uint16_t socid = SOCID_H3;
726 #elif defined(CONFIG_MACH_SUN8I_R40)
727 uint16_t socid = SOCID_R40;
728 /* Currently we cannot support R40 with dual rank memory */
730 #elif defined(CONFIG_MACH_SUN8I_V3S)
731 /* TODO: set delays and mbus priority for V3s */
732 uint16_t socid = SOCID_H3;
733 #elif defined(CONFIG_MACH_SUN50I)
734 uint16_t socid = SOCID_A64;
735 #elif defined(CONFIG_MACH_SUN50I_H5)
736 uint16_t socid = SOCID_H5;
739 mctl_sys_init(socid, ¶);
740 if (mctl_channel_init(socid, ¶))
744 writel(0x00000303, &mctl_ctl->odtmap);
746 writel(0x00000201, &mctl_ctl->odtmap);
750 if (socid == SOCID_H3)
751 writel(0x0c000400, &mctl_ctl->odtcfg);
753 if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40) {
754 /* VTF enable (tpr13[8] == 1) */
755 setbits_le32(&mctl_ctl->vtfcr,
756 (socid != SOCID_A64 ? 3 : 2) << 8);
757 /* DQ hold disable (tpr13[26] == 1) */
758 clrbits_le32(&mctl_ctl->pgcr[2], (1 << 13));
761 /* clear credit value */
762 setbits_le32(&mctl_com->cccr, 1 << 31);
765 mctl_auto_detect_dram_size(socid, ¶);
766 mctl_set_cr(socid, ¶);
768 return (1UL << (para.row_bits + para.bank_bits)) * para.page_size *
769 (para.dual_rank ? 2 : 1);