2 * sun8i H3 platform dram controller init
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>
10 * SPDX-License-Identifier: GPL-2.0+
14 #include <asm/arch/clock.h>
15 #include <asm/arch/dram.h>
16 #include <asm/arch/cpu.h>
17 #include <linux/kconfig.h>
19 static void mctl_phy_init(u32 val)
21 struct sunxi_mctl_ctl_reg * const mctl_ctl =
22 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
24 writel(val | PIR_INIT, &mctl_ctl->pir);
25 mctl_await_completion(&mctl_ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
28 static void mctl_set_bit_delays(struct dram_para *para)
30 struct sunxi_mctl_ctl_reg * const mctl_ctl =
31 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
34 clrbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
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]);
42 for (i = 0; i < 31; i++)
43 writel(ACBDLR_WRITE_DELAY(para->ac_delays[i]),
44 &mctl_ctl->acbdlr[i]);
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);
52 setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
67 MBUS_PORT_DE_CFD = 11,
68 MBUS_PORT_UNKNOWN1 = 12,
69 MBUS_PORT_UNKNOWN2 = 13,
70 MBUS_PORT_UNKNOWN3 = 14,
80 inline void mbus_configure_port(u8 port,
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 */
90 struct sunxi_mctl_com_reg * const mctl_com =
91 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
93 const u32 cfg0 = ( (bwlimit ? (1 << 0) : 0)
94 | (priority ? (1 << 1) : 0)
96 | ((waittime & 0xf) << 4)
99 const u32 cfg1 = ((u32)bwl2 << 16) | (bwl1 & 0xffff);
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]);
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)
110 static void mctl_set_master_priority_h3(void)
112 struct sunxi_mctl_com_reg * const mctl_com =
113 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
115 /* enable bandwidth limit windows and set windows size 1us */
116 writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
118 /* set cpu high priority */
119 writel(0x00000001, &mctl_com->mapr);
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);
135 static void mctl_set_master_priority_a64(void)
137 struct sunxi_mctl_com_reg * const mctl_com =
138 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
140 /* enable bandwidth limit windows and set windows size 1us */
141 writel(399, &mctl_com->tmr);
142 writel((1 << 16), &mctl_com->bwcr);
144 /* Port 2 is reserved per Allwinner's linux-3.10 source, yet they
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);
159 writel(0x81000004, &mctl_com->mdfs_bwlr[2]);
162 static void mctl_set_master_priority_h5(void)
164 struct sunxi_mctl_com_reg * const mctl_com =
165 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
167 /* enable bandwidth limit windows and set windows size 1us */
168 writel(399, &mctl_com->tmr);
169 writel((1 << 16), &mctl_com->bwcr);
171 /* set cpu high priority */
172 writel(0x00000001, &mctl_com->mapr);
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);
190 static void mctl_set_master_priority_r40(void)
192 struct sunxi_mctl_com_reg * const mctl_com =
193 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
195 /* enable bandwidth limit windows and set windows size 1us */
196 writel(399, &mctl_com->tmr);
197 writel((1 << 16), &mctl_com->bwcr);
199 /* set cpu high priority */
200 writel(0x00000001, &mctl_com->mapr);
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);
216 * The port names are probably wrong, but no correct sources
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);
226 static void mctl_set_master_priority(uint16_t socid)
230 mctl_set_master_priority_h3();
233 mctl_set_master_priority_a64();
236 mctl_set_master_priority_h5();
239 mctl_set_master_priority_r40();
244 static u32 bin_to_mgray(int val)
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,
253 return lookup_table[clamp(val, 0, 31)];
256 static int mgray_to_bin(u32 val)
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,
265 return lookup_table[val & 0x1f];
268 static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
270 struct sunxi_mctl_ctl_reg * const mctl_ctl =
271 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
274 #if defined CONFIG_SUNXI_DRAM_DW_16BIT
280 if ((readl(SUNXI_SRAMC_BASE + 0x24) & 0xff) == 0 &&
281 (readl(SUNXI_SRAMC_BASE + 0xf0) & 0x1) == 0) {
284 clrsetbits_le32(&mctl_ctl->zqcr, 0xffff,
285 CONFIG_DRAM_ZQ & 0xffff);
287 writel(PIR_CLRSR, &mctl_ctl->pir);
288 mctl_phy_init(PIR_ZCAL);
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]);
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]);
305 writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
307 for (i = 0; i < zq_count; i++) {
308 u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
310 writel((zq << 20) | (zq << 16) | (zq << 12) |
311 (zq << 8) | (zq << 4) | (zq << 0),
314 writel(PIR_CLRSR, &mctl_ctl->pir);
315 mctl_phy_init(PIR_ZCAL);
317 zq_val[i] = readl(&mctl_ctl->zqdr[0]) & 0xff;
318 writel(REPEAT_BYTE(zq_val[i]), &mctl_ctl->zqdr[2]);
320 writel(PIR_CLRSR, &mctl_ctl->pir);
321 mctl_phy_init(PIR_ZCAL);
323 val = readl(&mctl_ctl->zqdr[0]) >> 24;
324 zq_val[i] |= bin_to_mgray(mgray_to_bin(val) - 1) << 8;
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]);
330 writel((zq_val[5] << 16) | zq_val[4],
335 static void mctl_set_cr(uint16_t socid, struct dram_para *para)
337 struct sunxi_mctl_com_reg * const mctl_com =
338 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
340 writel(MCTL_CR_BL8 | MCTL_CR_INTERLEAVED |
341 #if defined CONFIG_SUNXI_DRAM_DDR3
342 MCTL_CR_DDR3 | MCTL_CR_2T |
344 #error Unsupported DRAM type!
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);
352 if (socid == SOCID_R40) {
354 panic("Dual rank memory not supported\n");
356 /* Mux pin to A15 address line for single rank memory. */
357 setbits_le32(&mctl_com->cr_r1, MCTL_CR_R1_MUX_A15);
361 static void mctl_sys_init(uint16_t socid, struct dram_para *para)
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;
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);
377 clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
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);
397 mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
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);
404 setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
407 writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken);
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)
416 static int mctl_channel_init(uint16_t socid, struct dram_para *para)
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;
425 mctl_set_cr(socid, para);
426 mctl_set_timing_params(socid, para);
427 mctl_set_master_priority(socid);
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));
434 clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
436 /* increase DFI_PHY_UPD clock */
437 writel(PROTECT_MAGIC, &mctl_com->protect);
439 clrsetbits_le32(&mctl_ctl->upd2, 0xfff << 16, 0x50 << 16);
440 writel(0x0, &mctl_com->protect);
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;
450 if (socid == SOCID_H5) {
451 clearmask |= 0x2 << 8;
454 clrsetbits_le32(&mctl_ctl->dx[i].gcr, clearmask, setmask);
457 /* AC PDR should always ON */
458 clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0,
461 /* set DQS auto gating PD mode */
462 setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
464 if (socid == SOCID_H3) {
465 /* dx ddr_clk & hdr_clk dynamic mode */
466 clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
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));
479 /* dphy & aphy phase select ? */
480 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
481 (0x0 << 10) | (0x3 << 8));
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);
492 #error Unsupported DRAM bus width!
496 /* data training configuration */
497 clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24,
498 (para->dual_rank ? 0x3 : 0x1) << 24);
500 mctl_set_bit_delays(para);
503 if (socid == SOCID_H3) {
504 mctl_h3_zq_calibration_quirk(para);
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);
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);
517 mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
518 PIR_DRAMRST | PIR_DRAMINIT);
521 /* detect ranks and bus width */
522 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
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)
529 clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
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;
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;
548 mctl_set_cr(socid, para);
552 mctl_phy_init(PIR_QSGATE);
553 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20))
557 /* check the dramc status */
558 mctl_await_completion(&mctl_ctl->statr, 0x1, 0x1);
560 /* liuke added for refresh debug */
561 setbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
563 clrbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
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]);
572 /* power down zq calibration module for power save */
573 setbits_le32(&mctl_ctl->zqcr, ZQCR_PWRDOWN);
575 /* enable master access */
576 writel(0xffffffff, &mctl_com->maer);
581 static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
583 /* detect row address bits */
584 para->page_size = 512;
587 mctl_set_cr(socid, para);
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))
593 /* detect bank address bits */
595 mctl_set_cr(socid, para);
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))
601 /* detect page size */
602 para->page_size = 8192;
603 mctl_set_cr(socid, para);
605 for (para->page_size = 512; para->page_size < 8192; para->page_size *= 2)
606 if (mctl_mem_matches(para->page_size))
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.
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 }
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 }
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 }
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 }
681 unsigned long sunxi_dram_init(void)
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;
688 struct dram_para para = {
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,
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
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;
728 mctl_sys_init(socid, ¶);
729 if (mctl_channel_init(socid, ¶))
733 writel(0x00000303, &mctl_ctl->odtmap);
735 writel(0x00000201, &mctl_ctl->odtmap);
739 if (socid == SOCID_H3)
740 writel(0x0c000400, &mctl_ctl->odtcfg);
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));
750 /* clear credit value */
751 setbits_le32(&mctl_com->cccr, 1 << 31);
754 mctl_auto_detect_dram_size(socid, ¶);
755 mctl_set_cr(socid, ¶);
757 return (1UL << (para.row_bits + para.bank_bits)) * para.page_size *
758 (para.dual_rank ? 2 : 1);