1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * sun8i H3 platform dram controller init
4  *
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>
10  */
11 #include <common.h>
12 #include <asm/io.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/dram.h>
15 #include <asm/arch/cpu.h>
16 #include <linux/kconfig.h>
17 
18 static void mctl_phy_init(u32 val)
19 {
20 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
21 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
22 
23 	writel(val | PIR_INIT, &mctl_ctl->pir);
24 	mctl_await_completion(&mctl_ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
25 }
26 
27 static void mctl_set_bit_delays(struct dram_para *para)
28 {
29 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
30 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
31 	int i, j;
32 
33 	clrbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
34 
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]);
40 
41 	for (i = 0; i < 31; i++)
42 		writel(ACBDLR_WRITE_DELAY(para->ac_delays[i]),
43 		       &mctl_ctl->acbdlr[i]);
44 
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);
49 #endif
50 
51 	setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
52 }
53 
54 enum {
55 	MBUS_PORT_CPU           = 0,
56 	MBUS_PORT_GPU           = 1,
57 	MBUS_PORT_UNUSED	= 2,
58 	MBUS_PORT_DMA           = 3,
59 	MBUS_PORT_VE            = 4,
60 	MBUS_PORT_CSI           = 5,
61 	MBUS_PORT_NAND          = 6,
62 	MBUS_PORT_SS            = 7,
63 	MBUS_PORT_TS            = 8,
64 	MBUS_PORT_DI            = 9,
65 	MBUS_PORT_DE            = 10,
66 	MBUS_PORT_DE_CFD        = 11,
67 	MBUS_PORT_UNKNOWN1	= 12,
68 	MBUS_PORT_UNKNOWN2	= 13,
69 	MBUS_PORT_UNKNOWN3	= 14,
70 };
71 
72 enum {
73 	MBUS_QOS_LOWEST = 0,
74 	MBUS_QOS_LOW,
75 	MBUS_QOS_HIGH,
76 	MBUS_QOS_HIGHEST
77 };
78 
79 inline void mbus_configure_port(u8 port,
80 				bool bwlimit,
81 				bool priority,
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 */
86 				u16 bwl1,
87 				u16 bwl2)
88 {
89 	struct sunxi_mctl_com_reg * const mctl_com =
90 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
91 
92 	const u32 cfg0 = ( (bwlimit ? (1 << 0) : 0)
93 			   | (priority ? (1 << 1) : 0)
94 			   | ((qos & 0x3) << 2)
95 			   | ((waittime & 0xf) << 4)
96 			   | ((acs & 0xff) << 8)
97 			   | (bwl0 << 16) );
98 	const u32 cfg1 = ((u32)bwl2 << 16) | (bwl1 & 0xffff);
99 
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]);
103 }
104 
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)
108 
109 static void mctl_set_master_priority_h3(void)
110 {
111 	struct sunxi_mctl_com_reg * const mctl_com =
112 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
113 
114 	/* enable bandwidth limit windows and set windows size 1us */
115 	writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
116 
117 	/* set cpu high priority */
118 	writel(0x00000001, &mctl_com->mapr);
119 
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);
132 }
133 
134 static void mctl_set_master_priority_a64(void)
135 {
136 	struct sunxi_mctl_com_reg * const mctl_com =
137 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
138 
139 	/* enable bandwidth limit windows and set windows size 1us */
140 	writel(399, &mctl_com->tmr);
141 	writel((1 << 16), &mctl_com->bwcr);
142 
143 	/* Port 2 is reserved per Allwinner's linux-3.10 source, yet they
144 	 * initialise it */
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);
157 
158 	writel(0x81000004, &mctl_com->mdfs_bwlr[2]);
159 }
160 
161 static void mctl_set_master_priority_h5(void)
162 {
163 	struct sunxi_mctl_com_reg * const mctl_com =
164 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
165 
166 	/* enable bandwidth limit windows and set windows size 1us */
167 	writel(399, &mctl_com->tmr);
168 	writel((1 << 16), &mctl_com->bwcr);
169 
170 	/* set cpu high priority */
171 	writel(0x00000001, &mctl_com->mapr);
172 
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);
187 }
188 
189 static void mctl_set_master_priority_r40(void)
190 {
191 	struct sunxi_mctl_com_reg * const mctl_com =
192 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
193 
194 	/* enable bandwidth limit windows and set windows size 1us */
195 	writel(399, &mctl_com->tmr);
196 	writel((1 << 16), &mctl_com->bwcr);
197 
198 	/* set cpu high priority */
199 	writel(0x00000001, &mctl_com->mapr);
200 
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 
214 	/*
215 	 * The port names are probably wrong, but no correct sources
216 	 * are available.
217 	 */
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);
223 }
224 
225 static void mctl_set_master_priority(uint16_t socid)
226 {
227 	switch (socid) {
228 	case SOCID_H3:
229 		mctl_set_master_priority_h3();
230 		return;
231 	case SOCID_A64:
232 		mctl_set_master_priority_a64();
233 		return;
234 	case SOCID_H5:
235 		mctl_set_master_priority_h5();
236 		return;
237 	case SOCID_R40:
238 		mctl_set_master_priority_r40();
239 		return;
240 	}
241 }
242 
243 static u32 bin_to_mgray(int val)
244 {
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,
250 	};
251 
252 	return lookup_table[clamp(val, 0, 31)];
253 }
254 
255 static int mgray_to_bin(u32 val)
256 {
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,
262 	};
263 
264 	return lookup_table[val & 0x1f];
265 }
266 
267 static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
268 {
269 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
270 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
271 	int zq_count;
272 
273 #if defined CONFIG_SUNXI_DRAM_DW_16BIT
274 	zq_count = 4;
275 #else
276 	zq_count = 6;
277 #endif
278 
279 	if ((readl(SUNXI_SRAMC_BASE + 0x24) & 0xff) == 0 &&
280 	    (readl(SUNXI_SRAMC_BASE + 0xf0) & 0x1) == 0) {
281 		u32 reg_val;
282 
283 		clrsetbits_le32(&mctl_ctl->zqcr, 0xffff,
284 				CONFIG_DRAM_ZQ & 0xffff);
285 
286 		writel(PIR_CLRSR, &mctl_ctl->pir);
287 		mctl_phy_init(PIR_ZCAL);
288 
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]);
293 
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]);
299 	} else {
300 		int i;
301 		u16 zq_val[6];
302 		u8 val;
303 
304 		writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
305 
306 		for (i = 0; i < zq_count; i++) {
307 			u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
308 
309 			writel((zq << 20) | (zq << 16) | (zq << 12) |
310 					(zq << 8) | (zq << 4) | (zq << 0),
311 					&mctl_ctl->zqcr);
312 
313 			writel(PIR_CLRSR, &mctl_ctl->pir);
314 			mctl_phy_init(PIR_ZCAL);
315 
316 			zq_val[i] = readl(&mctl_ctl->zqdr[0]) & 0xff;
317 			writel(REPEAT_BYTE(zq_val[i]), &mctl_ctl->zqdr[2]);
318 
319 			writel(PIR_CLRSR, &mctl_ctl->pir);
320 			mctl_phy_init(PIR_ZCAL);
321 
322 			val = readl(&mctl_ctl->zqdr[0]) >> 24;
323 			zq_val[i] |= bin_to_mgray(mgray_to_bin(val) - 1) << 8;
324 		}
325 
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]);
328 		if (zq_count > 4)
329 			writel((zq_val[5] << 16) | zq_val[4],
330 			       &mctl_ctl->zqdr[2]);
331 	}
332 }
333 
334 static void mctl_set_cr(uint16_t socid, struct dram_para *para)
335 {
336 	struct sunxi_mctl_com_reg * const mctl_com =
337 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
338 
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 |
346 #else
347 #error Unsupported DRAM type!
348 #endif
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);
354 
355 	if (socid == SOCID_R40) {
356 		if (para->dual_rank)
357 			panic("Dual rank memory not supported\n");
358 
359 		/* Mux pin to A15 address line for single rank memory. */
360 		setbits_le32(&mctl_com->cr_r1, MCTL_CR_R1_MUX_A15);
361 	}
362 }
363 
364 static void mctl_sys_init(uint16_t socid, struct dram_para *para)
365 {
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;
370 
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);
378 	udelay(10);
379 
380 	clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
381 	udelay(1000);
382 
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);
399 	}
400 	mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
401 
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);
406 
407 	setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
408 	udelay(10);
409 
410 	writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken);
411 	udelay(500);
412 }
413 
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)
418 
419 static int mctl_channel_init(uint16_t socid, struct dram_para *para)
420 {
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;
425 
426 	unsigned int i;
427 
428 	mctl_set_cr(socid, para);
429 	mctl_set_timing_params(socid, para);
430 	mctl_set_master_priority(socid);
431 
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));
436 	else
437 		clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
438 
439 	/* increase DFI_PHY_UPD clock */
440 	writel(PROTECT_MAGIC, &mctl_com->protect);
441 	udelay(100);
442 	clrsetbits_le32(&mctl_ctl->upd2, 0xfff << 16, 0x50 << 16);
443 	writel(0x0, &mctl_com->protect);
444 	udelay(100);
445 
446 	/* set dramc odt */
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;
452 
453 		if (socid == SOCID_H5) {
454 			clearmask |= 0x2 << 8;
455 			setmask |= 0x4 << 8;
456 		}
457 		clrsetbits_le32(&mctl_ctl->dx[i].gcr, clearmask, setmask);
458 	}
459 
460 	/* AC PDR should always ON */
461 	clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0,
462 			0x1 << 1);
463 
464 	/* set DQS auto gating PD mode */
465 	setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
466 
467 	if (socid == SOCID_H3) {
468 		/* dx ddr_clk & hdr_clk dynamic mode */
469 		clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
470 
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));
481 
482 		/* dphy & aphy phase select ? */
483 		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
484 				(0x0 << 10) | (0x3 << 8));
485 	}
486 
487 	/* set half DQ */
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);
494 #else
495 #error Unsupported DRAM bus width!
496 #endif
497 	}
498 
499 	/* data training configuration */
500 	clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24,
501 			(para->dual_rank ? 0x3 : 0x1) << 24);
502 
503 	mctl_set_bit_delays(para);
504 	udelay(50);
505 
506 	if (socid == SOCID_H3) {
507 		mctl_h3_zq_calibration_quirk(para);
508 
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);
513 
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);
519 
520 		mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
521 			      PIR_DRAMRST | PIR_DRAMINIT);
522 	}
523 
524 	/* detect ranks and bus width */
525 	if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
526 		/* only one rank */
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)
530 #endif
531 		    ) {
532 			clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
533 			para->dual_rank = 0;
534 		}
535 
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;
543 		}
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;
548 		}
549 #endif
550 
551 		mctl_set_cr(socid, para);
552 		udelay(20);
553 
554 		/* re-train */
555 		mctl_phy_init(PIR_QSGATE);
556 		if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20))
557 			return 1;
558 	}
559 
560 	/* check the dramc status */
561 	mctl_await_completion(&mctl_ctl->statr, 0x1, 0x1);
562 
563 	/* liuke added for refresh debug */
564 	setbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
565 	udelay(10);
566 	clrbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
567 	udelay(10);
568 
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]);
574 
575 	/* power down zq calibration module for power save */
576 	setbits_le32(&mctl_ctl->zqcr, ZQCR_PWRDOWN);
577 
578 	/* enable master access */
579 	writel(0xffffffff, &mctl_com->maer);
580 
581 	return 0;
582 }
583 
584 static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
585 {
586 	/* detect row address bits */
587 	para->page_size = 512;
588 	para->row_bits = 16;
589 	para->bank_bits = 2;
590 	mctl_set_cr(socid, para);
591 
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))
594 			break;
595 
596 	/* detect bank address bits */
597 	para->bank_bits = 3;
598 	mctl_set_cr(socid, para);
599 
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))
602 			break;
603 
604 	/* detect page size */
605 	para->page_size = 8192;
606 	mctl_set_cr(socid, para);
607 
608 	for (para->page_size = 512; para->page_size < 8192; para->page_size *= 2)
609 		if (mctl_mem_matches(para->page_size))
610 			break;
611 }
612 
613 /*
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.
619  */
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      }
635 
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      }
651 
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      }
667 
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      }
683 
684 unsigned long sunxi_dram_init(void)
685 {
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;
690 
691 	struct dram_para para = {
692 		.dual_rank = 1,
693 		.bus_full_width = 1,
694 		.row_bits = 15,
695 		.bank_bits = 3,
696 		.page_size = 4096,
697 
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,
714 #endif
715 	};
716 /*
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
719  * small.
720  */
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 */
726 	para.dual_rank = 0;
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;
734 #endif
735 
736 	mctl_sys_init(socid, &para);
737 	if (mctl_channel_init(socid, &para))
738 		return 0;
739 
740 	if (para.dual_rank)
741 		writel(0x00000303, &mctl_ctl->odtmap);
742 	else
743 		writel(0x00000201, &mctl_ctl->odtmap);
744 	udelay(1);
745 
746 	/* odt delay */
747 	if (socid == SOCID_H3)
748 		writel(0x0c000400, &mctl_ctl->odtcfg);
749 
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));
756 	}
757 
758 	/* clear credit value */
759 	setbits_le32(&mctl_com->cccr, 1 << 31);
760 	udelay(10);
761 
762 	mctl_auto_detect_dram_size(socid, &para);
763 	mctl_set_cr(socid, &para);
764 
765 	return (1UL << (para.row_bits + para.bank_bits)) * para.page_size *
766 	       (para.dual_rank ? 2 : 1);
767 }
768