xref: /rk3399_rockchip-uboot/drivers/mmc/rockchip_sdhci.c (revision edafafc4b7ef99a12dd162f389bf9c036ad51b05)
1 /*
2  * (C) Copyright 2016 Fuzhou Rockchip Electronics Co., Ltd
3  *
4  * Rockchip SD Host Controller Interface
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
7  */
8 
9 #include <asm/arch/hardware.h>
10 #include <common.h>
11 #include <dm.h>
12 #include <dt-structs.h>
13 #include <linux/libfdt.h>
14 #include <malloc.h>
15 #include <mapmem.h>
16 #include <sdhci.h>
17 #include <clk.h>
18 #include <syscon.h>
19 #include <dm/ofnode.h>
20 #include <asm/arch/clock.h>
21 
22 DECLARE_GLOBAL_DATA_PTR;
23 /* 400KHz is max freq for card ID etc. Use that as min */
24 #define EMMC_MIN_FREQ	400000
25 #define KHz	(1000)
26 #define MHz	(1000 * KHz)
27 
28 #define PHYCTRL_CALDONE_MASK		0x1
29 #define PHYCTRL_CALDONE_SHIFT		0x6
30 #define PHYCTRL_CALDONE_DONE		0x1
31 #define PHYCTRL_DLLRDY_MASK		0x1
32 #define PHYCTRL_DLLRDY_SHIFT		0x5
33 #define PHYCTRL_DLLRDY_DONE		0x1
34 #define PHYCTRL_FREQSEL_200M		0x0
35 #define PHYCTRL_FREQSEL_50M		0x1
36 #define PHYCTRL_FREQSEL_100M		0x2
37 #define PHYCTRL_FREQSEL_150M		0x3
38 #define PHYCTRL_DLL_LOCK_WO_TMOUT(x)	\
39 	((((x) >> PHYCTRL_DLLRDY_SHIFT) & PHYCTRL_DLLRDY_MASK) ==\
40 	PHYCTRL_DLLRDY_DONE)
41 
42 #define ARASAN_VENDOR_REGISTER		0x78
43 #define ARASAN_VENDOR_ENHANCED_STROBE	BIT(0)
44 
45 /* DWC IP vendor area 1 pointer */
46 #define DWCMSHC_P_VENDOR_AREA1		0xe8
47 #define DWCMSHC_AREA1_MASK		GENMASK(11, 0)
48 /* Rockchip specific Registers */
49 #define DWCMSHC_CTRL_HS400		0x7
50 #define DWCMSHC_CARD_IS_EMMC		BIT(0)
51 #define DWCMSHC_ENHANCED_STROBE		BIT(8)
52 
53 #define DWCMSHC_HOST_CTRL3		0x508
54 #define DWCMSHC_EMMC_CONTROL		0x52c
55 #define DWCMSHC_EMMC_ATCTRL		0x540
56 #define DWCMSHC_EMMC_DLL_CTRL		0x800
57 #define DWCMSHC_EMMC_DLL_CTRL_RESET	BIT(1)
58 #define DWCMSHC_EMMC_DLL_RXCLK		0x804
59 #define DWCMSHC_EMMC_DLL_TXCLK		0x808
60 #define DWCMSHC_EMMC_DLL_STRBIN		0x80c
61 #define DECMSHC_EMMC_DLL_CMDOUT		0x810
62 #define DWCMSHC_EMMC_DLL_STATUS0	0x840
63 #define DWCMSHC_EMMC_DLL_STATUS1	0x844
64 #define DWCMSHC_EMMC_DLL_START		BIT(0)
65 #define DWCMSHC_EMMC_DLL_START_POINT	16
66 #define DWCMSHC_EMMC_DLL_START_DEFAULT	5
67 #define DWCMSHC_EMMC_DLL_INC_VALUE	2
68 #define DWCMSHC_EMMC_DLL_INC		8
69 #define DWCMSHC_EMMC_DLL_BYPASS		BIT(24)
70 #define DWCMSHC_EMMC_DLL_DLYENA		BIT(27)
71 #define DLL_TXCLK_TAPNUM_DEFAULT	0x10
72 #define DLL_TXCLK_TAPNUM_90_DEGREES	0x9
73 #define DLL_STRBIN_TAPNUM_DEFAULT	0x4
74 #define DLL_STRBIN_DELAY_NUM_OFFSET	16
75 #define DLL_STRBIN_TAPNUM_FROM_SW	BIT(24)
76 #define DLL_STRBIN_DELAY_NUM_SEL	BIT(26)
77 #define DLL_TXCLK_TAPNUM_FROM_SW	BIT(24)
78 #define DLL_TXCLK_NO_INVERTER		BIT(29)
79 #define DWCMSHC_EMMC_DLL_LOCKED		BIT(8)
80 #define DWCMSHC_EMMC_DLL_TIMEOUT	BIT(9)
81 
82 #define DLL_RXCLK_TAPNUM_FROM_SW	BIT(24)
83 #define DLL_RXCLK_NO_INVERTER		BIT(29)
84 #define DLL_RXCLK_ORI_GATE		BIT(31)
85 #define DLL_RXCLK_MAX_TAP		32
86 
87 #define DLL_CMDOUT_TAPNUM_90_DEGREES	0x8
88 #define DLL_CMDOUT_TAPNUM_FROM_SW	BIT(24)
89 #define DLL_CMDOUT_SRC_CLK_NEG		BIT(28)
90 #define DLL_CMDOUT_EN_SRC_CLK_NEG	BIT(29)
91 #define DLL_CMDOUT_BOTH_CLK_EDGE	BIT(30)
92 
93 #define DWCMSHC_ENHANCED_STROBE		BIT(8)
94 #define DLL_LOCK_WO_TMOUT(x) \
95 	((((x) & DWCMSHC_EMMC_DLL_LOCKED) == DWCMSHC_EMMC_DLL_LOCKED) && \
96 	(((x) & DWCMSHC_EMMC_DLL_TIMEOUT) == 0))
97 #define ROCKCHIP_MAX_CLKS		3
98 
99 struct rockchip_sdhc_plat {
100 #if CONFIG_IS_ENABLED(OF_PLATDATA)
101 	struct dtd_rockchip_rk3399_sdhci_5_1 dtplat;
102 #endif
103 	struct mmc_config cfg;
104 	struct mmc mmc;
105 };
106 
107 struct rockchip_emmc_phy {
108 	u32 emmcphy_con[7];
109 	u32 reserved;
110 	u32 emmcphy_status;
111 };
112 
113 struct rockchip_sdhc {
114 	struct sdhci_host host;
115 	struct udevice *dev;
116 	void *base;
117 	struct rockchip_emmc_phy *phy;
118 	struct clk emmc_clk;
119 	u8 hs200_rx_tap;
120 };
121 
122 struct sdhci_data {
123 	int (*emmc_set_clock)(struct sdhci_host *host, unsigned int clock);
124 	void (*set_ios_post)(struct sdhci_host *host);
125 	int (*set_enhanced_strobe)(struct sdhci_host *host);
126 	int (*get_phy)(struct udevice *dev);
127 	u32 flags;
128 #define RK_DLL_CMD_OUT		BIT(1)
129 #define RK_RXCLK_NO_INVERTER	BIT(2)
130 #define RK_RXCLK_SW_TUNING	BIT(3)
131 
132 	u8 hs200_tx_tap;
133 	u8 hs400_tx_tap;
134 	u8 hs400_cmd_tap;
135 	u8 hs400_strbin_tap;
136 	u8 ddr50_strbin_delay_num;
137 };
138 
139 static void rk3399_emmc_phy_power_on(struct rockchip_emmc_phy *phy, u32 clock)
140 {
141 	u32 caldone, dllrdy, freqsel;
142 	uint start;
143 
144 	writel(RK_CLRSETBITS(7 << 4, 0), &phy->emmcphy_con[6]);
145 	writel(RK_CLRSETBITS(1 << 11, 1 << 11), &phy->emmcphy_con[0]);
146 	writel(RK_CLRSETBITS(0xf << 7, 6 << 7), &phy->emmcphy_con[0]);
147 
148 	/*
149 	 * According to the user manual, calpad calibration
150 	 * cycle takes more than 2us without the minimal recommended
151 	 * value, so we may need a little margin here
152 	 */
153 	udelay(3);
154 	writel(RK_CLRSETBITS(1, 1), &phy->emmcphy_con[6]);
155 
156 	/*
157 	 * According to the user manual, it asks driver to
158 	 * wait 5us for calpad busy trimming. But it seems that
159 	 * 5us of caldone isn't enough for all cases.
160 	 */
161 	udelay(500);
162 	caldone = readl(&phy->emmcphy_status);
163 	caldone = (caldone >> PHYCTRL_CALDONE_SHIFT) & PHYCTRL_CALDONE_MASK;
164 	if (caldone != PHYCTRL_CALDONE_DONE) {
165 		printf("%s: caldone timeout.\n", __func__);
166 		return;
167 	}
168 
169 	/* Set the frequency of the DLL operation */
170 	if (clock < 75 * MHz)
171 		freqsel = PHYCTRL_FREQSEL_50M;
172 	else if (clock < 125 * MHz)
173 		freqsel = PHYCTRL_FREQSEL_100M;
174 	else if (clock < 175 * MHz)
175 		freqsel = PHYCTRL_FREQSEL_150M;
176 	else
177 		freqsel = PHYCTRL_FREQSEL_200M;
178 
179 	/* Set the frequency of the DLL operation */
180 	writel(RK_CLRSETBITS(3 << 12, freqsel << 12), &phy->emmcphy_con[0]);
181 	writel(RK_CLRSETBITS(1 << 1, 1 << 1), &phy->emmcphy_con[6]);
182 
183 	/* REN Enable on STRB Line for HS400 */
184 	writel(RK_CLRSETBITS(0, 1 << 9), &phy->emmcphy_con[2]);
185 
186 	start = get_timer(0);
187 
188 	do {
189 		udelay(1);
190 		dllrdy = readl(&phy->emmcphy_status);
191 		dllrdy = (dllrdy >> PHYCTRL_DLLRDY_SHIFT) & PHYCTRL_DLLRDY_MASK;
192 		if (dllrdy == PHYCTRL_DLLRDY_DONE)
193 			break;
194 	} while (get_timer(start) < 50000);
195 
196 	if (dllrdy != PHYCTRL_DLLRDY_DONE)
197 		printf("%s: dllrdy timeout.\n", __func__);
198 }
199 
200 static void rk3399_emmc_phy_power_off(struct rockchip_emmc_phy *phy)
201 {
202 	writel(RK_CLRSETBITS(1, 0), &phy->emmcphy_con[6]);
203 	writel(RK_CLRSETBITS(1 << 1, 0), &phy->emmcphy_con[6]);
204 }
205 
206 static int rockchip_emmc_set_clock(struct sdhci_host *host, unsigned int clock)
207 {
208 	unsigned int div, clk = 0, timeout;
209 	unsigned int input_clk;
210 	struct rockchip_sdhc *priv =
211 			container_of(host, struct rockchip_sdhc, host);
212 
213 	/* Wait max 20 ms */
214 	timeout = 200;
215 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) &
216 			   (SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT)) {
217 		if (timeout == 0) {
218 			printf("%s: Timeout to wait cmd & data inhibit\n",
219 			       __func__);
220 			return -EBUSY;
221 		}
222 
223 		timeout--;
224 		udelay(100);
225 	}
226 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
227 
228 	if (clock == 0)
229 		return 0;
230 
231 	input_clk = clk_set_rate(&priv->emmc_clk, clock);
232 	if (IS_ERR_VALUE(input_clk))
233 		input_clk = host->max_clk;
234 
235 	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
236 		/*
237 		 * Check if the Host Controller supports Programmable Clock
238 		 * Mode.
239 		 */
240 		if (host->clk_mul) {
241 			for (div = 1; div <= 1024; div++) {
242 				if ((input_clk / div) <= clock)
243 					break;
244 			}
245 
246 			/*
247 			 * Set Programmable Clock Mode in the Clock
248 			 * Control register.
249 			 */
250 			clk = SDHCI_PROG_CLOCK_MODE;
251 			div--;
252 		} else {
253 			/* Version 3.00 divisors must be a multiple of 2. */
254 			if (input_clk <= clock) {
255 				div = 1;
256 			} else {
257 				for (div = 2;
258 				     div < SDHCI_MAX_DIV_SPEC_300;
259 				     div += 2) {
260 					if ((input_clk / div) <= clock)
261 						break;
262 				}
263 			}
264 			div >>= 1;
265 		}
266 	} else {
267 		/* Version 2.00 divisors must be a power of 2. */
268 		for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) {
269 			if ((input_clk / div) <= clock)
270 				break;
271 		}
272 		div >>= 1;
273 	}
274 
275 	clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
276 	clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
277 		<< SDHCI_DIVIDER_HI_SHIFT;
278 	clk |= SDHCI_CLOCK_INT_EN;
279 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
280 
281 	/* Wait max 20 ms */
282 	timeout = 20;
283 	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
284 		& SDHCI_CLOCK_INT_STABLE)) {
285 		if (timeout == 0) {
286 			printf("%s: Internal clock never stabilised.\n",
287 			       __func__);
288 			return -EBUSY;
289 		}
290 		timeout--;
291 		udelay(1000);
292 	}
293 	clk |= SDHCI_CLOCK_CARD_EN;
294 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
295 	host->clock = clock;
296 
297 	return 0;
298 }
299 
300 static int rk3399_emmc_get_phy(struct udevice *dev)
301 {
302 	struct rockchip_sdhc *priv = dev_get_priv(dev);
303 
304 #if CONFIG_IS_ENABLED(OF_PLATDATA)
305 	priv->phy = (struct rockchip_emmc_phy *)0xff77f780;
306 #else
307 	ofnode phy_node;
308 	void *grf_base;
309 	u32 grf_phy_offset, phandle;
310 
311 	phandle = dev_read_u32_default(dev, "phys", 0);
312 	phy_node = ofnode_get_by_phandle(phandle);
313 	if (!ofnode_valid(phy_node)) {
314 		debug("Not found emmc phy device\n");
315 		return -ENODEV;
316 	}
317 
318 	grf_base = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
319 	if (IS_ERR(grf_base))
320 		printf("%s Get syscon grf failed", __func__);
321 	grf_phy_offset = ofnode_read_u32_default(phy_node, "reg", 0);
322 
323 	priv->phy = (struct rockchip_emmc_phy *)(grf_base + grf_phy_offset);
324 #endif
325 	return 0;
326 }
327 
328 static int rk3399_sdhci_emmc_set_clock(struct sdhci_host *host, unsigned int clock)
329 {
330 	struct rockchip_sdhc *priv =
331 			container_of(host, struct rockchip_sdhc, host);
332 	int cycle_phy = host->clock != clock &&
333 			clock > EMMC_MIN_FREQ;
334 
335 	if (cycle_phy)
336 		rk3399_emmc_phy_power_off(priv->phy);
337 
338 	rockchip_emmc_set_clock(host, clock);
339 
340 	if (cycle_phy)
341 		rk3399_emmc_phy_power_on(priv->phy, clock);
342 
343 	return 0;
344 }
345 
346 static int dwcmshc_sdhci_emmc_set_clock(struct sdhci_host *host, unsigned int clock)
347 {
348 	struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
349 	struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
350 	u32 txclk_tapnum, extra, rxclk_tapnum;
351 	u16 clock_control;
352 	int timeout = 500, ret;
353 
354 	ret = rockchip_emmc_set_clock(host, clock);
355 
356 	/* Disable output clock while config DLL */
357 	clock_control = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
358 	clock_control &= ~SDHCI_CLOCK_CARD_EN;
359 	sdhci_writew(host, clock_control, SDHCI_CLOCK_CONTROL);
360 
361 	if (clock >= 100 * MHz) {
362 		/* reset DLL */
363 		sdhci_writel(host, DWCMSHC_EMMC_DLL_CTRL_RESET, DWCMSHC_EMMC_DLL_CTRL);
364 		udelay(1);
365 		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL);
366 
367 		extra = 0x1 << 16 | /* tune clock stop en */
368 			0x2 << 17 | /* pre-change delay */
369 			0x3 << 19;  /* post-change delay */
370 		sdhci_writel(host, extra, DWCMSHC_EMMC_ATCTRL);
371 
372 		/* Init DLL settings */
373 		extra = DWCMSHC_EMMC_DLL_START_DEFAULT << DWCMSHC_EMMC_DLL_START_POINT |
374 			DWCMSHC_EMMC_DLL_INC_VALUE << DWCMSHC_EMMC_DLL_INC |
375 			DWCMSHC_EMMC_DLL_START;
376 		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_CTRL);
377 
378 		while (1) {
379 			if (timeout < 0) {
380 				ret = -ETIMEDOUT;
381 				goto exit;
382 			}
383 			if (DLL_LOCK_WO_TMOUT((sdhci_readl(host, DWCMSHC_EMMC_DLL_STATUS0))))
384 				break;
385 			udelay(1);
386 			timeout--;
387 		}
388 
389 		rxclk_tapnum = priv->hs200_rx_tap;
390 		if ((data->flags & RK_RXCLK_NO_INVERTER) &&
391 		    host->mmc->timing == MMC_TIMING_MMC_HS400) {
392 			extra = data->hs200_tx_tap - data->hs400_tx_tap;
393 			if (rxclk_tapnum + extra < DLL_RXCLK_MAX_TAP)
394 				rxclk_tapnum += extra;
395 		}
396 		extra = DWCMSHC_EMMC_DLL_DLYENA | DLL_RXCLK_ORI_GATE;
397 		if (data->flags & RK_RXCLK_NO_INVERTER)
398 			extra |= DLL_RXCLK_NO_INVERTER;
399 		if (data->flags & RK_RXCLK_SW_TUNING && priv->hs200_rx_tap)
400 			extra |= DLL_RXCLK_TAPNUM_FROM_SW | rxclk_tapnum;
401 		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK);
402 
403 		txclk_tapnum = data->hs200_tx_tap;
404 		if ((data->flags & RK_DLL_CMD_OUT) &&
405 		    (host->mmc->timing == MMC_TIMING_MMC_HS400 ||
406 		    host->mmc->timing == MMC_TIMING_MMC_HS400ES)) {
407 			txclk_tapnum = data->hs400_tx_tap;
408 
409 			extra = DLL_CMDOUT_SRC_CLK_NEG |
410 				DLL_CMDOUT_BOTH_CLK_EDGE |
411 				DWCMSHC_EMMC_DLL_DLYENA |
412 				data->hs400_cmd_tap |
413 				DLL_CMDOUT_TAPNUM_FROM_SW;
414 			sdhci_writel(host, extra, DECMSHC_EMMC_DLL_CMDOUT);
415 		}
416 
417 		extra = DWCMSHC_EMMC_DLL_DLYENA |
418 			DLL_TXCLK_TAPNUM_FROM_SW |
419 			DLL_TXCLK_NO_INVERTER|
420 			txclk_tapnum;
421 		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_TXCLK);
422 
423 		extra = DWCMSHC_EMMC_DLL_DLYENA |
424 			data->hs400_strbin_tap |
425 			DLL_STRBIN_TAPNUM_FROM_SW;
426 		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN);
427 	} else {
428 		/* Disable cmd conflict check */
429 		extra = sdhci_readl(host, DWCMSHC_HOST_CTRL3);
430 		extra &= ~BIT(0);
431 		sdhci_writel(host, extra, DWCMSHC_HOST_CTRL3);
432 
433 		/* reset the clock phase when the frequency is lower than 100MHz */
434 		sdhci_writel(host, DWCMSHC_EMMC_DLL_BYPASS | DWCMSHC_EMMC_DLL_START, DWCMSHC_EMMC_DLL_CTRL);
435 		sdhci_writel(host, DLL_RXCLK_ORI_GATE, DWCMSHC_EMMC_DLL_RXCLK);
436 		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK);
437 		sdhci_writel(host, 0, DECMSHC_EMMC_DLL_CMDOUT);
438 		/*
439 		 * Before switching to hs400es mode, the driver will enable
440 		 * enhanced strobe first. PHY needs to configure the parameters
441 		 * of enhanced strobe first.
442 		 */
443 		extra = DWCMSHC_EMMC_DLL_DLYENA |
444 			DLL_STRBIN_DELAY_NUM_SEL |
445 			data->ddr50_strbin_delay_num << DLL_STRBIN_DELAY_NUM_OFFSET;
446 		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN);
447 	}
448 
449 exit:
450 	/* enable output clock */
451 	clock_control = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
452 	clock_control |= SDHCI_CLOCK_CARD_EN;
453 	sdhci_writew(host, clock_control, SDHCI_CLOCK_CONTROL);
454 
455 	return ret;
456 }
457 
458 static int dwcmshc_sdhci_set_enhanced_strobe(struct sdhci_host *host)
459 {
460 	struct mmc *mmc = host->mmc;
461 	u32 vendor;
462 
463 	vendor = sdhci_readl(host, DWCMSHC_EMMC_CONTROL);
464 	if (mmc->timing == MMC_TIMING_MMC_HS400ES)
465 		vendor |= DWCMSHC_ENHANCED_STROBE;
466 	else
467 		vendor &= ~DWCMSHC_ENHANCED_STROBE;
468 	sdhci_writel(host, vendor, DWCMSHC_EMMC_CONTROL);
469 
470 	/* some emmc device need a delay before send command */
471 	udelay(100);
472 
473 	return 0;
474 }
475 
476 static void dwcmshc_sdhci_execute_tuning_end(struct sdhci_host *host)
477 {
478 	struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
479 	int rx_delay, dll_lock_num;
480 	u32 extra;
481 	u16 ctrl;
482 
483 	rx_delay = (sdhci_readl(host, DWCMSHC_EMMC_DLL_STATUS1) >> 8) & 0xFF;
484 	dll_lock_num = sdhci_readl(host, DWCMSHC_EMMC_DLL_STATUS0) & 0xFF;
485 
486 	/* reset tuning */
487 	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
488 	ctrl &= ~SDHCI_CTRL_TUNED_CLK;
489 	ctrl &= ~SDHCI_CTRL_EXEC_TUNING;
490 	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
491 
492 	priv->hs200_rx_tap = rx_delay * 16 / dll_lock_num;
493 	extra = sdhci_readl(host, DWCMSHC_EMMC_DLL_RXCLK);
494 	extra &= DLL_RXCLK_NO_INVERTER;
495 	extra |= DWCMSHC_EMMC_DLL_DLYENA | DLL_RXCLK_ORI_GATE |
496 		 DLL_RXCLK_TAPNUM_FROM_SW | priv->hs200_rx_tap;
497 	sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK);
498 }
499 
500 static void dwcmshc_sdhci_set_ios_post(struct sdhci_host *host)
501 {
502 	u16 ctrl;
503 	u32 timing = host->mmc->timing;
504 
505 	if (timing == MMC_TIMING_MMC_HS400 || timing == MMC_TIMING_MMC_HS400ES) {
506 		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
507 		ctrl &= ~SDHCI_CTRL_UHS_MASK;
508 		ctrl |= DWCMSHC_CTRL_HS400;
509 		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
510 
511 		/* set CARD_IS_EMMC bit to enable Data Strobe for HS400 */
512 		ctrl = sdhci_readw(host, DWCMSHC_EMMC_CONTROL);
513 		ctrl |= DWCMSHC_CARD_IS_EMMC;
514 		sdhci_writew(host, ctrl, DWCMSHC_EMMC_CONTROL);
515 	}
516 }
517 
518 static int dwcmshc_emmc_get_phy(struct udevice *dev)
519 {
520 	return 0;
521 }
522 
523 static int rockchip_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
524 {
525 	struct rockchip_sdhc *priv =
526 			container_of(host, struct rockchip_sdhc, host);
527 	struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
528 	if (!data)
529 		return -EINVAL;
530 
531 	return data->emmc_set_clock(host, clock);
532 }
533 
534 static void rockchip_sdhci_set_ios_post(struct sdhci_host *host)
535 {
536 	struct rockchip_sdhc *priv =
537 			container_of(host, struct rockchip_sdhc, host);
538 	struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
539 
540 	if (data && data->set_ios_post)
541 		data->set_ios_post(host);
542 }
543 
544 static int rockchip_sdhci_set_enhanced_strobe(struct sdhci_host *host)
545 {
546 	struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
547 	struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
548 
549 	if (data->set_enhanced_strobe)
550 		return data->set_enhanced_strobe(host);
551 
552 	return -ENOTSUPP;
553 }
554 
555 static struct sdhci_ops rockchip_sdhci_ops = {
556 	.set_clock	= rockchip_sdhci_set_clock,
557 	.set_ios_post	= rockchip_sdhci_set_ios_post,
558 	.set_enhanced_strobe = rockchip_sdhci_set_enhanced_strobe,
559 };
560 
561 static int rockchip_sdhci_probe(struct udevice *dev)
562 {
563 	struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(dev);
564 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
565 	struct rockchip_sdhc_plat *plat = dev_get_platdata(dev);
566 	struct rockchip_sdhc *prv = dev_get_priv(dev);
567 	struct sdhci_host *host = &prv->host;
568 	int max_frequency, ret;
569 	struct clk clk;
570 
571 #if CONFIG_IS_ENABLED(OF_PLATDATA)
572 	struct dtd_rockchip_rk3399_sdhci_5_1 *dtplat = &plat->dtplat;
573 
574 	host->name = dev->name;
575 	host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
576 	host->host_caps |= MMC_MODE_8BIT;
577 	max_frequency = dtplat->max_frequency;
578 	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk);
579 #else
580 	max_frequency = dev_read_u32_default(dev, "max-frequency", 0);
581 	switch (dev_read_u32_default(dev, "bus-width", 4)) {
582 	case 8:
583 		host->host_caps |= MMC_MODE_8BIT;
584 		break;
585 	case 4:
586 		host->host_caps |= MMC_MODE_4BIT;
587 		break;
588 	case 1:
589 		break;
590 	default:
591 		printf("Invalid \"bus-width\" value\n");
592 		return -EINVAL;
593 	}
594 	ret = clk_get_by_index(dev, 0, &clk);
595 #endif
596 	if (!ret) {
597 		ret = clk_set_rate(&clk, max_frequency);
598 		if (IS_ERR_VALUE(ret))
599 			printf("%s clk set rate fail!\n", __func__);
600 	} else {
601 		printf("%s fail to get clk\n", __func__);
602 	}
603 
604 	prv->emmc_clk = clk;
605 	prv->dev = dev;
606 	ret = data->get_phy(dev);
607 	if (ret)
608 		return ret;
609 
610 	host->ops = &rockchip_sdhci_ops;
611 
612 	host->max_clk = max_frequency;
613 
614 	if (dev_read_bool(dev, "mmc-hs200-1_8v"))
615 		host->host_caps |= MMC_MODE_HS200;
616 	else if (dev_read_bool(dev, "mmc-hs400-1_8v"))
617 		host->host_caps |= MMC_MODE_HS400;
618 
619 	if (data->flags && RK_RXCLK_SW_TUNING)
620 		rockchip_sdhci_ops.execute_tuning_end = dwcmshc_sdhci_execute_tuning_end;
621 
622 	if (data->set_enhanced_strobe && dev_read_bool(dev, "mmc-hs400-enhanced-strobe"))
623 		host->host_caps |= MMC_MODE_HS400ES;
624 
625 	ret = sdhci_setup_cfg(&plat->cfg, host, 0, EMMC_MIN_FREQ);
626 
627 	plat->cfg.fixed_drv_type = dev_read_u32_default(dev, "fixed-emmc-driver-type", 0);
628 
629 	host->mmc = &plat->mmc;
630 	if (ret)
631 		return ret;
632 	host->mmc->priv = &prv->host;
633 	host->mmc->dev = dev;
634 	upriv->mmc = host->mmc;
635 
636 	return sdhci_probe(dev);
637 }
638 
639 static int rockchip_sdhci_of_to_plat(struct udevice *dev)
640 {
641 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
642 	struct sdhci_host *host = dev_get_priv(dev);
643 
644 	host->name = dev->name;
645 	host->ioaddr = dev_read_addr_ptr(dev);
646 #endif
647 
648 	return 0;
649 }
650 
651 static int rockchip_sdhci_bind(struct udevice *dev)
652 {
653 	struct rockchip_sdhc_plat *plat = dev_get_platdata(dev);
654 
655 	return sdhci_bind(dev, &plat->mmc, &plat->cfg);
656 }
657 
658 static const struct sdhci_data arasan_data = {
659 	.emmc_set_clock = rk3399_sdhci_emmc_set_clock,
660 	.get_phy = rk3399_emmc_get_phy,
661 };
662 
663 static const struct sdhci_data rk3568_data = {
664 	.emmc_set_clock = dwcmshc_sdhci_emmc_set_clock,
665 	.get_phy = dwcmshc_emmc_get_phy,
666 	.flags = RK_RXCLK_NO_INVERTER,
667 	.hs200_tx_tap = 16,
668 	.hs400_tx_tap = 8,
669 	.hs400_cmd_tap = 8,
670 	.hs400_strbin_tap = 3,
671 	.ddr50_strbin_delay_num = 16,
672 };
673 
674 static const struct sdhci_data rk3588_data = {
675 	.emmc_set_clock = dwcmshc_sdhci_emmc_set_clock,
676 	.get_phy = dwcmshc_emmc_get_phy,
677 	.set_ios_post = dwcmshc_sdhci_set_ios_post,
678 	.set_enhanced_strobe = dwcmshc_sdhci_set_enhanced_strobe,
679 	.flags = RK_DLL_CMD_OUT,
680 	.hs200_tx_tap = 16,
681 	.hs400_tx_tap = 9,
682 	.hs400_cmd_tap = 8,
683 	.hs400_strbin_tap = 3,
684 	.ddr50_strbin_delay_num = 16,
685 };
686 
687 static const struct sdhci_data rk3528_data = {
688 	.emmc_set_clock = dwcmshc_sdhci_emmc_set_clock,
689 	.get_phy = dwcmshc_emmc_get_phy,
690 	.set_ios_post = dwcmshc_sdhci_set_ios_post,
691 	.set_enhanced_strobe = dwcmshc_sdhci_set_enhanced_strobe,
692 	.flags = RK_DLL_CMD_OUT | RK_RXCLK_NO_INVERTER | RK_RXCLK_SW_TUNING,
693 	.hs200_tx_tap = 12,
694 	.hs400_tx_tap = 6,
695 	.hs400_cmd_tap = 6,
696 	.hs400_strbin_tap = 3,
697 	.ddr50_strbin_delay_num = 10,
698 };
699 
700 static const struct udevice_id sdhci_ids[] = {
701 	{
702 		.compatible = "arasan,sdhci-5.1",
703 		.data = (ulong)&arasan_data,
704 	},
705 	{
706 		.compatible = "snps,dwcmshc-sdhci",
707 		.data = (ulong)&rk3568_data,
708 	},
709 	{
710 		.compatible = "rockchip,rk3528-dwcmshc",
711 		.data = (ulong)&rk3528_data,
712 	},
713 	{
714 		.compatible = "rockchip,rk3588-dwcmshc",
715 		.data = (ulong)&rk3588_data,
716 	},
717 	{ }
718 };
719 
720 U_BOOT_DRIVER(arasan_sdhci_drv) = {
721 	.name		= "rockchip_sdhci_5_1",
722 	.id		= UCLASS_MMC,
723 	.of_match	= sdhci_ids,
724 	.ofdata_to_platdata = rockchip_sdhci_of_to_plat,
725 	.ops		= &sdhci_ops,
726 	.bind		= rockchip_sdhci_bind,
727 	.probe		= rockchip_sdhci_probe,
728 	.priv_auto_alloc_size = sizeof(struct rockchip_sdhc),
729 	.platdata_auto_alloc_size = sizeof(struct rockchip_sdhc_plat),
730 };
731