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 <init.h>
13 #include <log.h>
14 #include <asm/io.h>
15 #include <asm/arch/clock.h>
16 #include <asm/arch/dram.h>
17 #include <asm/arch/cpu.h>
18 #include <linux/delay.h>
19 #include <linux/kconfig.h>
20 
mctl_phy_init(u32 val)21 static void mctl_phy_init(u32 val)
22 {
23 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
24 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
25 
26 	writel(val | PIR_INIT, &mctl_ctl->pir);
27 	mctl_await_completion(&mctl_ctl->pgsr[0], PGSR_INIT_DONE, 0x1);
28 }
29 
mctl_set_bit_delays(struct dram_para * para)30 static void mctl_set_bit_delays(struct dram_para *para)
31 {
32 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
33 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
34 	int i, j;
35 
36 	clrbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
37 
38 	for (i = 0; i < NR_OF_BYTE_LANES; i++)
39 		for (j = 0; j < LINES_PER_BYTE_LANE; j++)
40 			writel(DXBDLR_WRITE_DELAY(para->dx_write_delays[i][j]) |
41 			       DXBDLR_READ_DELAY(para->dx_read_delays[i][j]),
42 			       &mctl_ctl->dx[i].bdlr[j]);
43 
44 	for (i = 0; i < 31; i++)
45 		writel(ACBDLR_WRITE_DELAY(para->ac_delays[i]),
46 		       &mctl_ctl->acbdlr[i]);
47 
48 #ifdef CONFIG_MACH_SUN8I_R40
49 	/* DQSn, DMn, DQn output enable bit delay */
50 	for (i = 0; i < 4; i++)
51 		writel(0x6 << 24, &mctl_ctl->dx[i].sdlr);
52 #endif
53 
54 	setbits_le32(&mctl_ctl->pgcr[0], 1 << 26);
55 }
56 
57 enum {
58 	MBUS_PORT_CPU           = 0,
59 	MBUS_PORT_GPU           = 1,
60 	MBUS_PORT_UNUSED	= 2,
61 	MBUS_PORT_DMA           = 3,
62 	MBUS_PORT_VE            = 4,
63 	MBUS_PORT_CSI           = 5,
64 	MBUS_PORT_NAND          = 6,
65 	MBUS_PORT_SS            = 7,
66 	MBUS_PORT_DE_V3S        = 8,
67 	MBUS_PORT_DE_CFD_V3S    = 9,
68 	MBUS_PORT_TS            = 8,
69 	MBUS_PORT_DI            = 9,
70 	MBUS_PORT_DE            = 10,
71 	MBUS_PORT_DE_CFD        = 11,
72 	MBUS_PORT_UNKNOWN1	= 12,
73 	MBUS_PORT_UNKNOWN2	= 13,
74 	MBUS_PORT_UNKNOWN3	= 14,
75 };
76 
77 enum {
78 	MBUS_QOS_LOWEST = 0,
79 	MBUS_QOS_LOW,
80 	MBUS_QOS_HIGH,
81 	MBUS_QOS_HIGHEST
82 };
83 
mbus_configure_port(u8 port,bool bwlimit,bool priority,u8 qos,u8 waittime,u8 acs,u16 bwl0,u16 bwl1,u16 bwl2)84 static inline void mbus_configure_port(u8 port,
85 				       bool bwlimit,
86 				       bool priority,
87 				       u8 qos,         /* MBUS_QOS_LOWEST .. MBUS_QOS_HIGEST */
88 				       u8 waittime,    /* 0 .. 0xf */
89 				       u8 acs,         /* 0 .. 0xff */
90 				       u16 bwl0,       /* 0 .. 0xffff, bandwidth limit in MB/s */
91 				       u16 bwl1,
92 				       u16 bwl2)
93 {
94 	struct sunxi_mctl_com_reg * const mctl_com =
95 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
96 
97 	const u32 cfg0 = ( (bwlimit ? (1 << 0) : 0)
98 			   | (priority ? (1 << 1) : 0)
99 			   | ((qos & 0x3) << 2)
100 			   | ((waittime & 0xf) << 4)
101 			   | ((acs & 0xff) << 8)
102 			   | (bwl0 << 16) );
103 	const u32 cfg1 = ((u32)bwl2 << 16) | (bwl1 & 0xffff);
104 
105 	debug("MBUS port %d cfg0 %08x cfg1 %08x\n", port, cfg0, cfg1);
106 	writel(cfg0, &mctl_com->mcr[port][0]);
107 	writel(cfg1, &mctl_com->mcr[port][1]);
108 }
109 
110 #define MBUS_CONF(port, bwlimit, qos, acs, bwl0, bwl1, bwl2)	\
111 	mbus_configure_port(MBUS_PORT_ ## port, bwlimit, false, \
112 			    MBUS_QOS_ ## qos, 0, acs, bwl0, bwl1, bwl2)
113 
mctl_set_master_priority_h3(void)114 static void mctl_set_master_priority_h3(void)
115 {
116 	struct sunxi_mctl_com_reg * const mctl_com =
117 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
118 
119 	/* enable bandwidth limit windows and set windows size 1us */
120 	writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
121 
122 	/* set cpu high priority */
123 	writel(0x00000001, &mctl_com->mapr);
124 
125 	MBUS_CONF(   CPU,  true, HIGHEST, 0,  512,  256,  128);
126 	MBUS_CONF(   GPU,  true,    HIGH, 0, 1536, 1024,  256);
127 	MBUS_CONF(UNUSED,  true, HIGHEST, 0,  512,  256,   96);
128 	MBUS_CONF(   DMA,  true, HIGHEST, 0,  256,  128,   32);
129 	MBUS_CONF(    VE,  true,    HIGH, 0, 1792, 1600,  256);
130 	MBUS_CONF(   CSI,  true, HIGHEST, 0,  256,  128,   32);
131 	MBUS_CONF(  NAND,  true,    HIGH, 0,  256,  128,   64);
132 	MBUS_CONF(    SS,  true, HIGHEST, 0,  256,  128,   64);
133 	MBUS_CONF(    TS,  true, HIGHEST, 0,  256,  128,   64);
134 	MBUS_CONF(    DI,  true,    HIGH, 0, 1024,  256,   64);
135 	MBUS_CONF(    DE,  true, HIGHEST, 3, 8192, 6120, 1024);
136 	MBUS_CONF(DE_CFD,  true,    HIGH, 0, 1024,  288,   64);
137 }
138 
mctl_set_master_priority_v3s(void)139 static void mctl_set_master_priority_v3s(void)
140 {
141 	struct sunxi_mctl_com_reg * const mctl_com =
142 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
143 
144 	/* enable bandwidth limit windows and set windows size 1us */
145 	writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
146 
147 	/* set cpu high priority */
148 	writel(0x00000001, &mctl_com->mapr);
149 
150 	MBUS_CONF(       CPU,  true, HIGHEST, 0,  160,  100,   80);
151 	MBUS_CONF(       GPU,  true,    HIGH, 0, 1792, 1536,    0);
152 	MBUS_CONF(    UNUSED,  true, HIGHEST, 0,  256,  128,   80);
153 	MBUS_CONF(       DMA,  true,    HIGH, 0,  256,  100,    0);
154 	MBUS_CONF(        VE,  true,    HIGH, 0, 2048, 1600,    0);
155 	MBUS_CONF(       CSI,  true, HIGHEST, 0,  384,  256,    0);
156 	MBUS_CONF(      NAND,  true,    HIGH, 0,  100,   50,    0);
157 	MBUS_CONF(        SS,  true,    HIGH, 0,  384,  256,    0);
158 	MBUS_CONF(    DE_V3S, false,    HIGH, 0, 8192, 4096,    0);
159 	MBUS_CONF(DE_CFD_V3S,  true,    HIGH, 0,  640,  256,    0);
160 }
161 
mctl_set_master_priority_a64(void)162 static void mctl_set_master_priority_a64(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 	/* Port 2 is reserved per Allwinner's linux-3.10 source, yet they
172 	 * initialise it */
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);
185 
186 	writel(0x81000004, &mctl_com->mdfs_bwlr[2]);
187 }
188 
mctl_set_master_priority_h5(void)189 static void mctl_set_master_priority_h5(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 	MBUS_CONF(    DE, true, HIGHEST, 3, 3400, 2400, 1024);
214 	MBUS_CONF(DE_CFD, true, HIGHEST, 0,  600,  400,  200);
215 }
216 
mctl_set_master_priority_r40(void)217 static void mctl_set_master_priority_r40(void)
218 {
219 	struct sunxi_mctl_com_reg * const mctl_com =
220 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
221 
222 	/* enable bandwidth limit windows and set windows size 1us */
223 	writel(399, &mctl_com->tmr);
224 	writel((1 << 16), &mctl_com->bwcr);
225 
226 	/* set cpu high priority */
227 	writel(0x00000001, &mctl_com->mapr);
228 
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);
241 
242 	/*
243 	 * The port names are probably wrong, but no correct sources
244 	 * are available.
245 	 */
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);
251 }
252 
mctl_set_master_priority(uint16_t socid)253 static void mctl_set_master_priority(uint16_t socid)
254 {
255 	switch (socid) {
256 	case SOCID_H3:
257 		mctl_set_master_priority_h3();
258 		return;
259 	case SOCID_V3S:
260 		mctl_set_master_priority_v3s();
261 		return;
262 	case SOCID_A64:
263 		mctl_set_master_priority_a64();
264 		return;
265 	case SOCID_H5:
266 		mctl_set_master_priority_h5();
267 		return;
268 	case SOCID_R40:
269 		mctl_set_master_priority_r40();
270 		return;
271 	}
272 }
273 
bin_to_mgray(int val)274 static u32 bin_to_mgray(int val)
275 {
276 	static const u8 lookup_table[32] = {
277 		0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
278 		0x0c, 0x0d, 0x0e, 0x0f, 0x0a, 0x0b, 0x08, 0x09,
279 		0x18, 0x19, 0x1a, 0x1b, 0x1e, 0x1f, 0x1c, 0x1d,
280 		0x14, 0x15, 0x16, 0x17, 0x12, 0x13, 0x10, 0x11,
281 	};
282 
283 	return lookup_table[clamp(val, 0, 31)];
284 }
285 
mgray_to_bin(u32 val)286 static int mgray_to_bin(u32 val)
287 {
288 	static const u8 lookup_table[32] = {
289 		0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05,
290 		0x0e, 0x0f, 0x0c, 0x0d, 0x08, 0x09, 0x0a, 0x0b,
291 		0x1e, 0x1f, 0x1c, 0x1d, 0x18, 0x19, 0x1a, 0x1b,
292 		0x10, 0x11, 0x12, 0x13, 0x16, 0x17, 0x14, 0x15,
293 	};
294 
295 	return lookup_table[val & 0x1f];
296 }
297 
mctl_h3_zq_calibration_quirk(struct dram_para * para)298 static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
299 {
300 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
301 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
302 	int zq_count;
303 
304 #if defined CONFIG_SUNXI_DRAM_DW_16BIT
305 	zq_count = 4;
306 #else
307 	zq_count = 6;
308 #endif
309 
310 	if ((readl(SUNXI_SRAMC_BASE + 0x24) & 0xff) == 0 &&
311 	    (readl(SUNXI_SRAMC_BASE + 0xf0) & 0x1) == 0) {
312 		u32 reg_val;
313 
314 		clrsetbits_le32(&mctl_ctl->zqcr, 0xffff,
315 				CONFIG_DRAM_ZQ & 0xffff);
316 
317 		writel(PIR_CLRSR, &mctl_ctl->pir);
318 		mctl_phy_init(PIR_ZCAL);
319 
320 		reg_val = readl(&mctl_ctl->zqdr[0]);
321 		reg_val &= (0x1f << 16) | (0x1f << 0);
322 		reg_val |= reg_val << 8;
323 		writel(reg_val, &mctl_ctl->zqdr[0]);
324 
325 		reg_val = readl(&mctl_ctl->zqdr[1]);
326 		reg_val &= (0x1f << 16) | (0x1f << 0);
327 		reg_val |= reg_val << 8;
328 		writel(reg_val, &mctl_ctl->zqdr[1]);
329 		writel(reg_val, &mctl_ctl->zqdr[2]);
330 	} else {
331 		int i;
332 		u16 zq_val[6];
333 		u8 val;
334 
335 		writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]);
336 
337 		for (i = 0; i < zq_count; i++) {
338 			u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf;
339 
340 			writel((zq << 20) | (zq << 16) | (zq << 12) |
341 					(zq << 8) | (zq << 4) | (zq << 0),
342 					&mctl_ctl->zqcr);
343 
344 			writel(PIR_CLRSR, &mctl_ctl->pir);
345 			mctl_phy_init(PIR_ZCAL);
346 
347 			zq_val[i] = readl(&mctl_ctl->zqdr[0]) & 0xff;
348 			writel(REPEAT_BYTE(zq_val[i]), &mctl_ctl->zqdr[2]);
349 
350 			writel(PIR_CLRSR, &mctl_ctl->pir);
351 			mctl_phy_init(PIR_ZCAL);
352 
353 			val = readl(&mctl_ctl->zqdr[0]) >> 24;
354 			zq_val[i] |= bin_to_mgray(mgray_to_bin(val) - 1) << 8;
355 		}
356 
357 		writel((zq_val[1] << 16) | zq_val[0], &mctl_ctl->zqdr[0]);
358 		writel((zq_val[3] << 16) | zq_val[2], &mctl_ctl->zqdr[1]);
359 		if (zq_count > 4)
360 			writel((zq_val[5] << 16) | zq_val[4],
361 			       &mctl_ctl->zqdr[2]);
362 	}
363 }
364 
mctl_v3s_zq_calibration_quirk(struct dram_para * para)365 static void mctl_v3s_zq_calibration_quirk(struct dram_para *para)
366 {
367 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
368 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
369 
370 	u32 reg_val;
371 
372 	clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff,
373 			CONFIG_DRAM_ZQ & 0xffffff);
374 	mctl_phy_init(PIR_ZCAL);
375 
376 	reg_val = readl(&mctl_ctl->zqdr[0]);
377 	reg_val &= (0x1f << 16) | (0x1f << 0);
378 	reg_val |= reg_val << 8;
379 	writel(reg_val, &mctl_ctl->zqdr[0]);
380 
381 	reg_val = readl(&mctl_ctl->zqdr[1]);
382 	reg_val &= (0x1f << 16) | (0x1f << 0);
383 	reg_val |= reg_val << 8;
384 	writel(reg_val, &mctl_ctl->zqdr[1]);
385 }
386 
mctl_set_cr(uint16_t socid,struct dram_para * para)387 static void mctl_set_cr(uint16_t socid, struct dram_para *para)
388 {
389 	struct sunxi_mctl_com_reg * const mctl_com =
390 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
391 
392 	writel(MCTL_CR_BL8 | MCTL_CR_INTERLEAVED |
393 #if defined CONFIG_SUNXI_DRAM_DDR3
394 	       MCTL_CR_DDR3 | MCTL_CR_2T |
395 #elif defined CONFIG_SUNXI_DRAM_DDR2
396 	       MCTL_CR_DDR2 | MCTL_CR_2T |
397 #elif defined CONFIG_SUNXI_DRAM_LPDDR3
398 	       MCTL_CR_LPDDR3 | MCTL_CR_1T |
399 #else
400 #error Unsupported DRAM type!
401 #endif
402 	       (para->ranks[0].bank_bits == 3 ? MCTL_CR_EIGHT_BANKS : MCTL_CR_FOUR_BANKS) |
403 	       MCTL_CR_BUS_FULL_WIDTH(para->bus_full_width) |
404 	       (para->dual_rank ? MCTL_CR_DUAL_RANK : MCTL_CR_SINGLE_RANK) |
405 	       MCTL_CR_PAGE_SIZE(para->ranks[0].page_size) |
406 	       MCTL_CR_ROW_BITS(para->ranks[0].row_bits), &mctl_com->cr);
407 
408 	if (para->dual_rank && (socid == SOCID_A64 || socid == SOCID_R40)) {
409 		writel((para->ranks[1].bank_bits == 3 ? MCTL_CR_EIGHT_BANKS : MCTL_CR_FOUR_BANKS) |
410 		       MCTL_CR_BUS_FULL_WIDTH(para->bus_full_width) |
411 		       MCTL_CR_DUAL_RANK |
412 		       MCTL_CR_PAGE_SIZE(para->ranks[1].page_size) |
413 		       MCTL_CR_ROW_BITS(para->ranks[1].row_bits), &mctl_com->cr_r1);
414 	}
415 
416 	if (socid == SOCID_R40) {
417 		/* Mux pin to A15 address line for single rank memory. */
418 		if (!para->dual_rank)
419 			setbits_le32(&mctl_com->cr_r1, MCTL_CR_R1_MUX_A15);
420 	}
421 }
422 
mctl_sys_init(uint16_t socid,struct dram_para * para)423 static void mctl_sys_init(uint16_t socid, struct dram_para *para)
424 {
425 	struct sunxi_ccm_reg * const ccm =
426 			(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
427 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
428 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
429 
430 	clrbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
431 	clrbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
432 	clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
433 	clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
434 	clrbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_EN);
435 	if (socid == SOCID_A64 || socid == SOCID_R40)
436 		clrbits_le32(&ccm->pll11_cfg, CCM_PLL11_CTRL_EN);
437 	udelay(10);
438 
439 	clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
440 	udelay(1000);
441 
442 	if (socid == SOCID_A64 || socid == SOCID_R40) {
443 		clock_set_pll11(CONFIG_DRAM_CLK * 2 * 1000000, false);
444 		clrsetbits_le32(&ccm->dram_clk_cfg,
445 				CCM_DRAMCLK_CFG_DIV_MASK |
446 				CCM_DRAMCLK_CFG_SRC_MASK,
447 				CCM_DRAMCLK_CFG_DIV(1) |
448 				CCM_DRAMCLK_CFG_SRC_PLL11 |
449 				CCM_DRAMCLK_CFG_UPD);
450 	} else if (socid == SOCID_H3 || socid == SOCID_H5 || socid == SOCID_V3S) {
451 		clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false);
452 		clrsetbits_le32(&ccm->dram_clk_cfg,
453 				CCM_DRAMCLK_CFG_DIV_MASK |
454 				CCM_DRAMCLK_CFG_SRC_MASK,
455 				CCM_DRAMCLK_CFG_DIV(1) |
456 				CCM_DRAMCLK_CFG_SRC_PLL5 |
457 				CCM_DRAMCLK_CFG_UPD);
458 	}
459 	mctl_await_completion(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_UPD, 0);
460 
461 	setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL);
462 	setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL);
463 	setbits_le32(&ccm->mbus_reset, CCM_MBUS_RESET_RESET);
464 	setbits_le32(&ccm->mbus0_clk_cfg, MBUS_CLK_GATE);
465 
466 	setbits_le32(&ccm->dram_clk_cfg, CCM_DRAMCLK_CFG_RST);
467 	udelay(10);
468 
469 	writel(socid == SOCID_H5 ? 0x8000 : 0xc00e, &mctl_ctl->clken);
470 	udelay(500);
471 }
472 
473 /* These are more guessed based on some Allwinner code. */
474 #define DX_GCR_ODT_DYNAMIC	(0x0 << 4)
475 #define DX_GCR_ODT_ALWAYS_ON	(0x1 << 4)
476 #define DX_GCR_ODT_OFF		(0x2 << 4)
477 
mctl_channel_init(uint16_t socid,struct dram_para * para)478 static int mctl_channel_init(uint16_t socid, struct dram_para *para)
479 {
480 	struct sunxi_mctl_com_reg * const mctl_com =
481 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
482 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
483 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
484 
485 	unsigned int i;
486 
487 	mctl_set_cr(socid, para);
488 	mctl_set_timing_params(socid, para);
489 	mctl_set_master_priority(socid);
490 
491 	/* setting VTC, default disable all VT */
492 	clrbits_le32(&mctl_ctl->pgcr[0], (1 << 30) | 0x3f);
493 	if (socid == SOCID_H5)
494 		setbits_le32(&mctl_ctl->pgcr[1], (1 << 24) | (1 << 26));
495 	else
496 		clrsetbits_le32(&mctl_ctl->pgcr[1], 1 << 24, 1 << 26);
497 
498 	/* increase DFI_PHY_UPD clock */
499 	writel(PROTECT_MAGIC, &mctl_com->protect);
500 	udelay(100);
501 	clrsetbits_le32(&mctl_ctl->upd2, 0xfff << 16, 0x50 << 16);
502 	writel(0x0, &mctl_com->protect);
503 	udelay(100);
504 
505 	/* set dramc odt */
506 	for (i = 0; i < 4; i++) {
507 		u32 clearmask = (0x3 << 4) | (0x1 << 1) | (0x3 << 2) |
508 				(0x3 << 12) | (0x3 << 14);
509 		u32 setmask = IS_ENABLED(CONFIG_DRAM_ODT_EN) ?
510 				DX_GCR_ODT_DYNAMIC : DX_GCR_ODT_OFF;
511 
512 		if (socid == SOCID_H5) {
513 			clearmask |= 0x2 << 8;
514 			setmask |= 0x4 << 8;
515 		}
516 		clrsetbits_le32(&mctl_ctl->dx[i].gcr, clearmask, setmask);
517 	}
518 
519 	/* AC PDR should always ON */
520 	clrsetbits_le32(&mctl_ctl->aciocr, socid == SOCID_H5 ? (0x1 << 11) : 0,
521 			0x1 << 1);
522 
523 	/* set DQS auto gating PD mode */
524 	setbits_le32(&mctl_ctl->pgcr[2], 0x3 << 6);
525 
526 	if (socid == SOCID_H3) {
527 		/* dx ddr_clk & hdr_clk dynamic mode */
528 		clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
529 
530 		/* dphy & aphy phase select 270 degree */
531 		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
532 				(0x1 << 10) | (0x2 << 8));
533 	} else if (socid == SOCID_V3S) {
534 		/* dx ddr_clk & hdr_clk dynamic mode */
535 		clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
536 
537 		/* dphy & aphy phase select 270 degree */
538 		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
539 				(0x1 << 10) | (0x1 << 8));
540 	} else if (socid == SOCID_A64 || socid == SOCID_H5) {
541 		/* dphy & aphy phase select ? */
542 		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
543 				(0x0 << 10) | (0x3 << 8));
544 	} else if (socid == SOCID_R40) {
545 		/* dx ddr_clk & hdr_clk dynamic mode (tpr13[9] == 0) */
546 		clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
547 
548 		/* dphy & aphy phase select ? */
549 		clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
550 				(0x0 << 10) | (0x3 << 8));
551 	}
552 
553 	/* set half DQ */
554 	if (!para->bus_full_width) {
555 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
556 		writel(0x0, &mctl_ctl->dx[2].gcr);
557 		writel(0x0, &mctl_ctl->dx[3].gcr);
558 #elif defined CONFIG_SUNXI_DRAM_DW_16BIT
559 		writel(0x0, &mctl_ctl->dx[1].gcr);
560 #else
561 #error Unsupported DRAM bus width!
562 #endif
563 	}
564 
565 	/* data training configuration */
566 	clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24,
567 			(para->dual_rank ? 0x3 : 0x1) << 24);
568 
569 	mctl_set_bit_delays(para);
570 	udelay(50);
571 
572 	if (socid == SOCID_V3S) {
573 		mctl_v3s_zq_calibration_quirk(para);
574 
575 		mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
576 			      PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
577 	} else if (socid == SOCID_H3) {
578 		mctl_h3_zq_calibration_quirk(para);
579 
580 		mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
581 			      PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
582 	} else if (socid == SOCID_A64 || socid == SOCID_H5) {
583 		clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
584 
585 		mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
586 			      PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
587 		/* no PIR_QSGATE for H5 ???? */
588 	} else if (socid == SOCID_R40) {
589 		clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff, CONFIG_DRAM_ZQ);
590 
591 		mctl_phy_init(PIR_ZCAL | PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
592 			      PIR_DRAMRST | PIR_DRAMINIT);
593 	}
594 
595 	/* detect ranks and bus width */
596 	if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20)) {
597 		/* only one rank */
598 		if (((readl(&mctl_ctl->dx[0].gsr[0]) >> 24) & 0x2)
599 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
600 		    || ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x2)
601 #endif
602 		    ) {
603 			clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
604 			para->dual_rank = 0;
605 		}
606 
607 		/* only half DQ width */
608 #if defined CONFIG_SUNXI_DRAM_DW_32BIT
609 		if (((readl(&mctl_ctl->dx[2].gsr[0]) >> 24) & 0x1) ||
610 		    ((readl(&mctl_ctl->dx[3].gsr[0]) >> 24) & 0x1)) {
611 			writel(0x0, &mctl_ctl->dx[2].gcr);
612 			writel(0x0, &mctl_ctl->dx[3].gcr);
613 			para->bus_full_width = 0;
614 		}
615 #elif defined CONFIG_SUNXI_DRAM_DW_16BIT
616 		if ((readl(&mctl_ctl->dx[1].gsr[0]) >> 24) & 0x1) {
617 			writel(0x0, &mctl_ctl->dx[1].gcr);
618 			para->bus_full_width = 0;
619 		}
620 #endif
621 
622 		mctl_set_cr(socid, para);
623 		udelay(20);
624 
625 		/* re-train */
626 		mctl_phy_init(PIR_QSGATE);
627 		if (readl(&mctl_ctl->pgsr[0]) & (0xfe << 20))
628 			return 1;
629 	}
630 
631 	/* check the dramc status */
632 	mctl_await_completion(&mctl_ctl->statr, 0x1, 0x1);
633 
634 	/* liuke added for refresh debug */
635 	setbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
636 	udelay(10);
637 	clrbits_le32(&mctl_ctl->rfshctl0, 0x1 << 31);
638 	udelay(10);
639 
640 	/* set PGCR3, CKE polarity */
641 	if (socid == SOCID_H3 || socid == SOCID_V3S)
642 		writel(0x00aa0060, &mctl_ctl->pgcr[3]);
643 	else if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40)
644 		writel(0xc0aa0060, &mctl_ctl->pgcr[3]);
645 
646 	/* power down zq calibration module for power save */
647 	setbits_le32(&mctl_ctl->zqcr, ZQCR_PWRDOWN);
648 
649 	/* enable master access */
650 	writel(0xffffffff, &mctl_com->maer);
651 
652 	return 0;
653 }
654 
655 /*
656  * Test if memory at offset offset matches memory at a certain base
657  */
mctl_mem_matches_base(u32 offset,ulong base)658 static bool mctl_mem_matches_base(u32 offset, ulong base)
659 {
660 	/* Try to write different values to RAM at two addresses */
661 	writel(0, base);
662 	writel(0xaa55aa55, base + offset);
663 	dsb();
664 	/* Check if the same value is actually observed when reading back */
665 	return readl(base) ==
666 	       readl(base + offset);
667 }
668 
mctl_auto_detect_dram_size_rank(uint16_t socid,struct dram_para * para,ulong base,struct rank_para * rank)669 static void mctl_auto_detect_dram_size_rank(uint16_t socid, struct dram_para *para, ulong base, struct rank_para *rank)
670 {
671 	/* detect row address bits */
672 	rank->page_size = 512;
673 	rank->row_bits = 16;
674 	rank->bank_bits = 2;
675 	mctl_set_cr(socid, para);
676 
677 	for (rank->row_bits = 11; rank->row_bits < 16; rank->row_bits++)
678 		if (mctl_mem_matches_base((1 << (rank->row_bits + rank->bank_bits)) * rank->page_size, base))
679 			break;
680 
681 	/* detect bank address bits */
682 	rank->bank_bits = 3;
683 	mctl_set_cr(socid, para);
684 
685 	for (rank->bank_bits = 2; rank->bank_bits < 3; rank->bank_bits++)
686 		if (mctl_mem_matches_base((1 << rank->bank_bits) * rank->page_size, base))
687 			break;
688 
689 	/* detect page size */
690 	rank->page_size = 8192;
691 	mctl_set_cr(socid, para);
692 
693 	for (rank->page_size = 512; rank->page_size < 8192; rank->page_size *= 2)
694 		if (mctl_mem_matches_base(rank->page_size, base))
695 			break;
696 }
697 
mctl_calc_rank_size(struct rank_para * rank)698 static unsigned long mctl_calc_rank_size(struct rank_para *rank)
699 {
700 	return (1UL << (rank->row_bits + rank->bank_bits)) * rank->page_size;
701 }
702 
703 /*
704  * Because we cannot do mctl_phy_init(PIR_QSGATE) on R40 now (which leads
705  * to failure), it's needed to detect the rank count of R40 in another way.
706  *
707  * The code here is modelled after time_out_detect() in BSP, which tries to
708  * access the memory and check for error code.
709  *
710  * TODO: auto detect half DQ width here
711  */
mctl_r40_detect_rank_count(struct dram_para * para)712 static void mctl_r40_detect_rank_count(struct dram_para *para)
713 {
714 	ulong rank1_base = (ulong) CONFIG_SYS_SDRAM_BASE +
715 			   mctl_calc_rank_size(&para->ranks[0]);
716 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
717 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
718 
719 	/* Enable read time out */
720 	setbits_le32(&mctl_ctl->pgcr[0], 0x1 << 25);
721 
722 	(void) readl((void *) rank1_base);
723 	udelay(10);
724 
725 	if (readl(&mctl_ctl->pgsr[0]) & (0x1 << 13)) {
726 		clrsetbits_le32(&mctl_ctl->dtcr, 0xf << 24, 0x1 << 24);
727 		para->dual_rank = 0;
728 	}
729 
730 	/* Reset PHY FIFO to clear it */
731 	clrbits_le32(&mctl_ctl->pgcr[0], 0x1 << 26);
732 	udelay(100);
733 	setbits_le32(&mctl_ctl->pgcr[0], 0x1 << 26);
734 
735 	/* Clear error status */
736 	setbits_le32(&mctl_ctl->pgcr[0], 0x1 << 24);
737 
738 	/* Clear time out flag */
739 	clrbits_le32(&mctl_ctl->pgsr[0], 0x1 << 13);
740 
741 	/* Disable read time out */
742 	clrbits_le32(&mctl_ctl->pgcr[0], 0x1 << 25);
743 }
744 
mctl_auto_detect_dram_size(uint16_t socid,struct dram_para * para)745 static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
746 {
747 	mctl_auto_detect_dram_size_rank(socid, para, (ulong)CONFIG_SYS_SDRAM_BASE, &para->ranks[0]);
748 
749 	if ((socid == SOCID_A64 || socid == SOCID_R40) && para->dual_rank) {
750 		mctl_auto_detect_dram_size_rank(socid, para, (ulong)CONFIG_SYS_SDRAM_BASE + mctl_calc_rank_size(&para->ranks[0]), &para->ranks[1]);
751 	}
752 }
753 
754 /*
755  * The actual values used here are taken from Allwinner provided boot0
756  * binaries, though they are probably board specific, so would likely benefit
757  * from invidual tuning for each board. Apparently a lot of boards copy from
758  * some Allwinner reference design, so we go with those generic values for now
759  * in the hope that they are reasonable for most (all?) boards.
760  */
761 #define SUN8I_H3_DX_READ_DELAYS					\
762 	{{ 18, 18, 18, 18, 18, 18, 18, 18, 18,  0,  0 },	\
763 	 { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 },	\
764 	 { 18, 18, 18, 18, 18, 18, 18, 18, 18,  0,  0 },	\
765 	 { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 }}
766 #define SUN8I_H3_DX_WRITE_DELAYS				\
767 	{{  0,  0,  0,  0,  0,  0,  0,  0,  0, 10, 10 },	\
768 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0, 10, 10 },	\
769 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0, 10, 10 },	\
770 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  6 }}
771 #define SUN8I_H3_AC_DELAYS					\
772 	{  0,  0,  0,  0,  0,  0,  0,  0,			\
773 	   0,  0,  0,  0,  0,  0,  0,  0,			\
774 	   0,  0,  0,  0,  0,  0,  0,  0,			\
775 	   0,  0,  0,  0,  0,  0,  0      }
776 
777 #define SUN8I_V3S_DX_READ_DELAYS					\
778 	{{  8,  8,  8,  8,  8,  8,  8,  8,  8,  0,  0 },	\
779 	 {  7,  7,  7,  7,  7,  7,  7,  7,  7,  0,  0 },	\
780 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },	\
781 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }}
782 #define SUN8I_V3S_DX_WRITE_DELAYS				\
783 	{{  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  4 },	\
784 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  2 },	\
785 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },	\
786 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }}
787 #define SUN8I_V3S_AC_DELAYS					\
788 	{  0,  0,  0,  0,  0,  0,  0,  0,			\
789 	   0,  0,  0,  0,  0,  0,  0,  0,			\
790 	   0,  0,  0,  0,  0,  0,  0,  0,			\
791 	   0,  0,  0,  0,  0,  0,  0      }
792 
793 #define SUN8I_R40_DX_READ_DELAYS				\
794 	{{ 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 },	\
795 	 { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 },	\
796 	 { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 },	\
797 	 { 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  0 } }
798 #define SUN8I_R40_DX_WRITE_DELAYS				\
799 	{{  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0 },	\
800 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0 },	\
801 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0 },	\
802 	 {  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0 } }
803 #define SUN8I_R40_AC_DELAYS					\
804 	{  0,  0,  3,  0,  0,  0,  0,  0,			\
805 	   0,  0,  0,  0,  0,  0,  0,  0,			\
806 	   0,  0,  0,  0,  0,  0,  0,  0,			\
807 	   0,  0,  0,  0,  0,  0,  0      }
808 
809 #define SUN50I_A64_DX_READ_DELAYS				\
810 	{{ 16, 16, 16, 16, 17, 16, 16, 17, 16,  1,  0 },	\
811 	 { 17, 17, 17, 17, 17, 17, 17, 17, 17,  1,  0 },	\
812 	 { 16, 17, 17, 16, 16, 16, 16, 16, 16,  0,  0 },	\
813 	 { 17, 17, 17, 17, 17, 17, 17, 17, 17,  1,  0 }}
814 #define SUN50I_A64_DX_WRITE_DELAYS				\
815 	{{  0,  0,  0,  0,  0,  0,  0,  0,  0, 15, 15 },	\
816 	 {  0,  0,  0,  0,  1,  1,  1,  1,  0, 10, 10 },	\
817 	 {  1,  0,  1,  1,  1,  1,  1,  1,  0, 11, 11 },	\
818 	 {  1,  0,  0,  1,  1,  1,  1,  1,  0, 12, 12 }}
819 #define SUN50I_A64_AC_DELAYS					\
820 	{  5,  5, 13, 10,  2,  5,  3,  3,			\
821 	   0,  3,  3,  3,  1,  0,  0,  0,			\
822 	   3,  4,  0,  3,  4,  1,  4,  0,			\
823 	   1,  1,  0,  1, 13,  5,  4      }
824 
825 #define SUN8I_H5_DX_READ_DELAYS					\
826 	{{ 14, 15, 17, 17, 17, 17, 17, 18, 17,  3,  3 },	\
827 	 { 21, 21, 12, 22, 21, 21, 21, 21, 21,  3,  3 },	\
828 	 { 16, 19, 19, 17, 22, 22, 21, 22, 19,  3,  3 },	\
829 	 { 21, 21, 22, 22, 20, 21, 19, 19, 19,  3,  3 } }
830 #define SUN8I_H5_DX_WRITE_DELAYS				\
831 	{{  1,  2,  3,  4,  3,  4,  4,  4,  6,  6,  6 },	\
832 	 {  6,  6,  6,  5,  5,  5,  5,  5,  6,  6,  6 },	\
833 	 {  0,  2,  4,  2,  6,  5,  5,  5,  6,  6,  6 },	\
834 	 {  3,  3,  3,  2,  2,  1,  1,  1,  4,  4,  4 } }
835 #define SUN8I_H5_AC_DELAYS					\
836 	{  0,  0,  5,  5,  0,  0,  0,  0,			\
837 	   0,  0,  0,  0,  3,  3,  3,  3,			\
838 	   3,  3,  3,  3,  3,  3,  3,  3,			\
839 	   3,  3,  3,  3,  2,  0,  0      }
840 
sunxi_dram_init(void)841 unsigned long sunxi_dram_init(void)
842 {
843 	struct sunxi_mctl_com_reg * const mctl_com =
844 			(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
845 	struct sunxi_mctl_ctl_reg * const mctl_ctl =
846 			(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
847 
848 	unsigned long size;
849 
850 	struct dram_para para = {
851 		.dual_rank = 1,
852 		.bus_full_width = 1,
853 		.ranks = {
854 			{
855 				.row_bits = 15,
856 				.bank_bits = 3,
857 				.page_size = 4096,
858 			},
859 			{
860 				.row_bits = 15,
861 				.bank_bits = 3,
862 				.page_size = 4096,
863 			}
864 		},
865 
866 #if defined(CONFIG_MACH_SUN8I_H3)
867 		.dx_read_delays  = SUN8I_H3_DX_READ_DELAYS,
868 		.dx_write_delays = SUN8I_H3_DX_WRITE_DELAYS,
869 		.ac_delays	 = SUN8I_H3_AC_DELAYS,
870 #elif defined(CONFIG_MACH_SUN8I_V3S)
871 		.dx_read_delays  = SUN8I_V3S_DX_READ_DELAYS,
872 		.dx_write_delays = SUN8I_V3S_DX_WRITE_DELAYS,
873 		.ac_delays	 = SUN8I_V3S_AC_DELAYS,
874 #elif defined(CONFIG_MACH_SUN8I_R40)
875 		.dx_read_delays  = SUN8I_R40_DX_READ_DELAYS,
876 		.dx_write_delays = SUN8I_R40_DX_WRITE_DELAYS,
877 		.ac_delays	 = SUN8I_R40_AC_DELAYS,
878 #elif defined(CONFIG_MACH_SUN50I)
879 		.dx_read_delays  = SUN50I_A64_DX_READ_DELAYS,
880 		.dx_write_delays = SUN50I_A64_DX_WRITE_DELAYS,
881 		.ac_delays	 = SUN50I_A64_AC_DELAYS,
882 #elif defined(CONFIG_MACH_SUN50I_H5)
883 		.dx_read_delays  = SUN8I_H5_DX_READ_DELAYS,
884 		.dx_write_delays = SUN8I_H5_DX_WRITE_DELAYS,
885 		.ac_delays	 = SUN8I_H5_AC_DELAYS,
886 #endif
887 	};
888 /*
889  * Let the compiler optimize alternatives away by passing this value into
890  * the static functions. This saves us #ifdefs, but still keeps the binary
891  * small.
892  */
893 #if defined(CONFIG_MACH_SUN8I_H3)
894 	uint16_t socid = SOCID_H3;
895 #elif defined(CONFIG_MACH_SUN8I_R40)
896 	uint16_t socid = SOCID_R40;
897 #elif defined(CONFIG_MACH_SUN8I_V3S)
898 	uint16_t socid = SOCID_V3S;
899 #elif defined(CONFIG_MACH_SUN50I)
900 	uint16_t socid = SOCID_A64;
901 #elif defined(CONFIG_MACH_SUN50I_H5)
902 	uint16_t socid = SOCID_H5;
903 #endif
904 
905 	mctl_sys_init(socid, &para);
906 	if (mctl_channel_init(socid, &para))
907 		return 0;
908 
909 	if (para.dual_rank)
910 		writel(0x00000303, &mctl_ctl->odtmap);
911 	else
912 		writel(0x00000201, &mctl_ctl->odtmap);
913 	udelay(1);
914 
915 	/* odt delay */
916 	if (socid == SOCID_H3)
917 		writel(0x0c000400, &mctl_ctl->odtcfg);
918 
919 	if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40) {
920 		/* VTF enable (tpr13[8] == 1) */
921 		setbits_le32(&mctl_ctl->vtfcr,
922 			     (socid != SOCID_A64 ? 3 : 2) << 8);
923 		/* DQ hold disable (tpr13[26] == 1) */
924 		clrbits_le32(&mctl_ctl->pgcr[2], (1 << 13));
925 	}
926 
927 	/* clear credit value */
928 	setbits_le32(&mctl_com->cccr, 1 << 31);
929 	udelay(10);
930 
931 	if (socid == SOCID_R40) {
932 		mctl_r40_detect_rank_count(&para);
933 		mctl_set_cr(SOCID_R40, &para);
934 	}
935 
936 	mctl_auto_detect_dram_size(socid, &para);
937 	mctl_set_cr(socid, &para);
938 
939 	size = mctl_calc_rank_size(&para.ranks[0]);
940 	if (socid == SOCID_A64 || socid == SOCID_R40) {
941 		if (para.dual_rank)
942 			size += mctl_calc_rank_size(&para.ranks[1]);
943 	} else if (para.dual_rank) {
944 		size *= 2;
945 	}
946 
947 	return size;
948 }
949