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/kconfig.h>
20 static void mctl_phy_init(u32 val)
22 struct sunxi_mctl_ctl_reg * const mctl_ctl =
23 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
25 writel(val | PIR_INIT, &mctl_ctl->pir);
26 mctl_await_completion(&mctl_ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
29 static void mctl_set_bit_delays(struct dram_para *para)
31 struct sunxi_mctl_ctl_reg * const mctl_ctl =
32 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
35 clrbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
37 for (i = 0; i < NR_OF_BYTE_LANES; i++)
38 for (j = 0; j < LINES_PER_BYTE_LANE; j++)
39 writel(DXBDLR_WRITE_DELAY(para->dx_write_delays[i][j]) |
40 DXBDLR_READ_DELAY(para->dx_read_delays[i][j]),
41 &mctl_ctl->dx[i].bdlr[j]);
43 for (i = 0; i < 31; i++)
44 writel(ACBDLR_WRITE_DELAY(para->ac_delays[i]),
45 &mctl_ctl->acbdlr[i]);
47 #ifdef CONFIG_MACH_SUN8I_R40
48 /* DQSn, DMn, DQn output enable bit delay */
49 for (i = 0; i < 4; i++)
50 writel(0x6 << 24, &mctl_ctl->dx[i].sdlr);
53 setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
68 MBUS_PORT_DE_CFD = 11,
69 MBUS_PORT_UNKNOWN1 = 12,
70 MBUS_PORT_UNKNOWN2 = 13,
71 MBUS_PORT_UNKNOWN3 = 14,
81 inline void mbus_configure_port(u8 port,
84 u8 qos, /* MBUS_QOS_LOWEST .. MBUS_QOS_HIGEST */
85 u8 waittime, /* 0 .. 0xf */
86 u8 acs, /* 0 .. 0xff */
87 u16 bwl0, /* 0 .. 0xffff, bandwidth limit in MB/s */
91 struct sunxi_mctl_com_reg * const mctl_com =
92 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
94 const u32 cfg0 = ( (bwlimit ? (1 << 0) : 0)
95 | (priority ? (1 << 1) : 0)
97 | ((waittime & 0xf) << 4)
100 const u32 cfg1 = ((u32)bwl2 << 16) | (bwl1 & 0xffff);
102 debug("MBUS port %d cfg0 %08x cfg1 %08x\n", port, cfg0, cfg1);
103 writel(cfg0, &mctl_com->mcr[port][0]);
104 writel(cfg1, &mctl_com->mcr[port][1]);
107 #define MBUS_CONF(port, bwlimit, qos, acs, bwl0, bwl1, bwl2) \
108 mbus_configure_port(MBUS_PORT_ ## port, bwlimit, false, \
109 MBUS_QOS_ ## qos, 0, acs, bwl0, bwl1, bwl2)
111 static void mctl_set_master_priority_h3(void)
113 struct sunxi_mctl_com_reg * const mctl_com =
114 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
116 /* enable bandwidth limit windows and set windows size 1us */
117 writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
119 /* set cpu high priority */
120 writel(0x00000001, &mctl_com->mapr);
122 MBUS_CONF( CPU, true, HIGHEST, 0, 512, 256, 128);
123 MBUS_CONF( GPU, true, HIGH, 0, 1536, 1024, 256);
124 MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96);
125 MBUS_CONF( DMA, true, HIGHEST, 0, 256, 128, 32);
126 MBUS_CONF( VE, true, HIGH, 0, 1792, 1600, 256);
127 MBUS_CONF( CSI, true, HIGHEST, 0, 256, 128, 32);
128 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
129 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
130 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
131 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
132 MBUS_CONF( DE, true, HIGHEST, 3, 8192, 6120, 1024);
133 MBUS_CONF(DE_CFD, true, HIGH, 0, 1024, 288, 64);
136 static void mctl_set_master_priority_a64(void)
138 struct sunxi_mctl_com_reg * const mctl_com =
139 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
141 /* enable bandwidth limit windows and set windows size 1us */
142 writel(399, &mctl_com->tmr);
143 writel((1 << 16), &mctl_com->bwcr);
145 /* Port 2 is reserved per Allwinner's linux-3.10 source, yet they
147 MBUS_CONF( CPU, true, HIGHEST, 0, 160, 100, 80);
148 MBUS_CONF( GPU, false, HIGH, 0, 1536, 1400, 256);
149 MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96);
150 MBUS_CONF( DMA, true, HIGH, 0, 256, 80, 100);
151 MBUS_CONF( VE, true, HIGH, 0, 1792, 1600, 256);
152 MBUS_CONF( CSI, true, HIGH, 0, 256, 128, 0);
153 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
154 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
155 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
156 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
157 MBUS_CONF( DE, true, HIGH, 2, 8192, 6144, 2048);
158 MBUS_CONF(DE_CFD, true, HIGH, 0, 1280, 144, 64);
160 writel(0x81000004, &mctl_com->mdfs_bwlr[2]);
163 static void mctl_set_master_priority_h5(void)
165 struct sunxi_mctl_com_reg * const mctl_com =
166 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
168 /* enable bandwidth limit windows and set windows size 1us */
169 writel(399, &mctl_com->tmr);
170 writel((1 << 16), &mctl_com->bwcr);
172 /* set cpu high priority */
173 writel(0x00000001, &mctl_com->mapr);
175 /* Port 2 is reserved per Allwinner's linux-3.10 source, yet
176 * they initialise it */
177 MBUS_CONF( CPU, true, HIGHEST, 0, 300, 260, 150);
178 MBUS_CONF( GPU, true, HIGHEST, 0, 600, 400, 200);
179 MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96);
180 MBUS_CONF( DMA, true, HIGHEST, 0, 256, 128, 32);
181 MBUS_CONF( VE, true, HIGHEST, 0, 1900, 1500, 1000);
182 MBUS_CONF( CSI, true, HIGHEST, 0, 150, 120, 100);
183 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
184 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
185 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
186 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
187 MBUS_CONF( DE, true, HIGHEST, 3, 3400, 2400, 1024);
188 MBUS_CONF(DE_CFD, true, HIGHEST, 0, 600, 400, 200);
191 static void mctl_set_master_priority_r40(void)
193 struct sunxi_mctl_com_reg * const mctl_com =
194 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
196 /* enable bandwidth limit windows and set windows size 1us */
197 writel(399, &mctl_com->tmr);
198 writel((1 << 16), &mctl_com->bwcr);
200 /* set cpu high priority */
201 writel(0x00000001, &mctl_com->mapr);
203 /* Port 2 is reserved per Allwinner's linux-3.10 source, yet
204 * they initialise it */
205 MBUS_CONF( CPU, true, HIGHEST, 0, 300, 260, 150);
206 MBUS_CONF( GPU, true, HIGHEST, 0, 600, 400, 200);
207 MBUS_CONF( UNUSED, true, HIGHEST, 0, 512, 256, 96);
208 MBUS_CONF( DMA, true, HIGHEST, 0, 256, 128, 32);
209 MBUS_CONF( VE, true, HIGHEST, 0, 1900, 1500, 1000);
210 MBUS_CONF( CSI, true, HIGHEST, 0, 150, 120, 100);
211 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
212 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
213 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
214 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
217 * The port names are probably wrong, but no correct sources
220 MBUS_CONF( DE, true, HIGH, 0, 128, 48, 0);
221 MBUS_CONF( DE_CFD, true, HIGH, 0, 384, 256, 0);
222 MBUS_CONF(UNKNOWN1, true, HIGHEST, 0, 512, 384, 256);
223 MBUS_CONF(UNKNOWN2, true, HIGHEST, 2, 8192, 6144, 1024);
224 MBUS_CONF(UNKNOWN3, true, HIGH, 0, 1280, 144, 64);
227 static void mctl_set_master_priority(uint16_t socid)
231 mctl_set_master_priority_h3();
234 mctl_set_master_priority_a64();
237 mctl_set_master_priority_h5();
240 mctl_set_master_priority_r40();
245 static u32 bin_to_mgray(int val)
247 static const u8 lookup_table[32] = {
248 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
249 0x0c, 0x0d, 0x0e, 0x0f, 0x0a, 0x0b, 0x08, 0x09,
250 0x18, 0x19, 0x1a, 0x1b, 0x1e, 0x1f, 0x1c, 0x1d,
251 0x14, 0x15, 0x16, 0x17, 0x12, 0x13, 0x10, 0x11,
254 return lookup_table[clamp(val, 0, 31)];
257 static int mgray_to_bin(u32 val)
259 static const u8 lookup_table[32] = {
260 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
261 0x0e, 0x0f, 0x0c, 0x0d, 0x08, 0x09, 0x0a, 0x0b,
262 0x1e, 0x1f, 0x1c, 0x1d, 0x18, 0x19, 0x1a, 0x1b,
263 0x10, 0x11, 0x12, 0x13, 0x16, 0x17, 0x14, 0x15,
266 return lookup_table[val & 0x1f];
269 static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
271 struct sunxi_mctl_ctl_reg * const mctl_ctl =
272 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
275 #if defined CONFIG_SUNXI_DRAM_DW_16BIT
281 if ((readl(SUNXI_SRAMC_BASE + 0x24) & 0xff) == 0 &&
282 (readl(SUNXI_SRAMC_BASE + 0xf0) & 0x1) == 0) {
285 clrsetbits_le32(&mctl_ctl->zqcr, 0xffff,
286 CONFIG_DRAM_ZQ & 0xffff);
288 writel(PIR_CLRSR, &mctl_ctl->pir);
289 mctl_phy_init(PIR_ZCAL);
291 reg_val = readl(&mctl_ctl->zqdr[0]);
292 reg_val &= (0x1f << 16) | (0x1f << 0);
293 reg_val |= reg_val << 8;
294 writel(reg_val, &mctl_ctl->zqdr[0]);
296 reg_val = readl(&mctl_ctl->zqdr[1]);
297 reg_val &= (0x1f << 16) | (0x1f << 0);
298 reg_val |= reg_val << 8;
299 writel(reg_val, &mctl_ctl->zqdr[1]);
300 writel(reg_val, &mctl_ctl->zqdr[2]);
306 writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
308 for (i = 0; i < zq_count; i++) {
309 u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
311 writel((zq << 20) | (zq << 16) | (zq << 12) |
312 (zq << 8) | (zq << 4) | (zq << 0),
315 writel(PIR_CLRSR, &mctl_ctl->pir);
316 mctl_phy_init(PIR_ZCAL);
318 zq_val[i] = readl(&mctl_ctl->zqdr[0]) & 0xff;
319 writel(REPEAT_BYTE(zq_val[i]), &mctl_ctl->zqdr[2]);
321 writel(PIR_CLRSR, &mctl_ctl->pir);
322 mctl_phy_init(PIR_ZCAL);
324 val = readl(&mctl_ctl->zqdr[0]) >> 24;
325 zq_val[i] |= bin_to_mgray(mgray_to_bin(val) - 1) << 8;
328 writel((zq_val[1] << 16) | zq_val[0], &mctl_ctl->zqdr[0]);
329 writel((zq_val[3] << 16) | zq_val[2], &mctl_ctl->zqdr[1]);
331 writel((zq_val[5] << 16) | zq_val[4],
336 static void mctl_set_cr(uint16_t socid, struct dram_para *para)
338 struct sunxi_mctl_com_reg * const mctl_com =
339 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
341 writel(MCTL_CR_BL8 | MCTL_CR_INTERLEAVED |
342 #if defined CONFIG_SUNXI_DRAM_DDR3
343 MCTL_CR_DDR3 | MCTL_CR_2T |
344 #elif defined CONFIG_SUNXI_DRAM_DDR2
345 MCTL_CR_DDR2 | MCTL_CR_2T |
346 #elif defined CONFIG_SUNXI_DRAM_LPDDR3
347 MCTL_CR_LPDDR3 | MCTL_CR_1T |
349 #error Unsupported DRAM type!
351 (para->bank_bits == 3 ? MCTL_CR_EIGHT_BANKS : MCTL_CR_FOUR_BANKS) |
352 MCTL_CR_BUS_FULL_WIDTH(para->bus_full_width) |
353 (para->dual_rank ? MCTL_CR_DUAL_RANK : MCTL_CR_SINGLE_RANK) |
354 MCTL_CR_PAGE_SIZE(para->page_size) |
355 MCTL_CR_ROW_BITS(para->row_bits), &mctl_com->cr);
357 if (socid == SOCID_R40) {
359 panic("Dual rank memory not supported\n");
361 /* Mux pin to A15 address line for single rank memory. */
362 setbits_le32(&mctl_com->cr_r1, MCTL_CR_R1_MUX_A15);
366 static void mctl_sys_init(uint16_t socid, struct dram_para *para)
368 struct sunxi_ccm_reg * const ccm =
369 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
370 struct sunxi_mctl_ctl_reg * const mctl_ctl =
371 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
373 clrbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
374 clrbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
375 clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
376 clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
377 clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
378 if (socid == SOCID_A64 || socid == SOCID_R40)
379 clrbits_le32(&ccm->pll11_cfg, CCM_PLL11_CTRL_EN);
382 clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
385 if (socid == SOCID_A64 || socid == SOCID_R40) {
386 clock_set_pll11(CONFIG_DRAM_CLK * 2 * 1000000, false);
387 clrsetbits_le32(&ccm->dram_clk_cfg,
388 CCM_DRAMCLK_CFG_DIV_MASK |
389 CCM_DRAMCLK_CFG_SRC_MASK,
390 CCM_DRAMCLK_CFG_DIV(1) |
391 CCM_DRAMCLK_CFG_SRC_PLL11 |
392 CCM_DRAMCLK_CFG_UPD);
393 } else if (socid == SOCID_H3 || socid == SOCID_H5) {
394 clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false);
395 clrsetbits_le32(&ccm->dram_clk_cfg,
396 CCM_DRAMCLK_CFG_DIV_MASK |
397 CCM_DRAMCLK_CFG_SRC_MASK,
398 CCM_DRAMCLK_CFG_DIV(1) |
399 CCM_DRAMCLK_CFG_SRC_PLL5 |
400 CCM_DRAMCLK_CFG_UPD);
402 mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
404 setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
405 setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
406 setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
407 setbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
409 setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
412 writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken);
416 /* These are more guessed based on some Allwinner code. */
417 #define DX_GCR_ODT_DYNAMIC (0x0 << 4)
418 #define DX_GCR_ODT_ALWAYS_ON (0x1 << 4)
419 #define DX_GCR_ODT_OFF (0x2 << 4)
421 static int mctl_channel_init(uint16_t socid, struct dram_para *para)
423 struct sunxi_mctl_com_reg * const mctl_com =
424 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
425 struct sunxi_mctl_ctl_reg * const mctl_ctl =
426 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
430 mctl_set_cr(socid, para);
431 mctl_set_timing_params(socid, para);
432 mctl_set_master_priority(socid);
434 /* setting VTC, default disable all VT */
435 clrbits_le32(&mctl_ctl->pgcr[0], (1 << 30) | 0x3f);
436 if (socid == SOCID_H5)
437 setbits_le32(&mctl_ctl->pgcr[1], (1 << 24) | (1 << 26));
439 clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
441 /* increase DFI_PHY_UPD clock */
442 writel(PROTECT_MAGIC, &mctl_com->protect);
444 clrsetbits_le32(&mctl_ctl->upd2, 0xfff << 16, 0x50 << 16);
445 writel(0x0, &mctl_com->protect);
449 for (i = 0; i < 4; i++) {
450 u32 clearmask = (0x3 << 4) | (0x1 << 1) | (0x3 << 2) |
451 (0x3 << 12) | (0x3 << 14);
452 u32 setmask = IS_ENABLED(CONFIG_DRAM_ODT_EN) ?
453 DX_GCR_ODT_DYNAMIC : DX_GCR_ODT_OFF;
455 if (socid == SOCID_H5) {
456 clearmask |= 0x2 << 8;
459 clrsetbits_le32(&mctl_ctl->dx[i].gcr, clearmask, setmask);
462 /* AC PDR should always ON */
463 clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0,
466 /* set DQS auto gating PD mode */
467 setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
469 if (socid == SOCID_H3) {
470 /* dx ddr_clk & hdr_clk dynamic mode */
471 clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
473 /* dphy & aphy phase select 270 degree */
474 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
475 (0x1 << 10) | (0x2 << 8));
476 } else if (socid == SOCID_A64 || socid == SOCID_H5) {
477 /* dphy & aphy phase select ? */
478 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
479 (0x0 << 10) | (0x3 << 8));
480 } else if (socid == SOCID_R40) {
481 /* dx ddr_clk & hdr_clk dynamic mode (tpr13[9] == 0) */
482 clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
484 /* dphy & aphy phase select ? */
485 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
486 (0x0 << 10) | (0x3 << 8));
490 if (!para->bus_full_width) {
491 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
492 writel(0x0, &mctl_ctl->dx[2].gcr);
493 writel(0x0, &mctl_ctl->dx[3].gcr);
494 #elif defined CONFIG_SUNXI_DRAM_DW_16BIT
495 writel(0x0, &mctl_ctl->dx[1].gcr);
497 #error Unsupported DRAM bus width!
501 /* data training configuration */
502 clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24,
503 (para->dual_rank ? 0x3 : 0x1) << 24);
505 mctl_set_bit_delays(para);
508 if (socid == SOCID_H3) {
509 mctl_h3_zq_calibration_quirk(para);
511 mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
512 PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
513 } else if (socid == SOCID_A64 || socid == SOCID_H5) {
514 clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
516 mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
517 PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
518 /* no PIR_QSGATE for H5 ???? */
519 } else if (socid == SOCID_R40) {
520 clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
522 mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
523 PIR_DRAMRST | PIR_DRAMINIT);
526 /* detect ranks and bus width */
527 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
529 if (((readl(&mctl_ctl->dx[0].gsr[0]) >> 24) & 0x2)
530 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
531 || ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x2)
534 clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
538 /* only half DQ width */
539 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
540 if (((readl(&mctl_ctl->dx[2].gsr[0]) >> 24) & 0x1) ||
541 ((readl(&mctl_ctl->dx[3].gsr[0]) >> 24) & 0x1)) {
542 writel(0x0, &mctl_ctl->dx[2].gcr);
543 writel(0x0, &mctl_ctl->dx[3].gcr);
544 para->bus_full_width = 0;
546 #elif defined CONFIG_SUNXI_DRAM_DW_16BIT
547 if ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x1) {
548 writel(0x0, &mctl_ctl->dx[1].gcr);
549 para->bus_full_width = 0;
553 mctl_set_cr(socid, para);
557 mctl_phy_init(PIR_QSGATE);
558 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20))
562 /* check the dramc status */
563 mctl_await_completion(&mctl_ctl->statr, 0x1, 0x1);
565 /* liuke added for refresh debug */
566 setbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
568 clrbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
571 /* set PGCR3, CKE polarity */
572 if (socid == SOCID_H3)
573 writel(0x00aa0060, &mctl_ctl->pgcr[3]);
574 else if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40)
575 writel(0xc0aa0060, &mctl_ctl->pgcr[3]);
577 /* power down zq calibration module for power save */
578 setbits_le32(&mctl_ctl->zqcr, ZQCR_PWRDOWN);
580 /* enable master access */
581 writel(0xffffffff, &mctl_com->maer);
586 static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
588 /* detect row address bits */
589 para->page_size = 512;
592 mctl_set_cr(socid, para);
594 for (para->row_bits = 11; para->row_bits < 16; para->row_bits++)
595 if (mctl_mem_matches((1 << (para->row_bits + para->bank_bits)) * para->page_size))
598 /* detect bank address bits */
600 mctl_set_cr(socid, para);
602 for (para->bank_bits = 2; para->bank_bits < 3; para->bank_bits++)
603 if (mctl_mem_matches((1 << para->bank_bits) * para->page_size))
606 /* detect page size */
607 para->page_size = 8192;
608 mctl_set_cr(socid, para);
610 for (para->page_size = 512; para->page_size < 8192; para->page_size *= 2)
611 if (mctl_mem_matches(para->page_size))
616 * The actual values used here are taken from Allwinner provided boot0
617 * binaries, though they are probably board specific, so would likely benefit
618 * from invidual tuning for each board. Apparently a lot of boards copy from
619 * some Allwinner reference design, so we go with those generic values for now
620 * in the hope that they are reasonable for most (all?) boards.
622 #define SUN8I_H3_DX_READ_DELAYS \
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 { 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0 }, \
626 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }}
627 #define SUN8I_H3_DX_WRITE_DELAYS \
628 {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10 }, \
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, 6, 6 }}
632 #define SUN8I_H3_AC_DELAYS \
633 { 0, 0, 0, 0, 0, 0, 0, 0, \
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 }
638 #define SUN8I_R40_DX_READ_DELAYS \
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 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
642 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 } }
643 #define SUN8I_R40_DX_WRITE_DELAYS \
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 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 }, \
647 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 } }
648 #define SUN8I_R40_AC_DELAYS \
649 { 0, 0, 3, 0, 0, 0, 0, 0, \
650 0, 0, 0, 0, 0, 0, 0, 0, \
651 0, 0, 0, 0, 0, 0, 0, 0, \
652 0, 0, 0, 0, 0, 0, 0 }
654 #define SUN50I_A64_DX_READ_DELAYS \
655 {{ 16, 16, 16, 16, 17, 16, 16, 17, 16, 1, 0 }, \
656 { 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0 }, \
657 { 16, 17, 17, 16, 16, 16, 16, 16, 16, 0, 0 }, \
658 { 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0 }}
659 #define SUN50I_A64_DX_WRITE_DELAYS \
660 {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15 }, \
661 { 0, 0, 0, 0, 1, 1, 1, 1, 0, 10, 10 }, \
662 { 1, 0, 1, 1, 1, 1, 1, 1, 0, 11, 11 }, \
663 { 1, 0, 0, 1, 1, 1, 1, 1, 0, 12, 12 }}
664 #define SUN50I_A64_AC_DELAYS \
665 { 5, 5, 13, 10, 2, 5, 3, 3, \
666 0, 3, 3, 3, 1, 0, 0, 0, \
667 3, 4, 0, 3, 4, 1, 4, 0, \
668 1, 1, 0, 1, 13, 5, 4 }
670 #define SUN8I_H5_DX_READ_DELAYS \
671 {{ 14, 15, 17, 17, 17, 17, 17, 18, 17, 3, 3 }, \
672 { 21, 21, 12, 22, 21, 21, 21, 21, 21, 3, 3 }, \
673 { 16, 19, 19, 17, 22, 22, 21, 22, 19, 3, 3 }, \
674 { 21, 21, 22, 22, 20, 21, 19, 19, 19, 3, 3 } }
675 #define SUN8I_H5_DX_WRITE_DELAYS \
676 {{ 1, 2, 3, 4, 3, 4, 4, 4, 6, 6, 6 }, \
677 { 6, 6, 6, 5, 5, 5, 5, 5, 6, 6, 6 }, \
678 { 0, 2, 4, 2, 6, 5, 5, 5, 6, 6, 6 }, \
679 { 3, 3, 3, 2, 2, 1, 1, 1, 4, 4, 4 } }
680 #define SUN8I_H5_AC_DELAYS \
681 { 0, 0, 5, 5, 0, 0, 0, 0, \
682 0, 0, 0, 0, 3, 3, 3, 3, \
683 3, 3, 3, 3, 3, 3, 3, 3, \
684 3, 3, 3, 3, 2, 0, 0 }
686 unsigned long sunxi_dram_init(void)
688 struct sunxi_mctl_com_reg * const mctl_com =
689 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
690 struct sunxi_mctl_ctl_reg * const mctl_ctl =
691 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
693 struct dram_para para = {
700 #if defined(CONFIG_MACH_SUN8I_H3)
701 .dx_read_delays = SUN8I_H3_DX_READ_DELAYS,
702 .dx_write_delays = SUN8I_H3_DX_WRITE_DELAYS,
703 .ac_delays = SUN8I_H3_AC_DELAYS,
704 #elif defined(CONFIG_MACH_SUN8I_R40)
705 .dx_read_delays = SUN8I_R40_DX_READ_DELAYS,
706 .dx_write_delays = SUN8I_R40_DX_WRITE_DELAYS,
707 .ac_delays = SUN8I_R40_AC_DELAYS,
708 #elif defined(CONFIG_MACH_SUN50I)
709 .dx_read_delays = SUN50I_A64_DX_READ_DELAYS,
710 .dx_write_delays = SUN50I_A64_DX_WRITE_DELAYS,
711 .ac_delays = SUN50I_A64_AC_DELAYS,
712 #elif defined(CONFIG_MACH_SUN50I_H5)
713 .dx_read_delays = SUN8I_H5_DX_READ_DELAYS,
714 .dx_write_delays = SUN8I_H5_DX_WRITE_DELAYS,
715 .ac_delays = SUN8I_H5_AC_DELAYS,
719 * Let the compiler optimize alternatives away by passing this value into
720 * the static functions. This saves us #ifdefs, but still keeps the binary
723 #if defined(CONFIG_MACH_SUN8I_H3)
724 uint16_t socid = SOCID_H3;
725 #elif defined(CONFIG_MACH_SUN8I_R40)
726 uint16_t socid = SOCID_R40;
727 /* Currently we cannot support R40 with dual rank memory */
729 #elif defined(CONFIG_MACH_SUN8I_V3S)
730 /* TODO: set delays and mbus priority for V3s */
731 uint16_t socid = SOCID_H3;
732 #elif defined(CONFIG_MACH_SUN50I)
733 uint16_t socid = SOCID_A64;
734 #elif defined(CONFIG_MACH_SUN50I_H5)
735 uint16_t socid = SOCID_H5;
738 mctl_sys_init(socid, ¶);
739 if (mctl_channel_init(socid, ¶))
743 writel(0x00000303, &mctl_ctl->odtmap);
745 writel(0x00000201, &mctl_ctl->odtmap);
749 if (socid == SOCID_H3)
750 writel(0x0c000400, &mctl_ctl->odtcfg);
752 if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40) {
753 /* VTF enable (tpr13[8] == 1) */
754 setbits_le32(&mctl_ctl->vtfcr,
755 (socid != SOCID_A64 ? 3 : 2) << 8);
756 /* DQ hold disable (tpr13[26] == 1) */
757 clrbits_le32(&mctl_ctl->pgcr[2], (1 << 13));
760 /* clear credit value */
761 setbits_le32(&mctl_com->cccr, 1 << 31);
764 mctl_auto_detect_dram_size(socid, ¶);
765 mctl_set_cr(socid, ¶);
767 return (1UL << (para.row_bits + para.bank_bits)) * para.page_size *
768 (para.dual_rank ? 2 : 1);