1 /*
2  * sun8i H3 platform dram controller init
3  *
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>
9  *
10  * SPDX-License-Identifier:	GPL-2.0+
11  */
12 #include <common.h>
13 #include <asm/io.h>
14 #include <asm/arch/clock.h>
15 #include <asm/arch/dram.h>
16 #include <asm/arch/cpu.h>
17 #include <linux/kconfig.h>
18 
19 static void mctl_phy_init(u32 val)
20 {
21 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
22 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
23 
24 	writel(val | PIR_INIT, &mctl_ctl->pir);
25 	mctl_await_completion(&mctl_ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
26 }
27 
28 static void mctl_set_bit_delays(struct dram_para *para)
29 {
30 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
31 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
32 	int i, j;
33 
34 	clrbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
35 
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]);
41 
42 	for (i = 0; i < 31; i++)
43 		writel(ACBDLR_WRITE_DELAY(para->ac_delays[i]),
44 		       &mctl_ctl->acbdlr[i]);
45 
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);
50 #endif
51 
52 	setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
53 }
54 
55 enum {
56 	MBUS_PORT_CPU           = 0,
57 	MBUS_PORT_GPU           = 1,
58 	MBUS_PORT_UNUSED	= 2,
59 	MBUS_PORT_DMA           = 3,
60 	MBUS_PORT_VE            = 4,
61 	MBUS_PORT_CSI           = 5,
62 	MBUS_PORT_NAND          = 6,
63 	MBUS_PORT_SS            = 7,
64 	MBUS_PORT_TS            = 8,
65 	MBUS_PORT_DI            = 9,
66 	MBUS_PORT_DE            = 10,
67 	MBUS_PORT_DE_CFD        = 11,
68 	MBUS_PORT_UNKNOWN1	= 12,
69 	MBUS_PORT_UNKNOWN2	= 13,
70 	MBUS_PORT_UNKNOWN3	= 14,
71 };
72 
73 enum {
74 	MBUS_QOS_LOWEST = 0,
75 	MBUS_QOS_LOW,
76 	MBUS_QOS_HIGH,
77 	MBUS_QOS_HIGHEST
78 };
79 
80 inline void mbus_configure_port(u8 port,
81 				bool bwlimit,
82 				bool priority,
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 */
87 				u16 bwl1,
88 				u16 bwl2)
89 {
90 	struct sunxi_mctl_com_reg * const mctl_com =
91 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
92 
93 	const u32 cfg0 = ( (bwlimit ? (1 << 0) : 0)
94 			   | (priority ? (1 << 1) : 0)
95 			   | ((qos & 0x3) << 2)
96 			   | ((waittime & 0xf) << 4)
97 			   | ((acs & 0xff) << 8)
98 			   | (bwl0 << 16) );
99 	const u32 cfg1 = ((u32)bwl2 << 16) | (bwl1 & 0xffff);
100 
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]);
104 }
105 
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)
109 
110 static void mctl_set_master_priority_h3(void)
111 {
112 	struct sunxi_mctl_com_reg * const mctl_com =
113 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
114 
115 	/* enable bandwidth limit windows and set windows size 1us */
116 	writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
117 
118 	/* set cpu high priority */
119 	writel(0x00000001, &mctl_com->mapr);
120 
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);
133 }
134 
135 static void mctl_set_master_priority_a64(void)
136 {
137 	struct sunxi_mctl_com_reg * const mctl_com =
138 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
139 
140 	/* enable bandwidth limit windows and set windows size 1us */
141 	writel(399, &mctl_com->tmr);
142 	writel((1 << 16), &mctl_com->bwcr);
143 
144 	/* Port 2 is reserved per Allwinner's linux-3.10 source, yet they
145 	 * initialise it */
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);
158 
159 	writel(0x81000004, &mctl_com->mdfs_bwlr[2]);
160 }
161 
162 static void mctl_set_master_priority_h5(void)
163 {
164 	struct sunxi_mctl_com_reg * const mctl_com =
165 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
166 
167 	/* enable bandwidth limit windows and set windows size 1us */
168 	writel(399, &mctl_com->tmr);
169 	writel((1 << 16), &mctl_com->bwcr);
170 
171 	/* set cpu high priority */
172 	writel(0x00000001, &mctl_com->mapr);
173 
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);
188 }
189 
190 static void mctl_set_master_priority_r40(void)
191 {
192 	struct sunxi_mctl_com_reg * const mctl_com =
193 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
194 
195 	/* enable bandwidth limit windows and set windows size 1us */
196 	writel(399, &mctl_com->tmr);
197 	writel((1 << 16), &mctl_com->bwcr);
198 
199 	/* set cpu high priority */
200 	writel(0x00000001, &mctl_com->mapr);
201 
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);
214 
215 	/*
216 	 * The port names are probably wrong, but no correct sources
217 	 * are available.
218 	 */
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);
224 }
225 
226 static void mctl_set_master_priority(uint16_t socid)
227 {
228 	switch (socid) {
229 	case SOCID_H3:
230 		mctl_set_master_priority_h3();
231 		return;
232 	case SOCID_A64:
233 		mctl_set_master_priority_a64();
234 		return;
235 	case SOCID_H5:
236 		mctl_set_master_priority_h5();
237 		return;
238 	case SOCID_R40:
239 		mctl_set_master_priority_r40();
240 		return;
241 	}
242 }
243 
244 static u32 bin_to_mgray(int val)
245 {
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,
251 	};
252 
253 	return lookup_table[clamp(val, 0, 31)];
254 }
255 
256 static int mgray_to_bin(u32 val)
257 {
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,
263 	};
264 
265 	return lookup_table[val & 0x1f];
266 }
267 
268 static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
269 {
270 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
271 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
272 	int zq_count;
273 
274 #if defined CONFIG_SUNXI_DRAM_DW_16BIT
275 	zq_count = 4;
276 #else
277 	zq_count = 6;
278 #endif
279 
280 	if ((readl(SUNXI_SRAMC_BASE + 0x24) & 0xff) == 0 &&
281 	    (readl(SUNXI_SRAMC_BASE + 0xf0) & 0x1) == 0) {
282 		u32 reg_val;
283 
284 		clrsetbits_le32(&mctl_ctl->zqcr, 0xffff,
285 				CONFIG_DRAM_ZQ & 0xffff);
286 
287 		writel(PIR_CLRSR, &mctl_ctl->pir);
288 		mctl_phy_init(PIR_ZCAL);
289 
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]);
294 
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]);
300 	} else {
301 		int i;
302 		u16 zq_val[6];
303 		u8 val;
304 
305 		writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
306 
307 		for (i = 0; i < zq_count; i++) {
308 			u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
309 
310 			writel((zq << 20) | (zq << 16) | (zq << 12) |
311 					(zq << 8) | (zq << 4) | (zq << 0),
312 					&mctl_ctl->zqcr);
313 
314 			writel(PIR_CLRSR, &mctl_ctl->pir);
315 			mctl_phy_init(PIR_ZCAL);
316 
317 			zq_val[i] = readl(&mctl_ctl->zqdr[0]) & 0xff;
318 			writel(REPEAT_BYTE(zq_val[i]), &mctl_ctl->zqdr[2]);
319 
320 			writel(PIR_CLRSR, &mctl_ctl->pir);
321 			mctl_phy_init(PIR_ZCAL);
322 
323 			val = readl(&mctl_ctl->zqdr[0]) >> 24;
324 			zq_val[i] |= bin_to_mgray(mgray_to_bin(val) - 1) << 8;
325 		}
326 
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]);
329 		if (zq_count > 4)
330 			writel((zq_val[5] << 16) | zq_val[4],
331 			       &mctl_ctl->zqdr[2]);
332 	}
333 }
334 
335 static void mctl_set_cr(uint16_t socid, struct dram_para *para)
336 {
337 	struct sunxi_mctl_com_reg * const mctl_com =
338 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
339 
340 	writel(MCTL_CR_BL8 | MCTL_CR_INTERLEAVED |
341 #if defined CONFIG_SUNXI_DRAM_DDR3
342 	       MCTL_CR_DDR3 | MCTL_CR_2T |
343 #elif defined CONFIG_SUNXI_DRAM_DDR2
344 	       MCTL_CR_DDR2 | MCTL_CR_2T |
345 #elif defined CONFIG_SUNXI_DRAM_LPDDR3
346 	       MCTL_CR_LPDDR3 | MCTL_CR_1T |
347 #else
348 #error Unsupported DRAM type!
349 #endif
350 	       (para->bank_bits == 3 ? MCTL_CR_EIGHT_BANKS : MCTL_CR_FOUR_BANKS) |
351 	       MCTL_CR_BUS_FULL_WIDTH(para->bus_full_width) |
352 	       (para->dual_rank ? MCTL_CR_DUAL_RANK : MCTL_CR_SINGLE_RANK) |
353 	       MCTL_CR_PAGE_SIZE(para->page_size) |
354 	       MCTL_CR_ROW_BITS(para->row_bits), &mctl_com->cr);
355 
356 	if (socid == SOCID_R40) {
357 		if (para->dual_rank)
358 			panic("Dual rank memory not supported\n");
359 
360 		/* Mux pin to A15 address line for single rank memory. */
361 		setbits_le32(&mctl_com->cr_r1, MCTL_CR_R1_MUX_A15);
362 	}
363 }
364 
365 static void mctl_sys_init(uint16_t socid, struct dram_para *para)
366 {
367 	struct sunxi_ccm_reg * const ccm =
368 			(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
369 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
370 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
371 
372 	clrbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
373 	clrbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
374 	clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
375 	clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
376 	clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
377 	if (socid == SOCID_A64 || socid == SOCID_R40)
378 		clrbits_le32(&ccm->pll11_cfg, CCM_PLL11_CTRL_EN);
379 	udelay(10);
380 
381 	clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
382 	udelay(1000);
383 
384 	if (socid == SOCID_A64 || socid == SOCID_R40) {
385 		clock_set_pll11(CONFIG_DRAM_CLK * 2 * 1000000, false);
386 		clrsetbits_le32(&ccm->dram_clk_cfg,
387 				CCM_DRAMCLK_CFG_DIV_MASK |
388 				CCM_DRAMCLK_CFG_SRC_MASK,
389 				CCM_DRAMCLK_CFG_DIV(1) |
390 				CCM_DRAMCLK_CFG_SRC_PLL11 |
391 				CCM_DRAMCLK_CFG_UPD);
392 	} else if (socid == SOCID_H3 || socid == SOCID_H5) {
393 		clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false);
394 		clrsetbits_le32(&ccm->dram_clk_cfg,
395 				CCM_DRAMCLK_CFG_DIV_MASK |
396 				CCM_DRAMCLK_CFG_SRC_MASK,
397 				CCM_DRAMCLK_CFG_DIV(1) |
398 				CCM_DRAMCLK_CFG_SRC_PLL5 |
399 				CCM_DRAMCLK_CFG_UPD);
400 	}
401 	mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
402 
403 	setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
404 	setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
405 	setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
406 	setbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
407 
408 	setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
409 	udelay(10);
410 
411 	writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken);
412 	udelay(500);
413 }
414 
415 /* These are more guessed based on some Allwinner code. */
416 #define DX_GCR_ODT_DYNAMIC	(0x0 << 4)
417 #define DX_GCR_ODT_ALWAYS_ON	(0x1 << 4)
418 #define DX_GCR_ODT_OFF		(0x2 << 4)
419 
420 static int mctl_channel_init(uint16_t socid, struct dram_para *para)
421 {
422 	struct sunxi_mctl_com_reg * const mctl_com =
423 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
424 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
425 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
426 
427 	unsigned int i;
428 
429 	mctl_set_cr(socid, para);
430 	mctl_set_timing_params(socid, para);
431 	mctl_set_master_priority(socid);
432 
433 	/* setting VTC, default disable all VT */
434 	clrbits_le32(&mctl_ctl->pgcr[0], (1 << 30) | 0x3f);
435 	if (socid == SOCID_H5)
436 		setbits_le32(&mctl_ctl->pgcr[1], (1 << 24) | (1 << 26));
437 	else
438 		clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
439 
440 	/* increase DFI_PHY_UPD clock */
441 	writel(PROTECT_MAGIC, &mctl_com->protect);
442 	udelay(100);
443 	clrsetbits_le32(&mctl_ctl->upd2, 0xfff << 16, 0x50 << 16);
444 	writel(0x0, &mctl_com->protect);
445 	udelay(100);
446 
447 	/* set dramc odt */
448 	for (i = 0; i < 4; i++) {
449 		u32 clearmask = (0x3 << 4) | (0x1 << 1) | (0x3 << 2) |
450 				(0x3 << 12) | (0x3 << 14);
451 		u32 setmask = IS_ENABLED(CONFIG_DRAM_ODT_EN) ?
452 				DX_GCR_ODT_DYNAMIC : DX_GCR_ODT_OFF;
453 
454 		if (socid == SOCID_H5) {
455 			clearmask |= 0x2 << 8;
456 			setmask |= 0x4 << 8;
457 		}
458 		clrsetbits_le32(&mctl_ctl->dx[i].gcr, clearmask, setmask);
459 	}
460 
461 	/* AC PDR should always ON */
462 	clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0,
463 			0x1 << 1);
464 
465 	/* set DQS auto gating PD mode */
466 	setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
467 
468 	if (socid == SOCID_H3) {
469 		/* dx ddr_clk & hdr_clk dynamic mode */
470 		clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
471 
472 		/* dphy & aphy phase select 270 degree */
473 		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
474 				(0x1 << 10) | (0x2 << 8));
475 	} else if (socid == SOCID_A64 || socid == SOCID_H5) {
476 		/* dphy & aphy phase select ? */
477 		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
478 				(0x0 << 10) | (0x3 << 8));
479 	} else if (socid == SOCID_R40) {
480 		/* dx ddr_clk & hdr_clk dynamic mode (tpr13[9] == 0) */
481 		clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
482 
483 		/* dphy & aphy phase select ? */
484 		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
485 				(0x0 << 10) | (0x3 << 8));
486 	}
487 
488 	/* set half DQ */
489 	if (!para->bus_full_width) {
490 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
491 		writel(0x0, &mctl_ctl->dx[2].gcr);
492 		writel(0x0, &mctl_ctl->dx[3].gcr);
493 #elif defined CONFIG_SUNXI_DRAM_DW_16BIT
494 		writel(0x0, &mctl_ctl->dx[1].gcr);
495 #else
496 #error Unsupported DRAM bus width!
497 #endif
498 	}
499 
500 	/* data training configuration */
501 	clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24,
502 			(para->dual_rank ? 0x3 : 0x1) << 24);
503 
504 	mctl_set_bit_delays(para);
505 	udelay(50);
506 
507 	if (socid == SOCID_H3) {
508 		mctl_h3_zq_calibration_quirk(para);
509 
510 		mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
511 			      PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
512 	} else if (socid == SOCID_A64 || socid == SOCID_H5) {
513 		clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
514 
515 		mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
516 			      PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
517 		/* no PIR_QSGATE for H5 ???? */
518 	} else if (socid == SOCID_R40) {
519 		clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
520 
521 		mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
522 			      PIR_DRAMRST | PIR_DRAMINIT);
523 	}
524 
525 	/* detect ranks and bus width */
526 	if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
527 		/* only one rank */
528 		if (((readl(&mctl_ctl->dx[0].gsr[0]) >> 24) & 0x2)
529 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
530 		    || ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x2)
531 #endif
532 		    ) {
533 			clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
534 			para->dual_rank = 0;
535 		}
536 
537 		/* only half DQ width */
538 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
539 		if (((readl(&mctl_ctl->dx[2].gsr[0]) >> 24) & 0x1) ||
540 		    ((readl(&mctl_ctl->dx[3].gsr[0]) >> 24) & 0x1)) {
541 			writel(0x0, &mctl_ctl->dx[2].gcr);
542 			writel(0x0, &mctl_ctl->dx[3].gcr);
543 			para->bus_full_width = 0;
544 		}
545 #elif defined CONFIG_SUNXI_DRAM_DW_16BIT
546 		if ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x1) {
547 			writel(0x0, &mctl_ctl->dx[1].gcr);
548 			para->bus_full_width = 0;
549 		}
550 #endif
551 
552 		mctl_set_cr(socid, para);
553 		udelay(20);
554 
555 		/* re-train */
556 		mctl_phy_init(PIR_QSGATE);
557 		if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20))
558 			return 1;
559 	}
560 
561 	/* check the dramc status */
562 	mctl_await_completion(&mctl_ctl->statr, 0x1, 0x1);
563 
564 	/* liuke added for refresh debug */
565 	setbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
566 	udelay(10);
567 	clrbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
568 	udelay(10);
569 
570 	/* set PGCR3, CKE polarity */
571 	if (socid == SOCID_H3)
572 		writel(0x00aa0060, &mctl_ctl->pgcr[3]);
573 	else if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40)
574 		writel(0xc0aa0060, &mctl_ctl->pgcr[3]);
575 
576 	/* power down zq calibration module for power save */
577 	setbits_le32(&mctl_ctl->zqcr, ZQCR_PWRDOWN);
578 
579 	/* enable master access */
580 	writel(0xffffffff, &mctl_com->maer);
581 
582 	return 0;
583 }
584 
585 static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
586 {
587 	/* detect row address bits */
588 	para->page_size = 512;
589 	para->row_bits = 16;
590 	para->bank_bits = 2;
591 	mctl_set_cr(socid, para);
592 
593 	for (para->row_bits = 11; para->row_bits < 16; para->row_bits++)
594 		if (mctl_mem_matches((1 << (para->row_bits + para->bank_bits)) * para->page_size))
595 			break;
596 
597 	/* detect bank address bits */
598 	para->bank_bits = 3;
599 	mctl_set_cr(socid, para);
600 
601 	for (para->bank_bits = 2; para->bank_bits < 3; para->bank_bits++)
602 		if (mctl_mem_matches((1 << para->bank_bits) * para->page_size))
603 			break;
604 
605 	/* detect page size */
606 	para->page_size = 8192;
607 	mctl_set_cr(socid, para);
608 
609 	for (para->page_size = 512; para->page_size < 8192; para->page_size *= 2)
610 		if (mctl_mem_matches(para->page_size))
611 			break;
612 }
613 
614 /*
615  * The actual values used here are taken from Allwinner provided boot0
616  * binaries, though they are probably board specific, so would likely benefit
617  * from invidual tuning for each board. Apparently a lot of boards copy from
618  * some Allwinner reference design, so we go with those generic values for now
619  * in the hope that they are reasonable for most (all?) boards.
620  */
621 #define SUN8I_H3_DX_READ_DELAYS					\
622 	{{ 18, 18, 18, 18, 18, 18, 18, 18, 18,  0,  0 },	\
623 	 { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 },	\
624 	 { 18, 18, 18, 18, 18, 18, 18, 18, 18,  0,  0 },	\
625 	 { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 }}
626 #define SUN8I_H3_DX_WRITE_DELAYS				\
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, 10, 10 },	\
630 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  6 }}
631 #define SUN8I_H3_AC_DELAYS					\
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,  0,			\
635 	   0,  0,  0,  0,  0,  0,  0      }
636 
637 #define SUN8I_R40_DX_READ_DELAYS				\
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 	 { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 } }
642 #define SUN8I_R40_DX_WRITE_DELAYS				\
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 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0 } }
647 #define SUN8I_R40_AC_DELAYS					\
648 	{  0,  0,  3,  0,  0,  0,  0,  0,			\
649 	   0,  0,  0,  0,  0,  0,  0,  0,			\
650 	   0,  0,  0,  0,  0,  0,  0,  0,			\
651 	   0,  0,  0,  0,  0,  0,  0      }
652 
653 #define SUN50I_A64_DX_READ_DELAYS				\
654 	{{ 16, 16, 16, 16, 17, 16, 16, 17, 16,  1,  0 },	\
655 	 { 17, 17, 17, 17, 17, 17, 17, 17, 17,  1,  0 },	\
656 	 { 16, 17, 17, 16, 16, 16, 16, 16, 16,  0,  0 },	\
657 	 { 17, 17, 17, 17, 17, 17, 17, 17, 17,  1,  0 }}
658 #define SUN50I_A64_DX_WRITE_DELAYS				\
659 	{{  0,  0,  0,  0,  0,  0,  0,  0,  0, 15, 15 },	\
660 	 {  0,  0,  0,  0,  1,  1,  1,  1,  0, 10, 10 },	\
661 	 {  1,  0,  1,  1,  1,  1,  1,  1,  0, 11, 11 },	\
662 	 {  1,  0,  0,  1,  1,  1,  1,  1,  0, 12, 12 }}
663 #define SUN50I_A64_AC_DELAYS					\
664 	{  5,  5, 13, 10,  2,  5,  3,  3,			\
665 	   0,  3,  3,  3,  1,  0,  0,  0,			\
666 	   3,  4,  0,  3,  4,  1,  4,  0,			\
667 	   1,  1,  0,  1, 13,  5,  4      }
668 
669 #define SUN8I_H5_DX_READ_DELAYS					\
670 	{{ 14, 15, 17, 17, 17, 17, 17, 18, 17,  3,  3 },	\
671 	 { 21, 21, 12, 22, 21, 21, 21, 21, 21,  3,  3 },	\
672 	 { 16, 19, 19, 17, 22, 22, 21, 22, 19,  3,  3 },	\
673 	 { 21, 21, 22, 22, 20, 21, 19, 19, 19,  3,  3 } }
674 #define SUN8I_H5_DX_WRITE_DELAYS				\
675 	{{  1,  2,  3,  4,  3,  4,  4,  4,  6,  6,  6 },	\
676 	 {  6,  6,  6,  5,  5,  5,  5,  5,  6,  6,  6 },	\
677 	 {  0,  2,  4,  2,  6,  5,  5,  5,  6,  6,  6 },	\
678 	 {  3,  3,  3,  2,  2,  1,  1,  1,  4,  4,  4 } }
679 #define SUN8I_H5_AC_DELAYS					\
680 	{  0,  0,  5,  5,  0,  0,  0,  0,			\
681 	   0,  0,  0,  0,  3,  3,  3,  3,			\
682 	   3,  3,  3,  3,  3,  3,  3,  3,			\
683 	   3,  3,  3,  3,  2,  0,  0      }
684 
685 unsigned long sunxi_dram_init(void)
686 {
687 	struct sunxi_mctl_com_reg * const mctl_com =
688 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
689 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
690 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
691 
692 	struct dram_para para = {
693 		.dual_rank = 1,
694 		.bus_full_width = 1,
695 		.row_bits = 15,
696 		.bank_bits = 3,
697 		.page_size = 4096,
698 
699 #if defined(CONFIG_MACH_SUN8I_H3)
700 		.dx_read_delays  = SUN8I_H3_DX_READ_DELAYS,
701 		.dx_write_delays = SUN8I_H3_DX_WRITE_DELAYS,
702 		.ac_delays	 = SUN8I_H3_AC_DELAYS,
703 #elif defined(CONFIG_MACH_SUN8I_R40)
704 		.dx_read_delays  = SUN8I_R40_DX_READ_DELAYS,
705 		.dx_write_delays = SUN8I_R40_DX_WRITE_DELAYS,
706 		.ac_delays	 = SUN8I_R40_AC_DELAYS,
707 #elif defined(CONFIG_MACH_SUN50I)
708 		.dx_read_delays  = SUN50I_A64_DX_READ_DELAYS,
709 		.dx_write_delays = SUN50I_A64_DX_WRITE_DELAYS,
710 		.ac_delays	 = SUN50I_A64_AC_DELAYS,
711 #elif defined(CONFIG_MACH_SUN50I_H5)
712 		.dx_read_delays  = SUN8I_H5_DX_READ_DELAYS,
713 		.dx_write_delays = SUN8I_H5_DX_WRITE_DELAYS,
714 		.ac_delays	 = SUN8I_H5_AC_DELAYS,
715 #endif
716 	};
717 /*
718  * Let the compiler optimize alternatives away by passing this value into
719  * the static functions. This saves us #ifdefs, but still keeps the binary
720  * small.
721  */
722 #if defined(CONFIG_MACH_SUN8I_H3)
723 	uint16_t socid = SOCID_H3;
724 #elif defined(CONFIG_MACH_SUN8I_R40)
725 	uint16_t socid = SOCID_R40;
726 	/* Currently we cannot support R40 with dual rank memory */
727 	para.dual_rank = 0;
728 #elif defined(CONFIG_MACH_SUN8I_V3S)
729 	/* TODO: set delays and mbus priority for V3s */
730 	uint16_t socid = SOCID_H3;
731 #elif defined(CONFIG_MACH_SUN50I)
732 	uint16_t socid = SOCID_A64;
733 #elif defined(CONFIG_MACH_SUN50I_H5)
734 	uint16_t socid = SOCID_H5;
735 #endif
736 
737 	mctl_sys_init(socid, &para);
738 	if (mctl_channel_init(socid, &para))
739 		return 0;
740 
741 	if (para.dual_rank)
742 		writel(0x00000303, &mctl_ctl->odtmap);
743 	else
744 		writel(0x00000201, &mctl_ctl->odtmap);
745 	udelay(1);
746 
747 	/* odt delay */
748 	if (socid == SOCID_H3)
749 		writel(0x0c000400, &mctl_ctl->odtcfg);
750 
751 	if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40) {
752 		/* VTF enable (tpr13[8] == 1) */
753 		setbits_le32(&mctl_ctl->vtfcr,
754 			     (socid != SOCID_A64 ? 3 : 2) << 8);
755 		/* DQ hold disable (tpr13[26] == 1) */
756 		clrbits_le32(&mctl_ctl->pgcr[2], (1 << 13));
757 	}
758 
759 	/* clear credit value */
760 	setbits_le32(&mctl_com->cccr, 1 << 31);
761 	udelay(10);
762 
763 	mctl_auto_detect_dram_size(socid, &para);
764 	mctl_set_cr(socid, &para);
765 
766 	return (1UL << (para.row_bits + para.bank_bits)) * para.page_size *
767 	       (para.dual_rank ? 2 : 1);
768 }
769