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