xref: /openbmc/linux/drivers/mmc/host/sdhci_am654.c (revision 23514731)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * sdhci_am654.c - SDHCI driver for TI's AM654 SOCs
4  *
5  * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
6  *
7  */
8 #include <linux/clk.h>
9 #include <linux/of.h>
10 #include <linux/module.h>
11 #include <linux/pm_runtime.h>
12 #include <linux/property.h>
13 #include <linux/regmap.h>
14 
15 #include "cqhci.h"
16 #include "sdhci-pltfm.h"
17 
18 /* CTL_CFG Registers */
19 #define CTL_CFG_2		0x14
20 
21 #define SLOTTYPE_MASK		GENMASK(31, 30)
22 #define SLOTTYPE_EMBEDDED	BIT(30)
23 
24 /* PHY Registers */
25 #define PHY_CTRL1	0x100
26 #define PHY_CTRL2	0x104
27 #define PHY_CTRL3	0x108
28 #define PHY_CTRL4	0x10C
29 #define PHY_CTRL5	0x110
30 #define PHY_CTRL6	0x114
31 #define PHY_STAT1	0x130
32 #define PHY_STAT2	0x134
33 
34 #define IOMUX_ENABLE_SHIFT	31
35 #define IOMUX_ENABLE_MASK	BIT(IOMUX_ENABLE_SHIFT)
36 #define OTAPDLYENA_SHIFT	20
37 #define OTAPDLYENA_MASK		BIT(OTAPDLYENA_SHIFT)
38 #define OTAPDLYSEL_SHIFT	12
39 #define OTAPDLYSEL_MASK		GENMASK(15, 12)
40 #define STRBSEL_SHIFT		24
41 #define STRBSEL_4BIT_MASK	GENMASK(27, 24)
42 #define STRBSEL_8BIT_MASK	GENMASK(31, 24)
43 #define SEL50_SHIFT		8
44 #define SEL50_MASK		BIT(SEL50_SHIFT)
45 #define SEL100_SHIFT		9
46 #define SEL100_MASK		BIT(SEL100_SHIFT)
47 #define FREQSEL_SHIFT		8
48 #define FREQSEL_MASK		GENMASK(10, 8)
49 #define DLL_TRIM_ICP_SHIFT	4
50 #define DLL_TRIM_ICP_MASK	GENMASK(7, 4)
51 #define DR_TY_SHIFT		20
52 #define DR_TY_MASK		GENMASK(22, 20)
53 #define ENDLL_SHIFT		1
54 #define ENDLL_MASK		BIT(ENDLL_SHIFT)
55 #define DLLRDY_SHIFT		0
56 #define DLLRDY_MASK		BIT(DLLRDY_SHIFT)
57 #define PDB_SHIFT		0
58 #define PDB_MASK		BIT(PDB_SHIFT)
59 #define CALDONE_SHIFT		1
60 #define CALDONE_MASK		BIT(CALDONE_SHIFT)
61 #define RETRIM_SHIFT		17
62 #define RETRIM_MASK		BIT(RETRIM_SHIFT)
63 
64 #define DRIVER_STRENGTH_50_OHM	0x0
65 #define DRIVER_STRENGTH_33_OHM	0x1
66 #define DRIVER_STRENGTH_66_OHM	0x2
67 #define DRIVER_STRENGTH_100_OHM	0x3
68 #define DRIVER_STRENGTH_40_OHM	0x4
69 
70 #define CLOCK_TOO_SLOW_HZ	400000
71 
72 /* Command Queue Host Controller Interface Base address */
73 #define SDHCI_AM654_CQE_BASE_ADDR 0x200
74 
75 static struct regmap_config sdhci_am654_regmap_config = {
76 	.reg_bits = 32,
77 	.val_bits = 32,
78 	.reg_stride = 4,
79 	.fast_io = true,
80 };
81 
82 struct sdhci_am654_data {
83 	struct regmap *base;
84 	bool legacy_otapdly;
85 	int otap_del_sel[11];
86 	int trm_icp;
87 	int drv_strength;
88 	bool dll_on;
89 	int strb_sel;
90 	u32 flags;
91 };
92 
93 struct sdhci_am654_driver_data {
94 	const struct sdhci_pltfm_data *pdata;
95 	u32 flags;
96 #define IOMUX_PRESENT	(1 << 0)
97 #define FREQSEL_2_BIT	(1 << 1)
98 #define STRBSEL_4_BIT	(1 << 2)
99 #define DLL_PRESENT	(1 << 3)
100 #define DLL_CALIB	(1 << 4)
101 };
102 
103 struct timing_data {
104 	const char *binding;
105 	u32 capability;
106 };
107 
108 static const struct timing_data td[] = {
109 	[MMC_TIMING_LEGACY] = {"ti,otap-del-sel-legacy", 0},
110 	[MMC_TIMING_MMC_HS] = {"ti,otap-del-sel-mmc-hs", MMC_CAP_MMC_HIGHSPEED},
111 	[MMC_TIMING_SD_HS]  = {"ti,otap-del-sel-sd-hs", MMC_CAP_SD_HIGHSPEED},
112 	[MMC_TIMING_UHS_SDR12] = {"ti,otap-del-sel-sdr12", MMC_CAP_UHS_SDR12},
113 	[MMC_TIMING_UHS_SDR25] = {"ti,otap-del-sel-sdr25", MMC_CAP_UHS_SDR25},
114 	[MMC_TIMING_UHS_SDR50] = {"ti,otap-del-sel-sdr50", MMC_CAP_UHS_SDR50},
115 	[MMC_TIMING_UHS_SDR104] = {"ti,otap-del-sel-sdr104",
116 				   MMC_CAP_UHS_SDR104},
117 	[MMC_TIMING_UHS_DDR50] = {"ti,otap-del-sel-ddr50", MMC_CAP_UHS_DDR50},
118 	[MMC_TIMING_MMC_DDR52] = {"ti,otap-del-sel-ddr52", MMC_CAP_DDR},
119 	[MMC_TIMING_MMC_HS200] = {"ti,otap-del-sel-hs200", MMC_CAP2_HS200},
120 	[MMC_TIMING_MMC_HS400] = {"ti,otap-del-sel-hs400", MMC_CAP2_HS400},
121 };
122 
123 static void sdhci_am654_setup_dll(struct sdhci_host *host, unsigned int clock)
124 {
125 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
126 	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
127 	int sel50, sel100, freqsel;
128 	u32 mask, val;
129 	int ret;
130 
131 	if (sdhci_am654->flags & FREQSEL_2_BIT) {
132 		switch (clock) {
133 		case 200000000:
134 			sel50 = 0;
135 			sel100 = 0;
136 			break;
137 		case 100000000:
138 			sel50 = 0;
139 			sel100 = 1;
140 			break;
141 		default:
142 			sel50 = 1;
143 			sel100 = 0;
144 		}
145 
146 		/* Configure PHY DLL frequency */
147 		mask = SEL50_MASK | SEL100_MASK;
148 		val = (sel50 << SEL50_SHIFT) | (sel100 << SEL100_SHIFT);
149 		regmap_update_bits(sdhci_am654->base, PHY_CTRL5, mask, val);
150 
151 	} else {
152 		switch (clock) {
153 		case 200000000:
154 			freqsel = 0x0;
155 			break;
156 		default:
157 			freqsel = 0x4;
158 		}
159 
160 		regmap_update_bits(sdhci_am654->base, PHY_CTRL5, FREQSEL_MASK,
161 				   freqsel << FREQSEL_SHIFT);
162 	}
163 	/* Configure DLL TRIM */
164 	mask = DLL_TRIM_ICP_MASK;
165 	val = sdhci_am654->trm_icp << DLL_TRIM_ICP_SHIFT;
166 
167 	/* Configure DLL driver strength */
168 	mask |= DR_TY_MASK;
169 	val |= sdhci_am654->drv_strength << DR_TY_SHIFT;
170 	regmap_update_bits(sdhci_am654->base, PHY_CTRL1, mask, val);
171 
172 	/* Enable DLL */
173 	regmap_update_bits(sdhci_am654->base, PHY_CTRL1, ENDLL_MASK,
174 			   0x1 << ENDLL_SHIFT);
175 	/*
176 	 * Poll for DLL ready. Use a one second timeout.
177 	 * Works in all experiments done so far
178 	 */
179 	ret = regmap_read_poll_timeout(sdhci_am654->base, PHY_STAT1, val,
180 				       val & DLLRDY_MASK, 1000, 1000000);
181 	if (ret) {
182 		dev_err(mmc_dev(host->mmc), "DLL failed to relock\n");
183 		return;
184 	}
185 
186 	sdhci_am654->dll_on = true;
187 }
188 
189 static void sdhci_am654_set_clock(struct sdhci_host *host, unsigned int clock)
190 {
191 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
192 	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
193 	unsigned char timing = host->mmc->ios.timing;
194 	u32 otap_del_sel;
195 	u32 otap_del_ena;
196 	u32 mask, val;
197 
198 	if (sdhci_am654->dll_on) {
199 		regmap_update_bits(sdhci_am654->base, PHY_CTRL1, ENDLL_MASK, 0);
200 
201 		sdhci_am654->dll_on = false;
202 	}
203 
204 	sdhci_set_clock(host, clock);
205 
206 	if (clock > CLOCK_TOO_SLOW_HZ) {
207 		/* Setup DLL Output TAP delay */
208 		if (sdhci_am654->legacy_otapdly)
209 			otap_del_sel = sdhci_am654->otap_del_sel[0];
210 		else
211 			otap_del_sel = sdhci_am654->otap_del_sel[timing];
212 
213 		otap_del_ena = (timing > MMC_TIMING_UHS_SDR25) ? 1 : 0;
214 
215 		mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
216 		val = (otap_del_ena << OTAPDLYENA_SHIFT) |
217 		      (otap_del_sel << OTAPDLYSEL_SHIFT);
218 
219 		/* Write to STRBSEL for HS400 speed mode */
220 		if (timing == MMC_TIMING_MMC_HS400) {
221 			if (sdhci_am654->flags & STRBSEL_4_BIT)
222 				mask |= STRBSEL_4BIT_MASK;
223 			else
224 				mask |= STRBSEL_8BIT_MASK;
225 
226 			val |= sdhci_am654->strb_sel << STRBSEL_SHIFT;
227 		}
228 
229 		regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val);
230 
231 		if (timing > MMC_TIMING_UHS_SDR25)
232 			sdhci_am654_setup_dll(host, clock);
233 	}
234 }
235 
236 static void sdhci_j721e_4bit_set_clock(struct sdhci_host *host,
237 				       unsigned int clock)
238 {
239 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
240 	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
241 	unsigned char timing = host->mmc->ios.timing;
242 	u32 otap_del_sel;
243 	u32 mask, val;
244 
245 	/* Setup DLL Output TAP delay */
246 	if (sdhci_am654->legacy_otapdly)
247 		otap_del_sel = sdhci_am654->otap_del_sel[0];
248 	else
249 		otap_del_sel = sdhci_am654->otap_del_sel[timing];
250 
251 	mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
252 	val = (0x1 << OTAPDLYENA_SHIFT) |
253 	      (otap_del_sel << OTAPDLYSEL_SHIFT);
254 	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val);
255 
256 	sdhci_set_clock(host, clock);
257 }
258 
259 static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg)
260 {
261 	unsigned char timing = host->mmc->ios.timing;
262 
263 	if (reg == SDHCI_HOST_CONTROL) {
264 		switch (timing) {
265 		/*
266 		 * According to the data manual, HISPD bit
267 		 * should not be set in these speed modes.
268 		 */
269 		case MMC_TIMING_SD_HS:
270 		case MMC_TIMING_MMC_HS:
271 		case MMC_TIMING_UHS_SDR12:
272 		case MMC_TIMING_UHS_SDR25:
273 			val &= ~SDHCI_CTRL_HISPD;
274 		}
275 	}
276 
277 	writeb(val, host->ioaddr + reg);
278 }
279 
280 static int sdhci_am654_execute_tuning(struct mmc_host *mmc, u32 opcode)
281 {
282 	struct sdhci_host *host = mmc_priv(mmc);
283 	int err = sdhci_execute_tuning(mmc, opcode);
284 
285 	if (err)
286 		return err;
287 	/*
288 	 * Tuning data remains in the buffer after tuning.
289 	 * Do a command and data reset to get rid of it
290 	 */
291 	sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
292 
293 	return 0;
294 }
295 
296 static u32 sdhci_am654_cqhci_irq(struct sdhci_host *host, u32 intmask)
297 {
298 	int cmd_error = 0;
299 	int data_error = 0;
300 
301 	if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
302 		return intmask;
303 
304 	cqhci_irq(host->mmc, intmask, cmd_error, data_error);
305 
306 	return 0;
307 }
308 
309 static struct sdhci_ops sdhci_am654_ops = {
310 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
311 	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
312 	.set_uhs_signaling = sdhci_set_uhs_signaling,
313 	.set_bus_width = sdhci_set_bus_width,
314 	.set_power = sdhci_set_power_and_bus_voltage,
315 	.set_clock = sdhci_am654_set_clock,
316 	.write_b = sdhci_am654_write_b,
317 	.irq = sdhci_am654_cqhci_irq,
318 	.reset = sdhci_reset,
319 };
320 
321 static const struct sdhci_pltfm_data sdhci_am654_pdata = {
322 	.ops = &sdhci_am654_ops,
323 	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
324 	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
325 };
326 
327 static const struct sdhci_am654_driver_data sdhci_am654_drvdata = {
328 	.pdata = &sdhci_am654_pdata,
329 	.flags = IOMUX_PRESENT | FREQSEL_2_BIT | STRBSEL_4_BIT | DLL_PRESENT |
330 		 DLL_CALIB,
331 };
332 
333 static struct sdhci_ops sdhci_j721e_8bit_ops = {
334 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
335 	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
336 	.set_uhs_signaling = sdhci_set_uhs_signaling,
337 	.set_bus_width = sdhci_set_bus_width,
338 	.set_power = sdhci_set_power_and_bus_voltage,
339 	.set_clock = sdhci_am654_set_clock,
340 	.write_b = sdhci_am654_write_b,
341 	.irq = sdhci_am654_cqhci_irq,
342 	.reset = sdhci_reset,
343 };
344 
345 static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = {
346 	.ops = &sdhci_j721e_8bit_ops,
347 	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
348 	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
349 };
350 
351 static const struct sdhci_am654_driver_data sdhci_j721e_8bit_drvdata = {
352 	.pdata = &sdhci_j721e_8bit_pdata,
353 	.flags = DLL_PRESENT | DLL_CALIB,
354 };
355 
356 static struct sdhci_ops sdhci_j721e_4bit_ops = {
357 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
358 	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
359 	.set_uhs_signaling = sdhci_set_uhs_signaling,
360 	.set_bus_width = sdhci_set_bus_width,
361 	.set_power = sdhci_set_power_and_bus_voltage,
362 	.set_clock = sdhci_j721e_4bit_set_clock,
363 	.write_b = sdhci_am654_write_b,
364 	.irq = sdhci_am654_cqhci_irq,
365 	.reset = sdhci_reset,
366 };
367 
368 static const struct sdhci_pltfm_data sdhci_j721e_4bit_pdata = {
369 	.ops = &sdhci_j721e_4bit_ops,
370 	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
371 	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
372 };
373 
374 static const struct sdhci_am654_driver_data sdhci_j721e_4bit_drvdata = {
375 	.pdata = &sdhci_j721e_4bit_pdata,
376 	.flags = IOMUX_PRESENT,
377 };
378 
379 static void sdhci_am654_dumpregs(struct mmc_host *mmc)
380 {
381 	sdhci_dumpregs(mmc_priv(mmc));
382 }
383 
384 static const struct cqhci_host_ops sdhci_am654_cqhci_ops = {
385 	.enable		= sdhci_cqe_enable,
386 	.disable	= sdhci_cqe_disable,
387 	.dumpregs	= sdhci_am654_dumpregs,
388 };
389 
390 static int sdhci_am654_cqe_add_host(struct sdhci_host *host)
391 {
392 	struct cqhci_host *cq_host;
393 	int ret;
394 
395 	cq_host = devm_kzalloc(host->mmc->parent, sizeof(struct cqhci_host),
396 			       GFP_KERNEL);
397 	if (!cq_host)
398 		return -ENOMEM;
399 
400 	cq_host->mmio = host->ioaddr + SDHCI_AM654_CQE_BASE_ADDR;
401 	cq_host->quirks |= CQHCI_QUIRK_SHORT_TXFR_DESC_SZ;
402 	cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
403 	cq_host->ops = &sdhci_am654_cqhci_ops;
404 
405 	host->mmc->caps2 |= MMC_CAP2_CQE;
406 
407 	ret = cqhci_init(cq_host, host->mmc, 1);
408 
409 	return ret;
410 }
411 
412 static int sdhci_am654_get_otap_delay(struct sdhci_host *host,
413 				      struct sdhci_am654_data *sdhci_am654)
414 {
415 	struct device *dev = mmc_dev(host->mmc);
416 	int i;
417 	int ret;
418 
419 	ret = device_property_read_u32(dev, td[MMC_TIMING_LEGACY].binding,
420 				 &sdhci_am654->otap_del_sel[MMC_TIMING_LEGACY]);
421 	if (ret) {
422 		/*
423 		 * ti,otap-del-sel-legacy is mandatory, look for old binding
424 		 * if not found.
425 		 */
426 		ret = device_property_read_u32(dev, "ti,otap-del-sel",
427 					       &sdhci_am654->otap_del_sel[0]);
428 		if (ret) {
429 			dev_err(dev, "Couldn't find otap-del-sel\n");
430 
431 			return ret;
432 		}
433 
434 		dev_info(dev, "Using legacy binding ti,otap-del-sel\n");
435 		sdhci_am654->legacy_otapdly = true;
436 
437 		return 0;
438 	}
439 
440 	for (i = MMC_TIMING_MMC_HS; i <= MMC_TIMING_MMC_HS400; i++) {
441 
442 		ret = device_property_read_u32(dev, td[i].binding,
443 					       &sdhci_am654->otap_del_sel[i]);
444 		if (ret) {
445 			dev_dbg(dev, "Couldn't find %s\n",
446 				td[i].binding);
447 			/*
448 			 * Remove the corresponding capability
449 			 * if an otap-del-sel value is not found
450 			 */
451 			if (i <= MMC_TIMING_MMC_DDR52)
452 				host->mmc->caps &= ~td[i].capability;
453 			else
454 				host->mmc->caps2 &= ~td[i].capability;
455 		}
456 	}
457 
458 	return 0;
459 }
460 
461 static int sdhci_am654_init(struct sdhci_host *host)
462 {
463 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
464 	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
465 	u32 ctl_cfg_2 = 0;
466 	u32 mask;
467 	u32 val;
468 	int ret;
469 
470 	/* Reset OTAP to default value */
471 	mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
472 	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, 0x0);
473 
474 	if (sdhci_am654->flags & DLL_CALIB) {
475 		regmap_read(sdhci_am654->base, PHY_STAT1, &val);
476 		if (~val & CALDONE_MASK) {
477 			/* Calibrate IO lines */
478 			regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
479 					   PDB_MASK, PDB_MASK);
480 			ret = regmap_read_poll_timeout(sdhci_am654->base,
481 						       PHY_STAT1, val,
482 						       val & CALDONE_MASK,
483 						       1, 20);
484 			if (ret)
485 				return ret;
486 		}
487 	}
488 
489 	/* Enable pins by setting IO mux to 0 */
490 	if (sdhci_am654->flags & IOMUX_PRESENT)
491 		regmap_update_bits(sdhci_am654->base, PHY_CTRL1,
492 				   IOMUX_ENABLE_MASK, 0);
493 
494 	/* Set slot type based on SD or eMMC */
495 	if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
496 		ctl_cfg_2 = SLOTTYPE_EMBEDDED;
497 
498 	regmap_update_bits(sdhci_am654->base, CTL_CFG_2, SLOTTYPE_MASK,
499 			   ctl_cfg_2);
500 
501 	ret = sdhci_setup_host(host);
502 	if (ret)
503 		return ret;
504 
505 	ret = sdhci_am654_cqe_add_host(host);
506 	if (ret)
507 		goto err_cleanup_host;
508 
509 	ret = sdhci_am654_get_otap_delay(host, sdhci_am654);
510 	if (ret)
511 		goto err_cleanup_host;
512 
513 	ret = __sdhci_add_host(host);
514 	if (ret)
515 		goto err_cleanup_host;
516 
517 	return 0;
518 
519 err_cleanup_host:
520 	sdhci_cleanup_host(host);
521 	return ret;
522 }
523 
524 static int sdhci_am654_get_of_property(struct platform_device *pdev,
525 					struct sdhci_am654_data *sdhci_am654)
526 {
527 	struct device *dev = &pdev->dev;
528 	int drv_strength;
529 	int ret;
530 
531 	if (sdhci_am654->flags & DLL_PRESENT) {
532 		ret = device_property_read_u32(dev, "ti,trm-icp",
533 					       &sdhci_am654->trm_icp);
534 		if (ret)
535 			return ret;
536 
537 		ret = device_property_read_u32(dev, "ti,driver-strength-ohm",
538 					       &drv_strength);
539 		if (ret)
540 			return ret;
541 
542 		switch (drv_strength) {
543 		case 50:
544 			sdhci_am654->drv_strength = DRIVER_STRENGTH_50_OHM;
545 			break;
546 		case 33:
547 			sdhci_am654->drv_strength = DRIVER_STRENGTH_33_OHM;
548 			break;
549 		case 66:
550 			sdhci_am654->drv_strength = DRIVER_STRENGTH_66_OHM;
551 			break;
552 		case 100:
553 			sdhci_am654->drv_strength = DRIVER_STRENGTH_100_OHM;
554 			break;
555 		case 40:
556 			sdhci_am654->drv_strength = DRIVER_STRENGTH_40_OHM;
557 			break;
558 		default:
559 			dev_err(dev, "Invalid driver strength\n");
560 			return -EINVAL;
561 		}
562 	}
563 
564 	device_property_read_u32(dev, "ti,strobe-sel", &sdhci_am654->strb_sel);
565 
566 	sdhci_get_of_property(pdev);
567 
568 	return 0;
569 }
570 
571 static const struct of_device_id sdhci_am654_of_match[] = {
572 	{
573 		.compatible = "ti,am654-sdhci-5.1",
574 		.data = &sdhci_am654_drvdata,
575 	},
576 	{
577 		.compatible = "ti,j721e-sdhci-8bit",
578 		.data = &sdhci_j721e_8bit_drvdata,
579 	},
580 	{
581 		.compatible = "ti,j721e-sdhci-4bit",
582 		.data = &sdhci_j721e_4bit_drvdata,
583 	},
584 	{ /* sentinel */ }
585 };
586 
587 static int sdhci_am654_probe(struct platform_device *pdev)
588 {
589 	const struct sdhci_am654_driver_data *drvdata;
590 	struct sdhci_pltfm_host *pltfm_host;
591 	struct sdhci_am654_data *sdhci_am654;
592 	const struct of_device_id *match;
593 	struct sdhci_host *host;
594 	struct clk *clk_xin;
595 	struct device *dev = &pdev->dev;
596 	void __iomem *base;
597 	int ret;
598 
599 	match = of_match_node(sdhci_am654_of_match, pdev->dev.of_node);
600 	drvdata = match->data;
601 	host = sdhci_pltfm_init(pdev, drvdata->pdata, sizeof(*sdhci_am654));
602 	if (IS_ERR(host))
603 		return PTR_ERR(host);
604 
605 	pltfm_host = sdhci_priv(host);
606 	sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
607 	sdhci_am654->flags = drvdata->flags;
608 
609 	clk_xin = devm_clk_get(dev, "clk_xin");
610 	if (IS_ERR(clk_xin)) {
611 		dev_err(dev, "clk_xin clock not found.\n");
612 		ret = PTR_ERR(clk_xin);
613 		goto err_pltfm_free;
614 	}
615 
616 	pltfm_host->clk = clk_xin;
617 
618 	/* Clocks are enabled using pm_runtime */
619 	pm_runtime_enable(dev);
620 	ret = pm_runtime_get_sync(dev);
621 	if (ret < 0) {
622 		pm_runtime_put_noidle(dev);
623 		goto pm_runtime_disable;
624 	}
625 
626 	base = devm_platform_ioremap_resource(pdev, 1);
627 	if (IS_ERR(base)) {
628 		ret = PTR_ERR(base);
629 		goto pm_runtime_put;
630 	}
631 
632 	sdhci_am654->base = devm_regmap_init_mmio(dev, base,
633 						  &sdhci_am654_regmap_config);
634 	if (IS_ERR(sdhci_am654->base)) {
635 		dev_err(dev, "Failed to initialize regmap\n");
636 		ret = PTR_ERR(sdhci_am654->base);
637 		goto pm_runtime_put;
638 	}
639 
640 	ret = sdhci_am654_get_of_property(pdev, sdhci_am654);
641 	if (ret)
642 		goto pm_runtime_put;
643 
644 	ret = mmc_of_parse(host->mmc);
645 	if (ret) {
646 		dev_err(dev, "parsing dt failed (%d)\n", ret);
647 		goto pm_runtime_put;
648 	}
649 
650 	host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning;
651 
652 	ret = sdhci_am654_init(host);
653 	if (ret)
654 		goto pm_runtime_put;
655 
656 	return 0;
657 
658 pm_runtime_put:
659 	pm_runtime_put_sync(dev);
660 pm_runtime_disable:
661 	pm_runtime_disable(dev);
662 err_pltfm_free:
663 	sdhci_pltfm_free(pdev);
664 	return ret;
665 }
666 
667 static int sdhci_am654_remove(struct platform_device *pdev)
668 {
669 	struct sdhci_host *host = platform_get_drvdata(pdev);
670 	int ret;
671 
672 	sdhci_remove_host(host, true);
673 	ret = pm_runtime_put_sync(&pdev->dev);
674 	if (ret < 0)
675 		return ret;
676 
677 	pm_runtime_disable(&pdev->dev);
678 	sdhci_pltfm_free(pdev);
679 
680 	return 0;
681 }
682 
683 static struct platform_driver sdhci_am654_driver = {
684 	.driver = {
685 		.name = "sdhci-am654",
686 		.of_match_table = sdhci_am654_of_match,
687 	},
688 	.probe = sdhci_am654_probe,
689 	.remove = sdhci_am654_remove,
690 };
691 
692 module_platform_driver(sdhci_am654_driver);
693 
694 MODULE_DESCRIPTION("Driver for SDHCI Controller on TI's AM654 devices");
695 MODULE_AUTHOR("Faiz Abbas <faiz_abbas@ti.com>");
696 MODULE_LICENSE("GPL");
697