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 setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
88 MBUS_PORT_DE_CFD = 11,
98 inline void mbus_configure_port(u8 port,
101 u8 qos, /* MBUS_QOS_LOWEST .. MBUS_QOS_HIGEST */
102 u8 waittime, /* 0 .. 0xf */
103 u8 acs, /* 0 .. 0xff */
104 u16 bwl0, /* 0 .. 0xffff, bandwidth limit in MB/s */
108 struct sunxi_mctl_com_reg * const mctl_com =
109 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
111 const u32 cfg0 = ( (bwlimit ? (1 << 0) : 0)
112 | (priority ? (1 << 1) : 0)
114 | ((waittime & 0xf) << 4)
115 | ((acs & 0xff) << 8)
117 const u32 cfg1 = ((u32)bwl2 << 16) | (bwl1 & 0xffff);
119 debug("MBUS port %d cfg0 %08x cfg1 %08x\n", port, cfg0, cfg1);
120 writel(cfg0, &mctl_com->mcr[port][0]);
121 writel(cfg1, &mctl_com->mcr[port][1]);
124 #define MBUS_CONF(port, bwlimit, qos, acs, bwl0, bwl1, bwl2) \
125 mbus_configure_port(MBUS_PORT_ ## port, bwlimit, false, \
126 MBUS_QOS_ ## qos, 0, acs, bwl0, bwl1, bwl2)
128 static void mctl_set_master_priority_h3(void)
130 struct sunxi_mctl_com_reg * const mctl_com =
131 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
133 /* enable bandwidth limit windows and set windows size 1us */
134 writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
136 /* set cpu high priority */
137 writel(0x00000001, &mctl_com->mapr);
139 MBUS_CONF( CPU, true, HIGHEST, 0, 512, 256, 128);
140 MBUS_CONF( GPU, true, HIGH, 0, 1536, 1024, 256);
141 MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96);
142 MBUS_CONF( DMA, true, HIGHEST, 0, 256, 128, 32);
143 MBUS_CONF( VE, true, HIGH, 0, 1792, 1600, 256);
144 MBUS_CONF( CSI, true, HIGHEST, 0, 256, 128, 32);
145 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
146 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
147 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
148 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
149 MBUS_CONF( DE, true, HIGHEST, 3, 8192, 6120, 1024);
150 MBUS_CONF(DE_CFD, true, HIGH, 0, 1024, 288, 64);
153 static void mctl_set_master_priority_a64(void)
155 struct sunxi_mctl_com_reg * const mctl_com =
156 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
158 /* enable bandwidth limit windows and set windows size 1us */
159 writel(399, &mctl_com->tmr);
160 writel((1 << 16), &mctl_com->bwcr);
162 /* Port 2 is reserved per Allwinner's linux-3.10 source, yet they
164 MBUS_CONF( CPU, true, HIGHEST, 0, 160, 100, 80);
165 MBUS_CONF( GPU, false, HIGH, 0, 1536, 1400, 256);
166 MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96);
167 MBUS_CONF( DMA, true, HIGH, 0, 256, 80, 100);
168 MBUS_CONF( VE, true, HIGH, 0, 1792, 1600, 256);
169 MBUS_CONF( CSI, true, HIGH, 0, 256, 128, 0);
170 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
171 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
172 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
173 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
174 MBUS_CONF( DE, true, HIGH, 2, 8192, 6144, 2048);
175 MBUS_CONF(DE_CFD, true, HIGH, 0, 1280, 144, 64);
177 writel(0x81000004, &mctl_com->mdfs_bwlr[2]);
180 static void mctl_set_master_priority_h5(void)
182 struct sunxi_mctl_com_reg * const mctl_com =
183 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
185 /* enable bandwidth limit windows and set windows size 1us */
186 writel(399, &mctl_com->tmr);
187 writel((1 << 16), &mctl_com->bwcr);
189 /* set cpu high priority */
190 writel(0x00000001, &mctl_com->mapr);
192 /* Port 2 is reserved per Allwinner's linux-3.10 source, yet
193 * they initialise it */
194 MBUS_CONF( CPU, true, HIGHEST, 0, 300, 260, 150);
195 MBUS_CONF( GPU, true, HIGHEST, 0, 600, 400, 200);
196 MBUS_CONF(UNUSED, true, HIGHEST, 0, 512, 256, 96);
197 MBUS_CONF( DMA, true, HIGHEST, 0, 256, 128, 32);
198 MBUS_CONF( VE, true, HIGHEST, 0, 1900, 1500, 1000);
199 MBUS_CONF( CSI, true, HIGHEST, 0, 150, 120, 100);
200 MBUS_CONF( NAND, true, HIGH, 0, 256, 128, 64);
201 MBUS_CONF( SS, true, HIGHEST, 0, 256, 128, 64);
202 MBUS_CONF( TS, true, HIGHEST, 0, 256, 128, 64);
203 MBUS_CONF( DI, true, HIGH, 0, 1024, 256, 64);
204 MBUS_CONF( DE, true, HIGHEST, 3, 3400, 2400, 1024);
205 MBUS_CONF(DE_CFD, true, HIGHEST, 0, 600, 400, 200);
208 static void mctl_set_master_priority(uint16_t socid)
212 mctl_set_master_priority_h3();
215 mctl_set_master_priority_a64();
218 mctl_set_master_priority_h5();
223 static void mctl_set_timing_params(uint16_t socid, struct dram_para *para)
225 struct sunxi_mctl_ctl_reg * const mctl_ctl =
226 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
229 u8 tfaw = ns_to_t(50);
230 u8 trrd = max(ns_to_t(10), 4);
231 u8 trcd = ns_to_t(15);
232 u8 trc = ns_to_t(53);
233 u8 txp = max(ns_to_t(8), 3);
234 u8 twtr = max(ns_to_t(8), 4);
235 u8 trtp = max(ns_to_t(8), 4);
236 u8 twr = max(ns_to_t(15), 3);
237 u8 trp = ns_to_t(15);
238 u8 tras = ns_to_t(38);
239 u16 trefi = ns_to_t(7800) / 32;
240 u16 trfc = ns_to_t(350);
251 u8 tcl = 6; /* CL 12 */
252 u8 tcwl = 4; /* CWL 8 */
256 u32 tdinit0 = (500 * CONFIG_DRAM_CLK) + 1; /* 500us */
257 u32 tdinit1 = (360 * CONFIG_DRAM_CLK) / 1000 + 1; /* 360ns */
258 u32 tdinit2 = (200 * CONFIG_DRAM_CLK) + 1; /* 200us */
259 u32 tdinit3 = (1 * CONFIG_DRAM_CLK) + 1; /* 1us */
261 u8 twtp = tcwl + 2 + twr; /* WL + BL / 2 + tWR */
262 u8 twr2rd = tcwl + 2 + twtr; /* WL + BL / 2 + tWTR */
263 u8 trd2wr = tcl + 2 + 1 - tcwl; /* RL + BL / 2 + 2 - WL */
265 /* set mode register */
266 writel(0x1c70, &mctl_ctl->mr[0]); /* CL=11, WR=12 */
267 writel(0x40, &mctl_ctl->mr[1]);
268 writel(0x18, &mctl_ctl->mr[2]); /* CWL=8 */
269 writel(0x0, &mctl_ctl->mr[3]);
271 /* set DRAM timing */
272 writel(DRAMTMG0_TWTP(twtp) | DRAMTMG0_TFAW(tfaw) |
273 DRAMTMG0_TRAS_MAX(trasmax) | DRAMTMG0_TRAS(tras),
274 &mctl_ctl->dramtmg[0]);
275 writel(DRAMTMG1_TXP(txp) | DRAMTMG1_TRTP(trtp) | DRAMTMG1_TRC(trc),
276 &mctl_ctl->dramtmg[1]);
277 writel(DRAMTMG2_TCWL(tcwl) | DRAMTMG2_TCL(tcl) |
278 DRAMTMG2_TRD2WR(trd2wr) | DRAMTMG2_TWR2RD(twr2rd),
279 &mctl_ctl->dramtmg[2]);
280 writel(DRAMTMG3_TMRW(tmrw) | DRAMTMG3_TMRD(tmrd) | DRAMTMG3_TMOD(tmod),
281 &mctl_ctl->dramtmg[3]);
282 writel(DRAMTMG4_TRCD(trcd) | DRAMTMG4_TCCD(tccd) | DRAMTMG4_TRRD(trrd) |
283 DRAMTMG4_TRP(trp), &mctl_ctl->dramtmg[4]);
284 writel(DRAMTMG5_TCKSRX(tcksrx) | DRAMTMG5_TCKSRE(tcksre) |
285 DRAMTMG5_TCKESR(tckesr) | DRAMTMG5_TCKE(tcke),
286 &mctl_ctl->dramtmg[5]);
288 /* set two rank timing */
289 clrsetbits_le32(&mctl_ctl->dramtmg[8], (0xff << 8) | (0xff << 0),
290 ((socid == SOCID_H5 ? 0x33 : 0x66) << 8) | (0x10 << 0));
292 /* set PHY interface timing, write latency and read latency configure */
293 writel((0x2 << 24) | (t_rdata_en << 16) | (0x1 << 8) |
294 (wr_latency << 0), &mctl_ctl->pitmg[0]);
296 /* set PHY timing, PTR0-2 use default */
297 writel(PTR3_TDINIT0(tdinit0) | PTR3_TDINIT1(tdinit1), &mctl_ctl->ptr[3]);
298 writel(PTR4_TDINIT2(tdinit2) | PTR4_TDINIT3(tdinit3), &mctl_ctl->ptr[4]);
300 /* set refresh timing */
301 writel(RFSHTMG_TREFI(trefi) | RFSHTMG_TRFC(trfc), &mctl_ctl->rfshtmg);
304 static u32 bin_to_mgray(int val)
306 static const u8 lookup_table[32] = {
307 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
308 0x0c, 0x0d, 0x0e, 0x0f, 0x0a, 0x0b, 0x08, 0x09,
309 0x18, 0x19, 0x1a, 0x1b, 0x1e, 0x1f, 0x1c, 0x1d,
310 0x14, 0x15, 0x16, 0x17, 0x12, 0x13, 0x10, 0x11,
313 return lookup_table[clamp(val, 0, 31)];
316 static int mgray_to_bin(u32 val)
318 static const u8 lookup_table[32] = {
319 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
320 0x0e, 0x0f, 0x0c, 0x0d, 0x08, 0x09, 0x0a, 0x0b,
321 0x1e, 0x1f, 0x1c, 0x1d, 0x18, 0x19, 0x1a, 0x1b,
322 0x10, 0x11, 0x12, 0x13, 0x16, 0x17, 0x14, 0x15,
325 return lookup_table[val & 0x1f];
328 static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
330 struct sunxi_mctl_ctl_reg * const mctl_ctl =
331 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
333 if ((readl(SUNXI_SRAMC_BASE + 0x24) & 0xff) == 0 &&
334 (readl(SUNXI_SRAMC_BASE + 0xf0) & 0x1) == 0) {
337 clrsetbits_le32(&mctl_ctl->zqcr, 0xffff,
338 CONFIG_DRAM_ZQ & 0xffff);
340 writel(PIR_CLRSR, &mctl_ctl->pir);
341 mctl_phy_init(PIR_ZCAL);
343 reg_val = readl(&mctl_ctl->zqdr[0]);
344 reg_val &= (0x1f << 16) | (0x1f << 0);
345 reg_val |= reg_val << 8;
346 writel(reg_val, &mctl_ctl->zqdr[0]);
348 reg_val = readl(&mctl_ctl->zqdr[1]);
349 reg_val &= (0x1f << 16) | (0x1f << 0);
350 reg_val |= reg_val << 8;
351 writel(reg_val, &mctl_ctl->zqdr[1]);
352 writel(reg_val, &mctl_ctl->zqdr[2]);
358 writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
360 for (i = 0; i < 6; i++) {
361 u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
363 writel((zq << 20) | (zq << 16) | (zq << 12) |
364 (zq << 8) | (zq << 4) | (zq << 0),
367 writel(PIR_CLRSR, &mctl_ctl->pir);
368 mctl_phy_init(PIR_ZCAL);
370 zq_val[i] = readl(&mctl_ctl->zqdr[0]) & 0xff;
371 writel(REPEAT_BYTE(zq_val[i]), &mctl_ctl->zqdr[2]);
373 writel(PIR_CLRSR, &mctl_ctl->pir);
374 mctl_phy_init(PIR_ZCAL);
376 val = readl(&mctl_ctl->zqdr[0]) >> 24;
377 zq_val[i] |= bin_to_mgray(mgray_to_bin(val) - 1) << 8;
380 writel((zq_val[1] << 16) | zq_val[0], &mctl_ctl->zqdr[0]);
381 writel((zq_val[3] << 16) | zq_val[2], &mctl_ctl->zqdr[1]);
382 writel((zq_val[5] << 16) | zq_val[4], &mctl_ctl->zqdr[2]);
386 static void mctl_set_cr(struct dram_para *para)
388 struct sunxi_mctl_com_reg * const mctl_com =
389 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
391 writel(MCTL_CR_BL8 | MCTL_CR_2T | MCTL_CR_DDR3 | MCTL_CR_INTERLEAVED |
392 MCTL_CR_EIGHT_BANKS | MCTL_CR_BUS_WIDTH(para->bus_width) |
393 (para->dual_rank ? MCTL_CR_DUAL_RANK : MCTL_CR_SINGLE_RANK) |
394 MCTL_CR_PAGE_SIZE(para->page_size) |
395 MCTL_CR_ROW_BITS(para->row_bits), &mctl_com->cr);
398 static void mctl_sys_init(uint16_t socid, struct dram_para *para)
400 struct sunxi_ccm_reg * const ccm =
401 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
402 struct sunxi_mctl_ctl_reg * const mctl_ctl =
403 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
405 clrbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
406 clrbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
407 clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
408 clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
409 clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
410 if (socid == SOCID_A64)
411 clrbits_le32(&ccm->pll11_cfg, CCM_PLL11_CTRL_EN);
414 clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
417 if (socid == SOCID_A64) {
418 clock_set_pll11(CONFIG_DRAM_CLK * 2 * 1000000, false);
419 clrsetbits_le32(&ccm->dram_clk_cfg,
420 CCM_DRAMCLK_CFG_DIV_MASK |
421 CCM_DRAMCLK_CFG_SRC_MASK,
422 CCM_DRAMCLK_CFG_DIV(1) |
423 CCM_DRAMCLK_CFG_SRC_PLL11 |
424 CCM_DRAMCLK_CFG_UPD);
425 } else if (socid == SOCID_H3 || socid == SOCID_H5) {
426 clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false);
427 clrsetbits_le32(&ccm->dram_clk_cfg,
428 CCM_DRAMCLK_CFG_DIV_MASK |
429 CCM_DRAMCLK_CFG_SRC_MASK,
430 CCM_DRAMCLK_CFG_DIV(1) |
431 CCM_DRAMCLK_CFG_SRC_PLL5 |
432 CCM_DRAMCLK_CFG_UPD);
434 mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
436 setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
437 setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
438 setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
439 setbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
441 setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
444 writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken);
448 /* These are more guessed based on some Allwinner code. */
449 #define DX_GCR_ODT_DYNAMIC (0x0 << 4)
450 #define DX_GCR_ODT_ALWAYS_ON (0x1 << 4)
451 #define DX_GCR_ODT_OFF (0x2 << 4)
453 static int mctl_channel_init(uint16_t socid, struct dram_para *para)
455 struct sunxi_mctl_com_reg * const mctl_com =
456 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
457 struct sunxi_mctl_ctl_reg * const mctl_ctl =
458 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
463 mctl_set_timing_params(socid, para);
464 mctl_set_master_priority(socid);
466 /* setting VTC, default disable all VT */
467 clrbits_le32(&mctl_ctl->pgcr[0], (1 << 30) | 0x3f);
468 if (socid == SOCID_H5)
469 setbits_le32(&mctl_ctl->pgcr[1], (1 << 24) | (1 << 26));
471 clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
473 /* increase DFI_PHY_UPD clock */
474 writel(PROTECT_MAGIC, &mctl_com->protect);
476 clrsetbits_le32(&mctl_ctl->upd2, 0xfff << 16, 0x50 << 16);
477 writel(0x0, &mctl_com->protect);
481 for (i = 0; i < 4; i++) {
482 u32 clearmask = (0x3 << 4) | (0x1 << 1) | (0x3 << 2) |
483 (0x3 << 12) | (0x3 << 14);
484 u32 setmask = IS_ENABLED(CONFIG_DRAM_ODT_EN) ?
485 DX_GCR_ODT_DYNAMIC : DX_GCR_ODT_OFF;
487 if (socid == SOCID_H5) {
488 clearmask |= 0x2 << 8;
491 clrsetbits_le32(&mctl_ctl->dx[i].gcr, clearmask, setmask);
494 /* AC PDR should always ON */
495 clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0,
498 /* set DQS auto gating PD mode */
499 setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
501 if (socid == SOCID_H3) {
502 /* dx ddr_clk & hdr_clk dynamic mode */
503 clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
505 /* dphy & aphy phase select 270 degree */
506 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
507 (0x1 << 10) | (0x2 << 8));
508 } else if (socid == SOCID_A64 || socid == SOCID_H5) {
509 /* dphy & aphy phase select ? */
510 clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
511 (0x0 << 10) | (0x3 << 8));
515 if (para->bus_width != 32) {
516 writel(0x0, &mctl_ctl->dx[2].gcr);
517 writel(0x0, &mctl_ctl->dx[3].gcr);
520 /* data training configuration */
521 clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24,
522 (para->dual_rank ? 0x3 : 0x1) << 24);
524 mctl_set_bit_delays(para);
527 if (socid == SOCID_H3) {
528 mctl_h3_zq_calibration_quirk(para);
530 mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
531 PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
532 } else if (socid == SOCID_A64 || socid == SOCID_H5) {
533 clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
535 mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
536 PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
537 /* no PIR_QSGATE for H5 ???? */
540 /* detect ranks and bus width */
541 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
543 if (((readl(&mctl_ctl->dx[0].gsr[0]) >> 24) & 0x2) ||
544 ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x2)) {
545 clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
549 /* only half DQ width */
550 if (((readl(&mctl_ctl->dx[2].gsr[0]) >> 24) & 0x1) ||
551 ((readl(&mctl_ctl->dx[3].gsr[0]) >> 24) & 0x1)) {
552 writel(0x0, &mctl_ctl->dx[2].gcr);
553 writel(0x0, &mctl_ctl->dx[3].gcr);
554 para->bus_width = 16;
561 mctl_phy_init(PIR_QSGATE);
562 if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20))
566 /* check the dramc status */
567 mctl_await_completion(&mctl_ctl->statr, 0x1, 0x1);
569 /* liuke added for refresh debug */
570 setbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
572 clrbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
575 /* set PGCR3, CKE polarity */
576 if (socid == SOCID_H3)
577 writel(0x00aa0060, &mctl_ctl->pgcr[3]);
578 else if (socid == SOCID_A64 || socid == SOCID_H5)
579 writel(0xc0aa0060, &mctl_ctl->pgcr[3]);
581 /* power down zq calibration module for power save */
582 setbits_le32(&mctl_ctl->zqcr, ZQCR_PWRDOWN);
584 /* enable master access */
585 writel(0xffffffff, &mctl_com->maer);
590 static void mctl_auto_detect_dram_size(struct dram_para *para)
592 /* detect row address bits */
593 para->page_size = 512;
597 for (para->row_bits = 11; para->row_bits < 16; para->row_bits++)
598 if (mctl_mem_matches((1 << (para->row_bits + 3)) * para->page_size))
601 /* detect page size */
602 para->page_size = 8192;
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 SUN50I_A64_DX_READ_DELAYS \
634 {{ 16, 16, 16, 16, 17, 16, 16, 17, 16, 1, 0 }, \
635 { 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0 }, \
636 { 16, 17, 17, 16, 16, 16, 16, 16, 16, 0, 0 }, \
637 { 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0 }}
638 #define SUN50I_A64_DX_WRITE_DELAYS \
639 {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15 }, \
640 { 0, 0, 0, 0, 1, 1, 1, 1, 0, 10, 10 }, \
641 { 1, 0, 1, 1, 1, 1, 1, 1, 0, 11, 11 }, \
642 { 1, 0, 0, 1, 1, 1, 1, 1, 0, 12, 12 }}
643 #define SUN50I_A64_AC_DELAYS \
644 { 5, 5, 13, 10, 2, 5, 3, 3, \
645 0, 3, 3, 3, 1, 0, 0, 0, \
646 3, 4, 0, 3, 4, 1, 4, 0, \
647 1, 1, 0, 1, 13, 5, 4 }
649 #define SUN8I_H5_DX_READ_DELAYS \
650 {{ 14, 15, 17, 17, 17, 17, 17, 18, 17, 3, 3 }, \
651 { 21, 21, 12, 22, 21, 21, 21, 21, 21, 3, 3 }, \
652 { 16, 19, 19, 17, 22, 22, 21, 22, 19, 3, 3 }, \
653 { 21, 21, 22, 22, 20, 21, 19, 19, 19, 3, 3 } }
654 #define SUN8I_H5_DX_WRITE_DELAYS \
655 {{ 1, 2, 3, 4, 3, 4, 4, 4, 6, 6, 6 }, \
656 { 6, 6, 6, 5, 5, 5, 5, 5, 6, 6, 6 }, \
657 { 0, 2, 4, 2, 6, 5, 5, 5, 6, 6, 6 }, \
658 { 3, 3, 3, 2, 2, 1, 1, 1, 4, 4, 4 } }
659 #define SUN8I_H5_AC_DELAYS \
660 { 0, 0, 5, 5, 0, 0, 0, 0, \
661 0, 0, 0, 0, 3, 3, 3, 3, \
662 3, 3, 3, 3, 3, 3, 3, 3, \
663 3, 3, 3, 3, 2, 0, 0 }
665 unsigned long sunxi_dram_init(void)
667 struct sunxi_mctl_com_reg * const mctl_com =
668 (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
669 struct sunxi_mctl_ctl_reg * const mctl_ctl =
670 (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
672 struct dram_para para = {
678 #if defined(CONFIG_MACH_SUN8I_H3)
679 .dx_read_delays = SUN8I_H3_DX_READ_DELAYS,
680 .dx_write_delays = SUN8I_H3_DX_WRITE_DELAYS,
681 .ac_delays = SUN8I_H3_AC_DELAYS,
682 #elif defined(CONFIG_MACH_SUN50I)
683 .dx_read_delays = SUN50I_A64_DX_READ_DELAYS,
684 .dx_write_delays = SUN50I_A64_DX_WRITE_DELAYS,
685 .ac_delays = SUN50I_A64_AC_DELAYS,
686 #elif defined(CONFIG_MACH_SUN50I_H5)
687 .dx_read_delays = SUN8I_H5_DX_READ_DELAYS,
688 .dx_write_delays = SUN8I_H5_DX_WRITE_DELAYS,
689 .ac_delays = SUN8I_H5_AC_DELAYS,
693 * Let the compiler optimize alternatives away by passing this value into
694 * the static functions. This saves us #ifdefs, but still keeps the binary
697 #if defined(CONFIG_MACH_SUN8I_H3)
698 uint16_t socid = SOCID_H3;
699 #elif defined(CONFIG_MACH_SUN50I)
700 uint16_t socid = SOCID_A64;
701 #elif defined(CONFIG_MACH_SUN50I_H5)
702 uint16_t socid = SOCID_H5;
705 mctl_sys_init(socid, ¶);
706 if (mctl_channel_init(socid, ¶))
710 writel(0x00000303, &mctl_ctl->odtmap);
712 writel(0x00000201, &mctl_ctl->odtmap);
716 if (socid == SOCID_H3)
717 writel(0x0c000400, &mctl_ctl->odtcfg);
719 if (socid == SOCID_A64 || socid == SOCID_H5) {
720 setbits_le32(&mctl_ctl->vtfcr,
721 (socid == SOCID_H5 ? 3 : 2) << 8);
722 clrbits_le32(&mctl_ctl->pgcr[2], (1 << 13));
725 /* clear credit value */
726 setbits_le32(&mctl_com->cccr, 1 << 31);
729 mctl_auto_detect_dram_size(¶);
732 return (1UL << (para.row_bits + 3)) * para.page_size *
733 (para.dual_rank ? 2 : 1);