xref: /rk3399_rockchip-uboot/drivers/mmc/rockchip_sdhci.c (revision 59b2bce9b7f26ba45a588a67a1a03ea44b694376)
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 	int timeout = 500, ret;
352 
353 	ret = rockchip_emmc_set_clock(host, clock);
354 
355 	if (clock >= 100 * MHz) {
356 		/* reset DLL */
357 		sdhci_writel(host, DWCMSHC_EMMC_DLL_CTRL_RESET, DWCMSHC_EMMC_DLL_CTRL);
358 		udelay(1);
359 		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL);
360 
361 		extra = 0x1 << 16 | /* tune clock stop en */
362 			0x2 << 17 | /* pre-change delay */
363 			0x3 << 19;  /* post-change delay */
364 		sdhci_writel(host, extra, DWCMSHC_EMMC_ATCTRL);
365 
366 		/* Init DLL settings */
367 		extra = DWCMSHC_EMMC_DLL_START_DEFAULT << DWCMSHC_EMMC_DLL_START_POINT |
368 			DWCMSHC_EMMC_DLL_INC_VALUE << DWCMSHC_EMMC_DLL_INC |
369 			DWCMSHC_EMMC_DLL_START;
370 		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_CTRL);
371 
372 		while (1) {
373 			if (timeout < 0)
374 				return -ETIMEDOUT;
375 			if (DLL_LOCK_WO_TMOUT((sdhci_readl(host, DWCMSHC_EMMC_DLL_STATUS0))))
376 				break;
377 			udelay(1);
378 			timeout--;
379 		}
380 
381 		rxclk_tapnum = priv->hs200_rx_tap;
382 		if ((data->flags & RK_RXCLK_NO_INVERTER) &&
383 		    host->mmc->timing == MMC_TIMING_MMC_HS400) {
384 			extra = data->hs200_tx_tap - data->hs400_tx_tap;
385 			if (rxclk_tapnum + extra < DLL_RXCLK_MAX_TAP)
386 				rxclk_tapnum += extra;
387 		}
388 		extra = DWCMSHC_EMMC_DLL_DLYENA | DLL_RXCLK_ORI_GATE;
389 		if (data->flags & RK_RXCLK_NO_INVERTER)
390 			extra |= DLL_RXCLK_NO_INVERTER;
391 		if (data->flags & RK_RXCLK_SW_TUNING && priv->hs200_rx_tap)
392 			extra |= DLL_RXCLK_TAPNUM_FROM_SW | rxclk_tapnum;
393 		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK);
394 
395 		txclk_tapnum = data->hs200_tx_tap;
396 		if ((data->flags & RK_DLL_CMD_OUT) &&
397 		    (host->mmc->timing == MMC_TIMING_MMC_HS400 ||
398 		    host->mmc->timing == MMC_TIMING_MMC_HS400ES)) {
399 			txclk_tapnum = data->hs400_tx_tap;
400 
401 			extra = DLL_CMDOUT_SRC_CLK_NEG |
402 				DLL_CMDOUT_BOTH_CLK_EDGE |
403 				DWCMSHC_EMMC_DLL_DLYENA |
404 				data->hs400_cmd_tap |
405 				DLL_CMDOUT_TAPNUM_FROM_SW;
406 			sdhci_writel(host, extra, DECMSHC_EMMC_DLL_CMDOUT);
407 		}
408 
409 		extra = DWCMSHC_EMMC_DLL_DLYENA |
410 			DLL_TXCLK_TAPNUM_FROM_SW |
411 			DLL_TXCLK_NO_INVERTER|
412 			txclk_tapnum;
413 		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_TXCLK);
414 
415 		extra = DWCMSHC_EMMC_DLL_DLYENA |
416 			data->hs400_strbin_tap |
417 			DLL_STRBIN_TAPNUM_FROM_SW;
418 		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN);
419 	} else {
420 		/* Disable cmd conflict check */
421 		extra = sdhci_readl(host, DWCMSHC_HOST_CTRL3);
422 		extra &= ~BIT(0);
423 		sdhci_writel(host, extra, DWCMSHC_HOST_CTRL3);
424 
425 		/* reset the clock phase when the frequency is lower than 100MHz */
426 		sdhci_writel(host, DWCMSHC_EMMC_DLL_BYPASS | DWCMSHC_EMMC_DLL_START, DWCMSHC_EMMC_DLL_CTRL);
427 		sdhci_writel(host, DLL_RXCLK_ORI_GATE, DWCMSHC_EMMC_DLL_RXCLK);
428 		sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK);
429 		sdhci_writel(host, 0, DECMSHC_EMMC_DLL_CMDOUT);
430 		/*
431 		 * Before switching to hs400es mode, the driver will enable
432 		 * enhanced strobe first. PHY needs to configure the parameters
433 		 * of enhanced strobe first.
434 		 */
435 		extra = DWCMSHC_EMMC_DLL_DLYENA |
436 			DLL_STRBIN_DELAY_NUM_SEL |
437 			data->ddr50_strbin_delay_num << DLL_STRBIN_DELAY_NUM_OFFSET;
438 		sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN);
439 	}
440 
441 	return ret;
442 }
443 
444 static int dwcmshc_sdhci_set_enhanced_strobe(struct sdhci_host *host)
445 {
446 	struct mmc *mmc = host->mmc;
447 	u32 vendor;
448 
449 	vendor = sdhci_readl(host, DWCMSHC_EMMC_CONTROL);
450 	if (mmc->timing == MMC_TIMING_MMC_HS400ES)
451 		vendor |= DWCMSHC_ENHANCED_STROBE;
452 	else
453 		vendor &= ~DWCMSHC_ENHANCED_STROBE;
454 	sdhci_writel(host, vendor, DWCMSHC_EMMC_CONTROL);
455 
456 	return 0;
457 }
458 
459 static void dwcmshc_sdhci_execute_tuning_end(struct sdhci_host *host)
460 {
461 	struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
462 	int rx_delay, dll_lock_num;
463 	u32 extra;
464 	u16 ctrl;
465 
466 	rx_delay = (sdhci_readl(host, DWCMSHC_EMMC_DLL_STATUS1) >> 8) & 0xFF;
467 	dll_lock_num = sdhci_readl(host, DWCMSHC_EMMC_DLL_STATUS0) & 0xFF;
468 
469 	/* reset tuning */
470 	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
471 	ctrl &= ~SDHCI_CTRL_TUNED_CLK;
472 	ctrl &= ~SDHCI_CTRL_EXEC_TUNING;
473 	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
474 
475 	priv->hs200_rx_tap = rx_delay * 16 / dll_lock_num;
476 	extra = sdhci_readl(host, DWCMSHC_EMMC_DLL_RXCLK);
477 	extra &= DLL_RXCLK_NO_INVERTER;
478 	extra |= DWCMSHC_EMMC_DLL_DLYENA | DLL_RXCLK_ORI_GATE |
479 		 DLL_RXCLK_TAPNUM_FROM_SW | priv->hs200_rx_tap;
480 	sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK);
481 }
482 
483 static void dwcmshc_sdhci_set_ios_post(struct sdhci_host *host)
484 {
485 	u16 ctrl;
486 	u32 timing = host->mmc->timing;
487 
488 	if (timing == MMC_TIMING_MMC_HS400 || timing == MMC_TIMING_MMC_HS400ES) {
489 		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
490 		ctrl &= ~SDHCI_CTRL_UHS_MASK;
491 		ctrl |= DWCMSHC_CTRL_HS400;
492 		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
493 
494 		/* set CARD_IS_EMMC bit to enable Data Strobe for HS400 */
495 		ctrl = sdhci_readw(host, DWCMSHC_EMMC_CONTROL);
496 		ctrl |= DWCMSHC_CARD_IS_EMMC;
497 		sdhci_writew(host, ctrl, DWCMSHC_EMMC_CONTROL);
498 	}
499 }
500 
501 static int dwcmshc_emmc_get_phy(struct udevice *dev)
502 {
503 	return 0;
504 }
505 
506 static int rockchip_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
507 {
508 	struct rockchip_sdhc *priv =
509 			container_of(host, struct rockchip_sdhc, host);
510 	struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
511 	if (!data)
512 		return -EINVAL;
513 
514 	return data->emmc_set_clock(host, clock);
515 }
516 
517 static void rockchip_sdhci_set_ios_post(struct sdhci_host *host)
518 {
519 	struct rockchip_sdhc *priv =
520 			container_of(host, struct rockchip_sdhc, host);
521 	struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
522 
523 	if (data && data->set_ios_post)
524 		data->set_ios_post(host);
525 }
526 
527 static int rockchip_sdhci_set_enhanced_strobe(struct sdhci_host *host)
528 {
529 	struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
530 	struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
531 
532 	if (data->set_enhanced_strobe)
533 		return data->set_enhanced_strobe(host);
534 
535 	return -ENOTSUPP;
536 }
537 
538 static struct sdhci_ops rockchip_sdhci_ops = {
539 	.set_clock	= rockchip_sdhci_set_clock,
540 	.set_ios_post	= rockchip_sdhci_set_ios_post,
541 	.set_enhanced_strobe = rockchip_sdhci_set_enhanced_strobe,
542 };
543 
544 static int rockchip_sdhci_probe(struct udevice *dev)
545 {
546 	struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(dev);
547 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
548 	struct rockchip_sdhc_plat *plat = dev_get_platdata(dev);
549 	struct rockchip_sdhc *prv = dev_get_priv(dev);
550 	struct sdhci_host *host = &prv->host;
551 	int max_frequency, ret;
552 	struct clk clk;
553 
554 #if CONFIG_IS_ENABLED(OF_PLATDATA)
555 	struct dtd_rockchip_rk3399_sdhci_5_1 *dtplat = &plat->dtplat;
556 
557 	host->name = dev->name;
558 	host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
559 	host->host_caps |= MMC_MODE_8BIT;
560 	max_frequency = dtplat->max_frequency;
561 	ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk);
562 #else
563 	max_frequency = dev_read_u32_default(dev, "max-frequency", 0);
564 	switch (dev_read_u32_default(dev, "bus-width", 4)) {
565 	case 8:
566 		host->host_caps |= MMC_MODE_8BIT;
567 		break;
568 	case 4:
569 		host->host_caps |= MMC_MODE_4BIT;
570 		break;
571 	case 1:
572 		break;
573 	default:
574 		printf("Invalid \"bus-width\" value\n");
575 		return -EINVAL;
576 	}
577 	ret = clk_get_by_index(dev, 0, &clk);
578 #endif
579 	if (!ret) {
580 		ret = clk_set_rate(&clk, max_frequency);
581 		if (IS_ERR_VALUE(ret))
582 			printf("%s clk set rate fail!\n", __func__);
583 	} else {
584 		printf("%s fail to get clk\n", __func__);
585 	}
586 
587 	prv->emmc_clk = clk;
588 	prv->dev = dev;
589 	ret = data->get_phy(dev);
590 	if (ret)
591 		return ret;
592 
593 	host->ops = &rockchip_sdhci_ops;
594 
595 	host->max_clk = max_frequency;
596 
597 	if (dev_read_bool(dev, "mmc-hs200-1_8v"))
598 		host->host_caps |= MMC_MODE_HS200;
599 	else if (dev_read_bool(dev, "mmc-hs400-1_8v"))
600 		host->host_caps |= MMC_MODE_HS400;
601 
602 	if (data->flags && RK_RXCLK_SW_TUNING)
603 		rockchip_sdhci_ops.execute_tuning_end = dwcmshc_sdhci_execute_tuning_end;
604 
605 	if (data->set_enhanced_strobe && dev_read_bool(dev, "mmc-hs400-enhanced-strobe"))
606 		host->host_caps |= MMC_MODE_HS400ES;
607 
608 	ret = sdhci_setup_cfg(&plat->cfg, host, 0, EMMC_MIN_FREQ);
609 
610 	plat->cfg.fixed_drv_type = dev_read_u32_default(dev, "fixed-emmc-driver-type", 0);
611 
612 	host->mmc = &plat->mmc;
613 	if (ret)
614 		return ret;
615 	host->mmc->priv = &prv->host;
616 	host->mmc->dev = dev;
617 	upriv->mmc = host->mmc;
618 
619 	return sdhci_probe(dev);
620 }
621 
622 static int rockchip_sdhci_of_to_plat(struct udevice *dev)
623 {
624 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
625 	struct sdhci_host *host = dev_get_priv(dev);
626 
627 	host->name = dev->name;
628 	host->ioaddr = dev_read_addr_ptr(dev);
629 #endif
630 
631 	return 0;
632 }
633 
634 static int rockchip_sdhci_bind(struct udevice *dev)
635 {
636 	struct rockchip_sdhc_plat *plat = dev_get_platdata(dev);
637 
638 	return sdhci_bind(dev, &plat->mmc, &plat->cfg);
639 }
640 
641 static const struct sdhci_data arasan_data = {
642 	.emmc_set_clock = rk3399_sdhci_emmc_set_clock,
643 	.get_phy = rk3399_emmc_get_phy,
644 };
645 
646 static const struct sdhci_data rk3568_data = {
647 	.emmc_set_clock = dwcmshc_sdhci_emmc_set_clock,
648 	.get_phy = dwcmshc_emmc_get_phy,
649 	.flags = RK_RXCLK_NO_INVERTER,
650 	.hs200_tx_tap = 16,
651 	.hs400_tx_tap = 8,
652 	.hs400_cmd_tap = 8,
653 	.hs400_strbin_tap = 3,
654 	.ddr50_strbin_delay_num = 16,
655 };
656 
657 static const struct sdhci_data rk3588_data = {
658 	.emmc_set_clock = dwcmshc_sdhci_emmc_set_clock,
659 	.get_phy = dwcmshc_emmc_get_phy,
660 	.set_ios_post = dwcmshc_sdhci_set_ios_post,
661 	.set_enhanced_strobe = dwcmshc_sdhci_set_enhanced_strobe,
662 	.flags = RK_DLL_CMD_OUT,
663 	.hs200_tx_tap = 16,
664 	.hs400_tx_tap = 9,
665 	.hs400_cmd_tap = 8,
666 	.hs400_strbin_tap = 3,
667 	.ddr50_strbin_delay_num = 16,
668 };
669 
670 static const struct sdhci_data rk3528_data = {
671 	.emmc_set_clock = dwcmshc_sdhci_emmc_set_clock,
672 	.get_phy = dwcmshc_emmc_get_phy,
673 	.set_ios_post = dwcmshc_sdhci_set_ios_post,
674 	.set_enhanced_strobe = dwcmshc_sdhci_set_enhanced_strobe,
675 	.flags = RK_DLL_CMD_OUT | RK_RXCLK_NO_INVERTER | RK_RXCLK_SW_TUNING,
676 	.hs200_tx_tap = 12,
677 	.hs400_tx_tap = 6,
678 	.hs400_cmd_tap = 6,
679 	.hs400_strbin_tap = 3,
680 	.ddr50_strbin_delay_num = 10,
681 };
682 
683 static const struct udevice_id sdhci_ids[] = {
684 	{
685 		.compatible = "arasan,sdhci-5.1",
686 		.data = (ulong)&arasan_data,
687 	},
688 	{
689 		.compatible = "snps,dwcmshc-sdhci",
690 		.data = (ulong)&rk3568_data,
691 	},
692 	{
693 		.compatible = "rockchip,rk3528-dwcmshc",
694 		.data = (ulong)&rk3528_data,
695 	},
696 	{
697 		.compatible = "rockchip,rk3588-dwcmshc",
698 		.data = (ulong)&rk3588_data,
699 	},
700 	{ }
701 };
702 
703 U_BOOT_DRIVER(arasan_sdhci_drv) = {
704 	.name		= "rockchip_sdhci_5_1",
705 	.id		= UCLASS_MMC,
706 	.of_match	= sdhci_ids,
707 	.ofdata_to_platdata = rockchip_sdhci_of_to_plat,
708 	.ops		= &sdhci_ops,
709 	.bind		= rockchip_sdhci_bind,
710 	.probe		= rockchip_sdhci_probe,
711 	.priv_auto_alloc_size = sizeof(struct rockchip_sdhc),
712 	.platdata_auto_alloc_size = sizeof(struct rockchip_sdhc_plat),
713 };
714