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>
20 * The delay parameters below allow to allegedly specify delay times of some
21 * unknown unit for each individual bit trace in each of the four data bytes
22 * the 32-bit wide access consists of. Also three control signals can be
23 * adjusted individually.
25 #define BITS_PER_BYTE 8
26 #define NR_OF_BYTE_LANES (32 / BITS_PER_BYTE)
27 /* The eight data lines (DQn) plus DM, DQS and DQSN */
28 #define LINES_PER_BYTE_LANE (BITS_PER_BYTE + 3)
34 const u8 dx_read_delays[NR_OF_BYTE_LANES][LINES_PER_BYTE_LANE];
35 const u8 dx_write_delays[NR_OF_BYTE_LANES][LINES_PER_BYTE_LANE];
36 const u8 ac_delays[31];
39 static inline int ns_to_t(int nanoseconds)
41 const unsigned int ctrl_freq = CONFIG_DRAM_CLK / 2;
43 return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000);
46 static void mctl_phy_init(u32 val)
48 struct sunxi_mctl_ctl_reg * const mctl_ctl =
49 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
51 writel(val | PIR_INIT, &mctl_ctl->pir);
52 mctl_await_completion(&mctl_ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
55 static void mctl_set_bit_delays(struct dram_para *para)
57 struct sunxi_mctl_ctl_reg * const mctl_ctl =
58 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
61 clrbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
63 for (i = 0; i < NR_OF_BYTE_LANES; i++)
64 for (j = 0; j < LINES_PER_BYTE_LANE; j++)
65 writel(DXBDLR_WRITE_DELAY(para->dx_write_delays[i][j]) |
66 DXBDLR_READ_DELAY(para->dx_read_delays[i][j]),
67 &mctl_ctl->dx[i].bdlr[j]);
69 for (i = 0; i < 31; i++)
70 writel(ACBDLR_WRITE_DELAY(para->ac_delays[i]),
71 &mctl_ctl->acbdlr[i]);
73 #ifdef CONFIG_MACH_SUN8I_R40
74 /* DQSn, DMn, DQn output enable bit delay */
75 for (i = 0; i < 4; i++)
76 writel(0x6 << 24, &mctl_ctl->dx[i].sdlr);
79 setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
94 MBUS_PORT_DE_CFD = 11,
95 MBUS_PORT_UNKNOWN1 = 12,
96 MBUS_PORT_UNKNOWN2 = 13,
97 MBUS_PORT_UNKNOWN3 = 14,
107 inline void mbus_configure_port(u8 port,
110 u8 qos, /* MBUS_QOS_LOWEST .. MBUS_QOS_HIGEST */
111 u8 waittime, /* 0 .. 0xf */
112 u8 acs, /* 0 .. 0xff */
113 u16 bwl0, /* 0 .. 0xffff, bandwidth limit in MB/s */
117 struct sunxi_mctl_com_reg * const mctl_com =
118 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
120 const u32 cfg0 = ( (bwlimit ? (1 << 0) : 0)
121 | (priority ? (1 << 1) : 0)
123 | ((waittime & 0xf) << 4)
124 | ((acs & 0xff) << 8)
126 const u32 cfg1 = ((u32)bwl2 << 16) | (bwl1 & 0xffff);
128 debug("MBUS port %d cfg0 %08x cfg1 %08x\n", port, cfg0, cfg1);
129 writel(cfg0, &mctl_com->mcr[port][0]);
130 writel(cfg1, &mctl_com->mcr[port][1]);
133 #define MBUS_CONF(port, bwlimit, qos, acs, bwl0, bwl1, bwl2) \
134 mbus_configure_port(MBUS_PORT_ ## port, bwlimit, false, \
135 MBUS_QOS_ ## qos, 0, acs, bwl0, bwl1, bwl2)
137 static void mctl_set_master_priority_h3(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((1 << 16) | (400 << 0), &mctl_com->bwcr);
145 /* set cpu high priority */
146 writel(0x00000001, &mctl_com->mapr);
148 MBUS_CONF( CPU, true, HIGHEST, 0, 512, 256, 128);
149 MBUS_CONF( GPU, true, HIGH, 0, 1536, 1024, 256);
150 MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96);
151 MBUS_CONF( DMA, true, HIGHEST, 0, 256, 128, 32);
152 MBUS_CONF( VE, true, HIGH, 0, 1792, 1600, 256);
153 MBUS_CONF( CSI, true, HIGHEST, 0, 256, 128, 32);
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, HIGHEST, 3, 8192, 6120, 1024);
159 MBUS_CONF(DE_CFD, true, HIGH, 0, 1024, 288, 64);
162 static void mctl_set_master_priority_a64(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 /* Port 2 is reserved per Allwinner's linux-3.10 source, yet they
173 MBUS_CONF( CPU, true, HIGHEST, 0, 160, 100, 80);
174 MBUS_CONF( GPU, false, HIGH, 0, 1536, 1400, 256);
175 MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96);
176 MBUS_CONF( DMA, true, HIGH, 0, 256, 80, 100);
177 MBUS_CONF( VE, true, HIGH, 0, 1792, 1600, 256);
178 MBUS_CONF( CSI, true, HIGH, 0, 256, 128, 0);
179 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
180 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
181 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
182 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
183 MBUS_CONF( DE, true, HIGH, 2, 8192, 6144, 2048);
184 MBUS_CONF(DE_CFD, true, HIGH, 0, 1280, 144, 64);
186 writel(0x81000004, &mctl_com->mdfs_bwlr[2]);
189 static void mctl_set_master_priority_h5(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);
213 MBUS_CONF( DE, true, HIGHEST, 3, 3400, 2400, 1024);
214 MBUS_CONF(DE_CFD, true, HIGHEST, 0, 600, 400, 200);
217 static void mctl_set_master_priority_r40(void)
219 struct sunxi_mctl_com_reg * const mctl_com =
220 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
222 /* enable bandwidth limit windows and set windows size 1us */
223 writel(399, &mctl_com->tmr);
224 writel((1 << 16), &mctl_com->bwcr);
226 /* set cpu high priority */
227 writel(0x00000001, &mctl_com->mapr);
229 /* Port 2 is reserved per Allwinner's linux-3.10 source, yet
230 * they initialise it */
231 MBUS_CONF( CPU, true, HIGHEST, 0, 300, 260, 150);
232 MBUS_CONF( GPU, true, HIGHEST, 0, 600, 400, 200);
233 MBUS_CONF( UNUSED, true, HIGHEST, 0, 512, 256, 96);
234 MBUS_CONF( DMA, true, HIGHEST, 0, 256, 128, 32);
235 MBUS_CONF( VE, true, HIGHEST, 0, 1900, 1500, 1000);
236 MBUS_CONF( CSI, true, HIGHEST, 0, 150, 120, 100);
237 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
238 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
239 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
240 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
243 * The port names are probably wrong, but no correct sources
246 MBUS_CONF( DE, true, HIGH, 0, 128, 48, 0);
247 MBUS_CONF( DE_CFD, true, HIGH, 0, 384, 256, 0);
248 MBUS_CONF(UNKNOWN1, true, HIGHEST, 0, 512, 384, 256);
249 MBUS_CONF(UNKNOWN2, true, HIGHEST, 2, 8192, 6144, 1024);
250 MBUS_CONF(UNKNOWN3, true, HIGH, 0, 1280, 144, 64);
253 static void mctl_set_master_priority(uint16_t socid)
257 mctl_set_master_priority_h3();
260 mctl_set_master_priority_a64();
263 mctl_set_master_priority_h5();
266 mctl_set_master_priority_r40();
271 static void mctl_set_timing_params(uint16_t socid, struct dram_para *para)
273 struct sunxi_mctl_ctl_reg * const mctl_ctl =
274 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
277 u8 tfaw = ns_to_t(50);
278 u8 trrd = max(ns_to_t(10), 4);
279 u8 trcd = ns_to_t(15);
280 u8 trc = ns_to_t(53);
281 u8 txp = max(ns_to_t(8), 3);
282 u8 twtr = max(ns_to_t(8), 4);
283 u8 trtp = max(ns_to_t(8), 4);
284 u8 twr = max(ns_to_t(15), 3);
285 u8 trp = ns_to_t(15);
286 u8 tras = ns_to_t(38);
287 u16 trefi = ns_to_t(7800) / 32;
288 u16 trfc = ns_to_t(350);
299 u8 tcl = 6; /* CL 12 */
300 u8 tcwl = 4; /* CWL 8 */
304 u32 tdinit0 = (500 * CONFIG_DRAM_CLK) + 1; /* 500us */
305 u32 tdinit1 = (360 * CONFIG_DRAM_CLK) / 1000 + 1; /* 360ns */
306 u32 tdinit2 = (200 * CONFIG_DRAM_CLK) + 1; /* 200us */
307 u32 tdinit3 = (1 * CONFIG_DRAM_CLK) + 1; /* 1us */
309 u8 twtp = tcwl + 2 + twr; /* WL + BL / 2 + tWR */
310 u8 twr2rd = tcwl + 2 + twtr; /* WL + BL / 2 + tWTR */
311 u8 trd2wr = tcl + 2 + 1 - tcwl; /* RL + BL / 2 + 2 - WL */
313 /* set mode register */
314 writel(0x1c70, &mctl_ctl->mr[0]); /* CL=11, WR=12 */
315 writel(0x40, &mctl_ctl->mr[1]);
316 writel(0x18, &mctl_ctl->mr[2]); /* CWL=8 */
317 writel(0x0, &mctl_ctl->mr[3]);
319 if (socid == SOCID_R40)
320 writel(0x3, &mctl_ctl->lp3mr11); /* odt_en[7:4] */
322 /* set DRAM timing */
323 writel(DRAMTMG0_TWTP(twtp) | DRAMTMG0_TFAW(tfaw) |
324 DRAMTMG0_TRAS_MAX(trasmax) | DRAMTMG0_TRAS(tras),
325 &mctl_ctl->dramtmg[0]);
326 writel(DRAMTMG1_TXP(txp) | DRAMTMG1_TRTP(trtp) | DRAMTMG1_TRC(trc),
327 &mctl_ctl->dramtmg[1]);
328 writel(DRAMTMG2_TCWL(tcwl) | DRAMTMG2_TCL(tcl) |
329 DRAMTMG2_TRD2WR(trd2wr) | DRAMTMG2_TWR2RD(twr2rd),
330 &mctl_ctl->dramtmg[2]);
331 writel(DRAMTMG3_TMRW(tmrw) | DRAMTMG3_TMRD(tmrd) | DRAMTMG3_TMOD(tmod),
332 &mctl_ctl->dramtmg[3]);
333 writel(DRAMTMG4_TRCD(trcd) | DRAMTMG4_TCCD(tccd) | DRAMTMG4_TRRD(trrd) |
334 DRAMTMG4_TRP(trp), &mctl_ctl->dramtmg[4]);
335 writel(DRAMTMG5_TCKSRX(tcksrx) | DRAMTMG5_TCKSRE(tcksre) |
336 DRAMTMG5_TCKESR(tckesr) | DRAMTMG5_TCKE(tcke),
337 &mctl_ctl->dramtmg[5]);
339 /* set two rank timing */
340 clrsetbits_le32(&mctl_ctl->dramtmg[8], (0xff << 8) | (0xff << 0),
341 ((socid == SOCID_H5 ? 0x33 : 0x66) << 8) | (0x10 << 0));
343 /* set PHY interface timing, write latency and read latency configure */
344 writel((0x2 << 24) | (t_rdata_en << 16) | (0x1 << 8) |
345 (wr_latency << 0), &mctl_ctl->pitmg[0]);
347 /* set PHY timing, PTR0-2 use default */
348 writel(PTR3_TDINIT0(tdinit0) | PTR3_TDINIT1(tdinit1), &mctl_ctl->ptr[3]);
349 writel(PTR4_TDINIT2(tdinit2) | PTR4_TDINIT3(tdinit3), &mctl_ctl->ptr[4]);
351 /* set refresh timing */
352 writel(RFSHTMG_TREFI(trefi) | RFSHTMG_TRFC(trfc), &mctl_ctl->rfshtmg);
355 static u32 bin_to_mgray(int val)
357 static const u8 lookup_table[32] = {
358 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
359 0x0c, 0x0d, 0x0e, 0x0f, 0x0a, 0x0b, 0x08, 0x09,
360 0x18, 0x19, 0x1a, 0x1b, 0x1e, 0x1f, 0x1c, 0x1d,
361 0x14, 0x15, 0x16, 0x17, 0x12, 0x13, 0x10, 0x11,
364 return lookup_table[clamp(val, 0, 31)];
367 static int mgray_to_bin(u32 val)
369 static const u8 lookup_table[32] = {
370 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
371 0x0e, 0x0f, 0x0c, 0x0d, 0x08, 0x09, 0x0a, 0x0b,
372 0x1e, 0x1f, 0x1c, 0x1d, 0x18, 0x19, 0x1a, 0x1b,
373 0x10, 0x11, 0x12, 0x13, 0x16, 0x17, 0x14, 0x15,
376 return lookup_table[val & 0x1f];
379 static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
381 struct sunxi_mctl_ctl_reg * const mctl_ctl =
382 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
384 if ((readl(SUNXI_SRAMC_BASE + 0x24) & 0xff) == 0 &&
385 (readl(SUNXI_SRAMC_BASE + 0xf0) & 0x1) == 0) {
388 clrsetbits_le32(&mctl_ctl->zqcr, 0xffff,
389 CONFIG_DRAM_ZQ & 0xffff);
391 writel(PIR_CLRSR, &mctl_ctl->pir);
392 mctl_phy_init(PIR_ZCAL);
394 reg_val = readl(&mctl_ctl->zqdr[0]);
395 reg_val &= (0x1f << 16) | (0x1f << 0);
396 reg_val |= reg_val << 8;
397 writel(reg_val, &mctl_ctl->zqdr[0]);
399 reg_val = readl(&mctl_ctl->zqdr[1]);
400 reg_val &= (0x1f << 16) | (0x1f << 0);
401 reg_val |= reg_val << 8;
402 writel(reg_val, &mctl_ctl->zqdr[1]);
403 writel(reg_val, &mctl_ctl->zqdr[2]);
409 writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
411 for (i = 0; i < 6; i++) {
412 u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
414 writel((zq << 20) | (zq << 16) | (zq << 12) |
415 (zq << 8) | (zq << 4) | (zq << 0),
418 writel(PIR_CLRSR, &mctl_ctl->pir);
419 mctl_phy_init(PIR_ZCAL);
421 zq_val[i] = readl(&mctl_ctl->zqdr[0]) & 0xff;
422 writel(REPEAT_BYTE(zq_val[i]), &mctl_ctl->zqdr[2]);
424 writel(PIR_CLRSR, &mctl_ctl->pir);
425 mctl_phy_init(PIR_ZCAL);
427 val = readl(&mctl_ctl->zqdr[0]) >> 24;
428 zq_val[i] |= bin_to_mgray(mgray_to_bin(val) - 1) << 8;
431 writel((zq_val[1] << 16) | zq_val[0], &mctl_ctl->zqdr[0]);
432 writel((zq_val[3] << 16) | zq_val[2], &mctl_ctl->zqdr[1]);
433 writel((zq_val[5] << 16) | zq_val[4], &mctl_ctl->zqdr[2]);
437 static void mctl_set_cr(uint16_t socid, struct dram_para *para)
439 struct sunxi_mctl_com_reg * const mctl_com =
440 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
442 writel(MCTL_CR_BL8 | MCTL_CR_2T | MCTL_CR_DDR3 | MCTL_CR_INTERLEAVED |
443 MCTL_CR_EIGHT_BANKS | MCTL_CR_BUS_WIDTH(para->bus_width) |
444 (para->dual_rank ? MCTL_CR_DUAL_RANK : MCTL_CR_SINGLE_RANK) |
445 MCTL_CR_PAGE_SIZE(para->page_size) |
446 MCTL_CR_ROW_BITS(para->row_bits), &mctl_com->cr);
448 if (socid == SOCID_R40) {
450 panic("Dual rank memory not supported\n");
452 /* Mux pin to A15 address line for single rank memory. */
453 setbits_le32(&mctl_com->cr_r1, MCTL_CR_R1_MUX_A15);
457 static void mctl_sys_init(uint16_t socid, struct dram_para *para)
459 struct sunxi_ccm_reg * const ccm =
460 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
461 struct sunxi_mctl_ctl_reg * const mctl_ctl =
462 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
464 clrbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
465 clrbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
466 clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
467 clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
468 clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
469 if (socid == SOCID_A64 || socid == SOCID_R40)
470 clrbits_le32(&ccm->pll11_cfg, CCM_PLL11_CTRL_EN);
473 clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
476 if (socid == SOCID_A64 || socid == SOCID_R40) {
477 clock_set_pll11(CONFIG_DRAM_CLK * 2 * 1000000, false);
478 clrsetbits_le32(&ccm->dram_clk_cfg,
479 CCM_DRAMCLK_CFG_DIV_MASK |
480 CCM_DRAMCLK_CFG_SRC_MASK,
481 CCM_DRAMCLK_CFG_DIV(1) |
482 CCM_DRAMCLK_CFG_SRC_PLL11 |
483 CCM_DRAMCLK_CFG_UPD);
484 } else if (socid == SOCID_H3 || socid == SOCID_H5) {
485 clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false);
486 clrsetbits_le32(&ccm->dram_clk_cfg,
487 CCM_DRAMCLK_CFG_DIV_MASK |
488 CCM_DRAMCLK_CFG_SRC_MASK,
489 CCM_DRAMCLK_CFG_DIV(1) |
490 CCM_DRAMCLK_CFG_SRC_PLL5 |
491 CCM_DRAMCLK_CFG_UPD);
493 mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
495 setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
496 setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
497 setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
498 setbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
500 setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
503 writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken);
507 /* These are more guessed based on some Allwinner code. */
508 #define DX_GCR_ODT_DYNAMIC (0x0 << 4)
509 #define DX_GCR_ODT_ALWAYS_ON (0x1 << 4)
510 #define DX_GCR_ODT_OFF (0x2 << 4)
512 static int mctl_channel_init(uint16_t socid, struct dram_para *para)
514 struct sunxi_mctl_com_reg * const mctl_com =
515 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
516 struct sunxi_mctl_ctl_reg * const mctl_ctl =
517 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
521 mctl_set_cr(socid, para);
522 mctl_set_timing_params(socid, para);
523 mctl_set_master_priority(socid);
525 /* setting VTC, default disable all VT */
526 clrbits_le32(&mctl_ctl->pgcr[0], (1 << 30) | 0x3f);
527 if (socid == SOCID_H5)
528 setbits_le32(&mctl_ctl->pgcr[1], (1 << 24) | (1 << 26));
530 clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
532 /* increase DFI_PHY_UPD clock */
533 writel(PROTECT_MAGIC, &mctl_com->protect);
535 clrsetbits_le32(&mctl_ctl->upd2, 0xfff << 16, 0x50 << 16);
536 writel(0x0, &mctl_com->protect);
540 for (i = 0; i < 4; i++) {
541 u32 clearmask = (0x3 << 4) | (0x1 << 1) | (0x3 << 2) |
542 (0x3 << 12) | (0x3 << 14);
543 u32 setmask = IS_ENABLED(CONFIG_DRAM_ODT_EN) ?
544 DX_GCR_ODT_DYNAMIC : DX_GCR_ODT_OFF;
546 if (socid == SOCID_H5) {
547 clearmask |= 0x2 << 8;
550 clrsetbits_le32(&mctl_ctl->dx[i].gcr, clearmask, setmask);
553 /* AC PDR should always ON */
554 clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0,
557 /* set DQS auto gating PD mode */
558 setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
560 if (socid == SOCID_H3) {
561 /* dx ddr_clk & hdr_clk dynamic mode */
562 clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
564 /* dphy & aphy phase select 270 degree */
565 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
566 (0x1 << 10) | (0x2 << 8));
567 } else if (socid == SOCID_A64 || socid == SOCID_H5) {
568 /* dphy & aphy phase select ? */
569 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
570 (0x0 << 10) | (0x3 << 8));
571 } else if (socid == SOCID_R40) {
572 /* dx ddr_clk & hdr_clk dynamic mode (tpr13[9] == 0) */
573 clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
575 /* dphy & aphy phase select ? */
576 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
577 (0x0 << 10) | (0x3 << 8));
581 if (para->bus_width != 32) {
582 writel(0x0, &mctl_ctl->dx[2].gcr);
583 writel(0x0, &mctl_ctl->dx[3].gcr);
586 /* data training configuration */
587 clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24,
588 (para->dual_rank ? 0x3 : 0x1) << 24);
590 mctl_set_bit_delays(para);
593 if (socid == SOCID_H3) {
594 mctl_h3_zq_calibration_quirk(para);
596 mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
597 PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
598 } else if (socid == SOCID_A64 || socid == SOCID_H5) {
599 clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
601 mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
602 PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
603 /* no PIR_QSGATE for H5 ???? */
604 } else if (socid == SOCID_R40) {
605 clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
607 mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
608 PIR_DRAMRST | PIR_DRAMINIT);
611 /* detect ranks and bus width */
612 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
614 if (((readl(&mctl_ctl->dx[0].gsr[0]) >> 24) & 0x2) ||
615 ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x2)) {
616 clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
620 /* only half DQ width */
621 if (((readl(&mctl_ctl->dx[2].gsr[0]) >> 24) & 0x1) ||
622 ((readl(&mctl_ctl->dx[3].gsr[0]) >> 24) & 0x1)) {
623 writel(0x0, &mctl_ctl->dx[2].gcr);
624 writel(0x0, &mctl_ctl->dx[3].gcr);
625 para->bus_width = 16;
628 mctl_set_cr(socid, para);
632 mctl_phy_init(PIR_QSGATE);
633 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20))
637 /* check the dramc status */
638 mctl_await_completion(&mctl_ctl->statr, 0x1, 0x1);
640 /* liuke added for refresh debug */
641 setbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
643 clrbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
646 /* set PGCR3, CKE polarity */
647 if (socid == SOCID_H3)
648 writel(0x00aa0060, &mctl_ctl->pgcr[3]);
649 else if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40)
650 writel(0xc0aa0060, &mctl_ctl->pgcr[3]);
652 /* power down zq calibration module for power save */
653 setbits_le32(&mctl_ctl->zqcr, ZQCR_PWRDOWN);
655 /* enable master access */
656 writel(0xffffffff, &mctl_com->maer);
661 static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
663 /* detect row address bits */
664 para->page_size = 512;
666 mctl_set_cr(socid, para);
668 for (para->row_bits = 11; para->row_bits < 16; para->row_bits++)
669 if (mctl_mem_matches((1 << (para->row_bits + 3)) * para->page_size))
672 /* detect page size */
673 para->page_size = 8192;
674 mctl_set_cr(socid, para);
676 for (para->page_size = 512; para->page_size < 8192; para->page_size *= 2)
677 if (mctl_mem_matches(para->page_size))
682 * The actual values used here are taken from Allwinner provided boot0
683 * binaries, though they are probably board specific, so would likely benefit
684 * from invidual tuning for each board. Apparently a lot of boards copy from
685 * some Allwinner reference design, so we go with those generic values for now
686 * in the hope that they are reasonable for most (all?) boards.
688 #define SUN8I_H3_DX_READ_DELAYS \
689 {{ 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0 }, \
690 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
691 { 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0 }, \
692 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }}
693 #define SUN8I_H3_DX_WRITE_DELAYS \
694 {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10 }, \
695 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10 }, \
696 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10 }, \
697 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6 }}
698 #define SUN8I_H3_AC_DELAYS \
699 { 0, 0, 0, 0, 0, 0, 0, 0, \
700 0, 0, 0, 0, 0, 0, 0, 0, \
701 0, 0, 0, 0, 0, 0, 0, 0, \
702 0, 0, 0, 0, 0, 0, 0 }
704 #define SUN8I_R40_DX_READ_DELAYS \
705 {{ 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
706 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
707 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
708 { 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 } }
709 #define SUN8I_R40_DX_WRITE_DELAYS \
710 {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 }, \
711 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 }, \
712 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 }, \
713 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0 } }
714 #define SUN8I_R40_AC_DELAYS \
715 { 0, 0, 3, 0, 0, 0, 0, 0, \
716 0, 0, 0, 0, 0, 0, 0, 0, \
717 0, 0, 0, 0, 0, 0, 0, 0, \
718 0, 0, 0, 0, 0, 0, 0 }
720 #define SUN50I_A64_DX_READ_DELAYS \
721 {{ 16, 16, 16, 16, 17, 16, 16, 17, 16, 1, 0 }, \
722 { 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0 }, \
723 { 16, 17, 17, 16, 16, 16, 16, 16, 16, 0, 0 }, \
724 { 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0 }}
725 #define SUN50I_A64_DX_WRITE_DELAYS \
726 {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15 }, \
727 { 0, 0, 0, 0, 1, 1, 1, 1, 0, 10, 10 }, \
728 { 1, 0, 1, 1, 1, 1, 1, 1, 0, 11, 11 }, \
729 { 1, 0, 0, 1, 1, 1, 1, 1, 0, 12, 12 }}
730 #define SUN50I_A64_AC_DELAYS \
731 { 5, 5, 13, 10, 2, 5, 3, 3, \
732 0, 3, 3, 3, 1, 0, 0, 0, \
733 3, 4, 0, 3, 4, 1, 4, 0, \
734 1, 1, 0, 1, 13, 5, 4 }
736 #define SUN8I_H5_DX_READ_DELAYS \
737 {{ 14, 15, 17, 17, 17, 17, 17, 18, 17, 3, 3 }, \
738 { 21, 21, 12, 22, 21, 21, 21, 21, 21, 3, 3 }, \
739 { 16, 19, 19, 17, 22, 22, 21, 22, 19, 3, 3 }, \
740 { 21, 21, 22, 22, 20, 21, 19, 19, 19, 3, 3 } }
741 #define SUN8I_H5_DX_WRITE_DELAYS \
742 {{ 1, 2, 3, 4, 3, 4, 4, 4, 6, 6, 6 }, \
743 { 6, 6, 6, 5, 5, 5, 5, 5, 6, 6, 6 }, \
744 { 0, 2, 4, 2, 6, 5, 5, 5, 6, 6, 6 }, \
745 { 3, 3, 3, 2, 2, 1, 1, 1, 4, 4, 4 } }
746 #define SUN8I_H5_AC_DELAYS \
747 { 0, 0, 5, 5, 0, 0, 0, 0, \
748 0, 0, 0, 0, 3, 3, 3, 3, \
749 3, 3, 3, 3, 3, 3, 3, 3, \
750 3, 3, 3, 3, 2, 0, 0 }
752 unsigned long sunxi_dram_init(void)
754 struct sunxi_mctl_com_reg * const mctl_com =
755 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
756 struct sunxi_mctl_ctl_reg * const mctl_ctl =
757 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
759 struct dram_para para = {
765 #if defined(CONFIG_MACH_SUN8I_H3)
766 .dx_read_delays = SUN8I_H3_DX_READ_DELAYS,
767 .dx_write_delays = SUN8I_H3_DX_WRITE_DELAYS,
768 .ac_delays = SUN8I_H3_AC_DELAYS,
769 #elif defined(CONFIG_MACH_SUN8I_R40)
770 .dx_read_delays = SUN8I_R40_DX_READ_DELAYS,
771 .dx_write_delays = SUN8I_R40_DX_WRITE_DELAYS,
772 .ac_delays = SUN8I_R40_AC_DELAYS,
773 #elif defined(CONFIG_MACH_SUN50I)
774 .dx_read_delays = SUN50I_A64_DX_READ_DELAYS,
775 .dx_write_delays = SUN50I_A64_DX_WRITE_DELAYS,
776 .ac_delays = SUN50I_A64_AC_DELAYS,
777 #elif defined(CONFIG_MACH_SUN50I_H5)
778 .dx_read_delays = SUN8I_H5_DX_READ_DELAYS,
779 .dx_write_delays = SUN8I_H5_DX_WRITE_DELAYS,
780 .ac_delays = SUN8I_H5_AC_DELAYS,
784 * Let the compiler optimize alternatives away by passing this value into
785 * the static functions. This saves us #ifdefs, but still keeps the binary
788 #if defined(CONFIG_MACH_SUN8I_H3)
789 uint16_t socid = SOCID_H3;
790 #elif defined(CONFIG_MACH_SUN8I_R40)
791 uint16_t socid = SOCID_R40;
792 #elif defined(CONFIG_MACH_SUN50I)
793 uint16_t socid = SOCID_A64;
794 #elif defined(CONFIG_MACH_SUN50I_H5)
795 uint16_t socid = SOCID_H5;
798 mctl_sys_init(socid, ¶);
799 if (mctl_channel_init(socid, ¶))
803 writel(0x00000303, &mctl_ctl->odtmap);
805 writel(0x00000201, &mctl_ctl->odtmap);
809 if (socid == SOCID_H3)
810 writel(0x0c000400, &mctl_ctl->odtcfg);
812 if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40) {
813 /* VTF enable (tpr13[8] == 1) */
814 setbits_le32(&mctl_ctl->vtfcr,
815 (socid != SOCID_A64 ? 3 : 2) << 8);
816 /* DQ hold disable (tpr13[26] == 1) */
817 clrbits_le32(&mctl_ctl->pgcr[2], (1 << 13));
820 /* clear credit value */
821 setbits_le32(&mctl_com->cccr, 1 << 31);
824 mctl_auto_detect_dram_size(socid, ¶);
825 mctl_set_cr(socid, ¶);
827 return (1UL << (para.row_bits + 3)) * para.page_size *
828 (para.dual_rank ? 2 : 1);