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>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/dram.h>
15 #include <asm/arch/cpu.h>
16 #include <linux/kconfig.h>
18 static void mctl_phy_init(u32 val)
20 struct sunxi_mctl_ctl_reg * const mctl_ctl =
21 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
23 writel(val | PIR_INIT, &mctl_ctl->pir);
24 mctl_await_completion(&mctl_ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
27 static void mctl_set_bit_delays(struct dram_para *para)
29 struct sunxi_mctl_ctl_reg * const mctl_ctl =
30 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
33 clrbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
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]);
41 for (i = 0; i < 31; i++)
42 writel(ACBDLR_WRITE_DELAY(para->ac_delays[i]),
43 &mctl_ctl->acbdlr[i]);
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);
51 setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
66 MBUS_PORT_DE_CFD = 11,
67 MBUS_PORT_UNKNOWN1 = 12,
68 MBUS_PORT_UNKNOWN2 = 13,
69 MBUS_PORT_UNKNOWN3 = 14,
79 inline void mbus_configure_port(u8 port,
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 */
89 struct sunxi_mctl_com_reg * const mctl_com =
90 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
92 const u32 cfg0 = ( (bwlimit ? (1 << 0) : 0)
93 | (priority ? (1 << 1) : 0)
95 | ((waittime & 0xf) << 4)
98 const u32 cfg1 = ((u32)bwl2 << 16) | (bwl1 & 0xffff);
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]);
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)
109 static void mctl_set_master_priority_h3(void)
111 struct sunxi_mctl_com_reg * const mctl_com =
112 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
114 /* enable bandwidth limit windows and set windows size 1us */
115 writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
117 /* set cpu high priority */
118 writel(0x00000001, &mctl_com->mapr);
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);
134 static void mctl_set_master_priority_a64(void)
136 struct sunxi_mctl_com_reg * const mctl_com =
137 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
139 /* enable bandwidth limit windows and set windows size 1us */
140 writel(399, &mctl_com->tmr);
141 writel((1 << 16), &mctl_com->bwcr);
143 /* Port 2 is reserved per Allwinner's linux-3.10 source, yet they
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);
158 writel(0x81000004, &mctl_com->mdfs_bwlr[2]);
161 static void mctl_set_master_priority_h5(void)
163 struct sunxi_mctl_com_reg * const mctl_com =
164 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
166 /* enable bandwidth limit windows and set windows size 1us */
167 writel(399, &mctl_com->tmr);
168 writel((1 << 16), &mctl_com->bwcr);
170 /* set cpu high priority */
171 writel(0x00000001, &mctl_com->mapr);
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);
189 static void mctl_set_master_priority_r40(void)
191 struct sunxi_mctl_com_reg * const mctl_com =
192 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
194 /* enable bandwidth limit windows and set windows size 1us */
195 writel(399, &mctl_com->tmr);
196 writel((1 << 16), &mctl_com->bwcr);
198 /* set cpu high priority */
199 writel(0x00000001, &mctl_com->mapr);
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);
215 * The port names are probably wrong, but no correct sources
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);
225 static void mctl_set_master_priority(uint16_t socid)
229 mctl_set_master_priority_h3();
232 mctl_set_master_priority_a64();
235 mctl_set_master_priority_h5();
238 mctl_set_master_priority_r40();
243 static u32 bin_to_mgray(int val)
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,
252 return lookup_table[clamp(val, 0, 31)];
255 static int mgray_to_bin(u32 val)
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,
264 return lookup_table[val & 0x1f];
267 static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
269 struct sunxi_mctl_ctl_reg * const mctl_ctl =
270 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
273 #if defined CONFIG_SUNXI_DRAM_DW_16BIT
279 if ((readl(SUNXI_SRAMC_BASE + 0x24) & 0xff) == 0 &&
280 (readl(SUNXI_SRAMC_BASE + 0xf0) & 0x1) == 0) {
283 clrsetbits_le32(&mctl_ctl->zqcr, 0xffff,
284 CONFIG_DRAM_ZQ & 0xffff);
286 writel(PIR_CLRSR, &mctl_ctl->pir);
287 mctl_phy_init(PIR_ZCAL);
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]);
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]);
304 writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
306 for (i = 0; i < zq_count; i++) {
307 u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
309 writel((zq << 20) | (zq << 16) | (zq << 12) |
310 (zq << 8) | (zq << 4) | (zq << 0),
313 writel(PIR_CLRSR, &mctl_ctl->pir);
314 mctl_phy_init(PIR_ZCAL);
316 zq_val[i] = readl(&mctl_ctl->zqdr[0]) & 0xff;
317 writel(REPEAT_BYTE(zq_val[i]), &mctl_ctl->zqdr[2]);
319 writel(PIR_CLRSR, &mctl_ctl->pir);
320 mctl_phy_init(PIR_ZCAL);
322 val = readl(&mctl_ctl->zqdr[0]) >> 24;
323 zq_val[i] |= bin_to_mgray(mgray_to_bin(val) - 1) << 8;
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]);
329 writel((zq_val[5] << 16) | zq_val[4],
334 static void mctl_set_cr(uint16_t socid, struct dram_para *para)
336 struct sunxi_mctl_com_reg * const mctl_com =
337 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
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 |
347 #error Unsupported DRAM type!
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);
355 if (socid == SOCID_R40) {
357 panic("Dual rank memory not supported\n");
359 /* Mux pin to A15 address line for single rank memory. */
360 setbits_le32(&mctl_com->cr_r1, MCTL_CR_R1_MUX_A15);
364 static void mctl_sys_init(uint16_t socid, struct dram_para *para)
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;
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);
380 clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
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);
400 mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
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);
407 setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
410 writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken);
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)
419 static int mctl_channel_init(uint16_t socid, struct dram_para *para)
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;
428 mctl_set_cr(socid, para);
429 mctl_set_timing_params(socid, para);
430 mctl_set_master_priority(socid);
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));
437 clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
439 /* increase DFI_PHY_UPD clock */
440 writel(PROTECT_MAGIC, &mctl_com->protect);
442 clrsetbits_le32(&mctl_ctl->upd2, 0xfff << 16, 0x50 << 16);
443 writel(0x0, &mctl_com->protect);
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;
453 if (socid == SOCID_H5) {
454 clearmask |= 0x2 << 8;
457 clrsetbits_le32(&mctl_ctl->dx[i].gcr, clearmask, setmask);
460 /* AC PDR should always ON */
461 clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0,
464 /* set DQS auto gating PD mode */
465 setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
467 if (socid == SOCID_H3) {
468 /* dx ddr_clk & hdr_clk dynamic mode */
469 clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
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));
482 /* dphy & aphy phase select ? */
483 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
484 (0x0 << 10) | (0x3 << 8));
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);
495 #error Unsupported DRAM bus width!
499 /* data training configuration */
500 clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24,
501 (para->dual_rank ? 0x3 : 0x1) << 24);
503 mctl_set_bit_delays(para);
506 if (socid == SOCID_H3) {
507 mctl_h3_zq_calibration_quirk(para);
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);
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);
520 mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
521 PIR_DRAMRST | PIR_DRAMINIT);
524 /* detect ranks and bus width */
525 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
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)
532 clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
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;
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;
551 mctl_set_cr(socid, para);
555 mctl_phy_init(PIR_QSGATE);
556 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20))
560 /* check the dramc status */
561 mctl_await_completion(&mctl_ctl->statr, 0x1, 0x1);
563 /* liuke added for refresh debug */
564 setbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
566 clrbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
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]);
575 /* power down zq calibration module for power save */
576 setbits_le32(&mctl_ctl->zqcr, ZQCR_PWRDOWN);
578 /* enable master access */
579 writel(0xffffffff, &mctl_com->maer);
584 static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
586 /* detect row address bits */
587 para->page_size = 512;
590 mctl_set_cr(socid, para);
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))
596 /* detect bank address bits */
598 mctl_set_cr(socid, para);
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))
604 /* detect page size */
605 para->page_size = 8192;
606 mctl_set_cr(socid, para);
608 for (para->page_size = 512; para->page_size < 8192; para->page_size *= 2)
609 if (mctl_mem_matches(para->page_size))
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.
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 }
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 }
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 }
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 }
684 unsigned long sunxi_dram_init(void)
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;
691 struct dram_para para = {
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,
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
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 */
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;
736 mctl_sys_init(socid, ¶);
737 if (mctl_channel_init(socid, ¶))
741 writel(0x00000303, &mctl_ctl->odtmap);
743 writel(0x00000201, &mctl_ctl->odtmap);
747 if (socid == SOCID_H3)
748 writel(0x0c000400, &mctl_ctl->odtcfg);
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));
758 /* clear credit value */
759 setbits_le32(&mctl_com->cccr, 1 << 31);
762 mctl_auto_detect_dram_size(socid, ¶);
763 mctl_set_cr(socid, ¶);
765 return (1UL << (para.row_bits + para.bank_bits)) * para.page_size *
766 (para.dual_rank ? 2 : 1);