xref: /linux/drivers/mmc/host/sdhci-cadence.c (revision be239684b18e1cdcafcf8c7face4a2f562c745ad)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2016 Socionext Inc.
4  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
5  */
6 
7 #include <linux/bitfield.h>
8 #include <linux/bits.h>
9 #include <linux/iopoll.h>
10 #include <linux/module.h>
11 #include <linux/mmc/host.h>
12 #include <linux/mmc/mmc.h>
13 #include <linux/of.h>
14 #include <linux/platform_device.h>
15 #include <linux/reset.h>
16 
17 #include "sdhci-pltfm.h"
18 
19 /* HRS - Host Register Set (specific to Cadence) */
20 #define SDHCI_CDNS_HRS04		0x10		/* PHY access port */
21 #define   SDHCI_CDNS_HRS04_ACK			BIT(26)
22 #define   SDHCI_CDNS_HRS04_RD			BIT(25)
23 #define   SDHCI_CDNS_HRS04_WR			BIT(24)
24 #define   SDHCI_CDNS_HRS04_RDATA		GENMASK(23, 16)
25 #define   SDHCI_CDNS_HRS04_WDATA		GENMASK(15, 8)
26 #define   SDHCI_CDNS_HRS04_ADDR			GENMASK(5, 0)
27 
28 #define SDHCI_CDNS_HRS06		0x18		/* eMMC control */
29 #define   SDHCI_CDNS_HRS06_TUNE_UP		BIT(15)
30 #define   SDHCI_CDNS_HRS06_TUNE			GENMASK(13, 8)
31 #define   SDHCI_CDNS_HRS06_MODE			GENMASK(2, 0)
32 #define   SDHCI_CDNS_HRS06_MODE_SD		0x0
33 #define   SDHCI_CDNS_HRS06_MODE_MMC_SDR		0x2
34 #define   SDHCI_CDNS_HRS06_MODE_MMC_DDR		0x3
35 #define   SDHCI_CDNS_HRS06_MODE_MMC_HS200	0x4
36 #define   SDHCI_CDNS_HRS06_MODE_MMC_HS400	0x5
37 #define   SDHCI_CDNS_HRS06_MODE_MMC_HS400ES	0x6
38 
39 /* SRS - Slot Register Set (SDHCI-compatible) */
40 #define SDHCI_CDNS_SRS_BASE		0x200
41 
42 /* PHY */
43 #define SDHCI_CDNS_PHY_DLY_SD_HS	0x00
44 #define SDHCI_CDNS_PHY_DLY_SD_DEFAULT	0x01
45 #define SDHCI_CDNS_PHY_DLY_UHS_SDR12	0x02
46 #define SDHCI_CDNS_PHY_DLY_UHS_SDR25	0x03
47 #define SDHCI_CDNS_PHY_DLY_UHS_SDR50	0x04
48 #define SDHCI_CDNS_PHY_DLY_UHS_DDR50	0x05
49 #define SDHCI_CDNS_PHY_DLY_EMMC_LEGACY	0x06
50 #define SDHCI_CDNS_PHY_DLY_EMMC_SDR	0x07
51 #define SDHCI_CDNS_PHY_DLY_EMMC_DDR	0x08
52 #define SDHCI_CDNS_PHY_DLY_SDCLK	0x0b
53 #define SDHCI_CDNS_PHY_DLY_HSMMC	0x0c
54 #define SDHCI_CDNS_PHY_DLY_STROBE	0x0d
55 
56 /*
57  * The tuned val register is 6 bit-wide, but not the whole of the range is
58  * available.  The range 0-42 seems to be available (then 43 wraps around to 0)
59  * but I am not quite sure if it is official.  Use only 0 to 39 for safety.
60  */
61 #define SDHCI_CDNS_MAX_TUNING_LOOP	40
62 
63 struct sdhci_cdns_phy_param {
64 	u8 addr;
65 	u8 data;
66 };
67 
68 struct sdhci_cdns_priv {
69 	void __iomem *hrs_addr;
70 	void __iomem *ctl_addr;	/* write control */
71 	spinlock_t wrlock;	/* write lock */
72 	bool enhanced_strobe;
73 	void (*priv_writel)(struct sdhci_cdns_priv *priv, u32 val, void __iomem *reg);
74 	struct reset_control *rst_hw;
75 	unsigned int nr_phy_params;
76 	struct sdhci_cdns_phy_param phy_params[];
77 };
78 
79 struct sdhci_cdns_phy_cfg {
80 	const char *property;
81 	u8 addr;
82 };
83 
84 struct sdhci_cdns_drv_data {
85 	int (*init)(struct platform_device *pdev);
86 	const struct sdhci_pltfm_data pltfm_data;
87 };
88 
89 static const struct sdhci_cdns_phy_cfg sdhci_cdns_phy_cfgs[] = {
90 	{ "cdns,phy-input-delay-sd-highspeed", SDHCI_CDNS_PHY_DLY_SD_HS, },
91 	{ "cdns,phy-input-delay-legacy", SDHCI_CDNS_PHY_DLY_SD_DEFAULT, },
92 	{ "cdns,phy-input-delay-sd-uhs-sdr12", SDHCI_CDNS_PHY_DLY_UHS_SDR12, },
93 	{ "cdns,phy-input-delay-sd-uhs-sdr25", SDHCI_CDNS_PHY_DLY_UHS_SDR25, },
94 	{ "cdns,phy-input-delay-sd-uhs-sdr50", SDHCI_CDNS_PHY_DLY_UHS_SDR50, },
95 	{ "cdns,phy-input-delay-sd-uhs-ddr50", SDHCI_CDNS_PHY_DLY_UHS_DDR50, },
96 	{ "cdns,phy-input-delay-mmc-highspeed", SDHCI_CDNS_PHY_DLY_EMMC_SDR, },
97 	{ "cdns,phy-input-delay-mmc-ddr", SDHCI_CDNS_PHY_DLY_EMMC_DDR, },
98 	{ "cdns,phy-dll-delay-sdclk", SDHCI_CDNS_PHY_DLY_SDCLK, },
99 	{ "cdns,phy-dll-delay-sdclk-hsmmc", SDHCI_CDNS_PHY_DLY_HSMMC, },
100 	{ "cdns,phy-dll-delay-strobe", SDHCI_CDNS_PHY_DLY_STROBE, },
101 };
102 
103 static inline void cdns_writel(struct sdhci_cdns_priv *priv, u32 val,
104 			       void __iomem *reg)
105 {
106 	writel(val, reg);
107 }
108 
109 static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv,
110 				    u8 addr, u8 data)
111 {
112 	void __iomem *reg = priv->hrs_addr + SDHCI_CDNS_HRS04;
113 	u32 tmp;
114 	int ret;
115 
116 	ret = readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS04_ACK),
117 				 0, 10);
118 	if (ret)
119 		return ret;
120 
121 	tmp = FIELD_PREP(SDHCI_CDNS_HRS04_WDATA, data) |
122 	      FIELD_PREP(SDHCI_CDNS_HRS04_ADDR, addr);
123 	priv->priv_writel(priv, tmp, reg);
124 
125 	tmp |= SDHCI_CDNS_HRS04_WR;
126 	priv->priv_writel(priv, tmp, reg);
127 
128 	ret = readl_poll_timeout(reg, tmp, tmp & SDHCI_CDNS_HRS04_ACK, 0, 10);
129 	if (ret)
130 		return ret;
131 
132 	tmp &= ~SDHCI_CDNS_HRS04_WR;
133 	priv->priv_writel(priv, tmp, reg);
134 
135 	ret = readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS04_ACK),
136 				 0, 10);
137 
138 	return ret;
139 }
140 
141 static unsigned int sdhci_cdns_phy_param_count(struct device_node *np)
142 {
143 	unsigned int count = 0;
144 	int i;
145 
146 	for (i = 0; i < ARRAY_SIZE(sdhci_cdns_phy_cfgs); i++)
147 		if (of_property_read_bool(np, sdhci_cdns_phy_cfgs[i].property))
148 			count++;
149 
150 	return count;
151 }
152 
153 static void sdhci_cdns_phy_param_parse(struct device_node *np,
154 				       struct sdhci_cdns_priv *priv)
155 {
156 	struct sdhci_cdns_phy_param *p = priv->phy_params;
157 	u32 val;
158 	int ret, i;
159 
160 	for (i = 0; i < ARRAY_SIZE(sdhci_cdns_phy_cfgs); i++) {
161 		ret = of_property_read_u32(np, sdhci_cdns_phy_cfgs[i].property,
162 					   &val);
163 		if (ret)
164 			continue;
165 
166 		p->addr = sdhci_cdns_phy_cfgs[i].addr;
167 		p->data = val;
168 		p++;
169 	}
170 }
171 
172 static int sdhci_cdns_phy_init(struct sdhci_cdns_priv *priv)
173 {
174 	int ret, i;
175 
176 	for (i = 0; i < priv->nr_phy_params; i++) {
177 		ret = sdhci_cdns_write_phy_reg(priv, priv->phy_params[i].addr,
178 					       priv->phy_params[i].data);
179 		if (ret)
180 			return ret;
181 	}
182 
183 	return 0;
184 }
185 
186 static void *sdhci_cdns_priv(struct sdhci_host *host)
187 {
188 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
189 
190 	return sdhci_pltfm_priv(pltfm_host);
191 }
192 
193 static unsigned int sdhci_cdns_get_timeout_clock(struct sdhci_host *host)
194 {
195 	/*
196 	 * Cadence's spec says the Timeout Clock Frequency is the same as the
197 	 * Base Clock Frequency.
198 	 */
199 	return host->max_clk;
200 }
201 
202 static void sdhci_cdns_set_emmc_mode(struct sdhci_cdns_priv *priv, u32 mode)
203 {
204 	u32 tmp;
205 
206 	/* The speed mode for eMMC is selected by HRS06 register */
207 	tmp = readl(priv->hrs_addr + SDHCI_CDNS_HRS06);
208 	tmp &= ~SDHCI_CDNS_HRS06_MODE;
209 	tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_MODE, mode);
210 	priv->priv_writel(priv, tmp, priv->hrs_addr + SDHCI_CDNS_HRS06);
211 }
212 
213 static u32 sdhci_cdns_get_emmc_mode(struct sdhci_cdns_priv *priv)
214 {
215 	u32 tmp;
216 
217 	tmp = readl(priv->hrs_addr + SDHCI_CDNS_HRS06);
218 	return FIELD_GET(SDHCI_CDNS_HRS06_MODE, tmp);
219 }
220 
221 static int sdhci_cdns_set_tune_val(struct sdhci_host *host, unsigned int val)
222 {
223 	struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host);
224 	void __iomem *reg = priv->hrs_addr + SDHCI_CDNS_HRS06;
225 	u32 tmp;
226 	int i, ret;
227 
228 	if (WARN_ON(!FIELD_FIT(SDHCI_CDNS_HRS06_TUNE, val)))
229 		return -EINVAL;
230 
231 	tmp = readl(reg);
232 	tmp &= ~SDHCI_CDNS_HRS06_TUNE;
233 	tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_TUNE, val);
234 
235 	/*
236 	 * Workaround for IP errata:
237 	 * The IP6116 SD/eMMC PHY design has a timing issue on receive data
238 	 * path. Send tune request twice.
239 	 */
240 	for (i = 0; i < 2; i++) {
241 		tmp |= SDHCI_CDNS_HRS06_TUNE_UP;
242 		priv->priv_writel(priv, tmp, reg);
243 
244 		ret = readl_poll_timeout(reg, tmp,
245 					 !(tmp & SDHCI_CDNS_HRS06_TUNE_UP),
246 					 0, 1);
247 		if (ret)
248 			return ret;
249 	}
250 
251 	return 0;
252 }
253 
254 /*
255  * In SD mode, software must not use the hardware tuning and instead perform
256  * an almost identical procedure to eMMC.
257  */
258 static int sdhci_cdns_execute_tuning(struct sdhci_host *host, u32 opcode)
259 {
260 	int cur_streak = 0;
261 	int max_streak = 0;
262 	int end_of_streak = 0;
263 	int i;
264 
265 	/*
266 	 * Do not execute tuning for UHS_SDR50 or UHS_DDR50.
267 	 * The delay is set by probe, based on the DT properties.
268 	 */
269 	if (host->timing != MMC_TIMING_MMC_HS200 &&
270 	    host->timing != MMC_TIMING_UHS_SDR104)
271 		return 0;
272 
273 	for (i = 0; i < SDHCI_CDNS_MAX_TUNING_LOOP; i++) {
274 		if (sdhci_cdns_set_tune_val(host, i) ||
275 		    mmc_send_tuning(host->mmc, opcode, NULL)) { /* bad */
276 			cur_streak = 0;
277 		} else { /* good */
278 			cur_streak++;
279 			if (cur_streak > max_streak) {
280 				max_streak = cur_streak;
281 				end_of_streak = i;
282 			}
283 		}
284 	}
285 
286 	if (!max_streak) {
287 		dev_err(mmc_dev(host->mmc), "no tuning point found\n");
288 		return -EIO;
289 	}
290 
291 	return sdhci_cdns_set_tune_val(host, end_of_streak - max_streak / 2);
292 }
293 
294 static void sdhci_cdns_set_uhs_signaling(struct sdhci_host *host,
295 					 unsigned int timing)
296 {
297 	struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host);
298 	u32 mode;
299 
300 	switch (timing) {
301 	case MMC_TIMING_MMC_HS:
302 		mode = SDHCI_CDNS_HRS06_MODE_MMC_SDR;
303 		break;
304 	case MMC_TIMING_MMC_DDR52:
305 		mode = SDHCI_CDNS_HRS06_MODE_MMC_DDR;
306 		break;
307 	case MMC_TIMING_MMC_HS200:
308 		mode = SDHCI_CDNS_HRS06_MODE_MMC_HS200;
309 		break;
310 	case MMC_TIMING_MMC_HS400:
311 		if (priv->enhanced_strobe)
312 			mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400ES;
313 		else
314 			mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400;
315 		break;
316 	default:
317 		mode = SDHCI_CDNS_HRS06_MODE_SD;
318 		break;
319 	}
320 
321 	sdhci_cdns_set_emmc_mode(priv, mode);
322 
323 	/* For SD, fall back to the default handler */
324 	if (mode == SDHCI_CDNS_HRS06_MODE_SD)
325 		sdhci_set_uhs_signaling(host, timing);
326 }
327 
328 /* Elba control register bits [6:3] are byte-lane enables */
329 #define ELBA_BYTE_ENABLE_MASK(x)	((x) << 3)
330 
331 /*
332  * The Pensando Elba SoC explicitly controls byte-lane enabling on writes
333  * which includes writes to the HRS registers.  The write lock (wrlock)
334  * is used to ensure byte-lane enable, using write control (ctl_addr),
335  * occurs before the data write.
336  */
337 static void elba_priv_writel(struct sdhci_cdns_priv *priv, u32 val,
338 			     void __iomem *reg)
339 {
340 	unsigned long flags;
341 
342 	spin_lock_irqsave(&priv->wrlock, flags);
343 	writel(GENMASK(7, 3), priv->ctl_addr);
344 	writel(val, reg);
345 	spin_unlock_irqrestore(&priv->wrlock, flags);
346 }
347 
348 static void elba_write_l(struct sdhci_host *host, u32 val, int reg)
349 {
350 	elba_priv_writel(sdhci_cdns_priv(host), val, host->ioaddr + reg);
351 }
352 
353 static void elba_write_w(struct sdhci_host *host, u16 val, int reg)
354 {
355 	struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host);
356 	u32 shift = reg & GENMASK(1, 0);
357 	unsigned long flags;
358 	u32 byte_enables;
359 
360 	byte_enables = GENMASK(1, 0) << shift;
361 	spin_lock_irqsave(&priv->wrlock, flags);
362 	writel(ELBA_BYTE_ENABLE_MASK(byte_enables), priv->ctl_addr);
363 	writew(val, host->ioaddr + reg);
364 	spin_unlock_irqrestore(&priv->wrlock, flags);
365 }
366 
367 static void elba_write_b(struct sdhci_host *host, u8 val, int reg)
368 {
369 	struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host);
370 	u32 shift = reg & GENMASK(1, 0);
371 	unsigned long flags;
372 	u32 byte_enables;
373 
374 	byte_enables = BIT(0) << shift;
375 	spin_lock_irqsave(&priv->wrlock, flags);
376 	writel(ELBA_BYTE_ENABLE_MASK(byte_enables), priv->ctl_addr);
377 	writeb(val, host->ioaddr + reg);
378 	spin_unlock_irqrestore(&priv->wrlock, flags);
379 }
380 
381 static const struct sdhci_ops sdhci_elba_ops = {
382 	.write_l = elba_write_l,
383 	.write_w = elba_write_w,
384 	.write_b = elba_write_b,
385 	.set_clock = sdhci_set_clock,
386 	.get_timeout_clock = sdhci_cdns_get_timeout_clock,
387 	.set_bus_width = sdhci_set_bus_width,
388 	.reset = sdhci_reset,
389 	.set_uhs_signaling = sdhci_cdns_set_uhs_signaling,
390 };
391 
392 static int elba_drv_init(struct platform_device *pdev)
393 {
394 	struct sdhci_host *host = platform_get_drvdata(pdev);
395 	struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host);
396 	void __iomem *ioaddr;
397 
398 	host->mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA;
399 	spin_lock_init(&priv->wrlock);
400 
401 	/* Byte-lane control register */
402 	ioaddr = devm_platform_ioremap_resource(pdev, 1);
403 	if (IS_ERR(ioaddr))
404 		return PTR_ERR(ioaddr);
405 
406 	priv->ctl_addr = ioaddr;
407 	priv->priv_writel = elba_priv_writel;
408 	writel(ELBA_BYTE_ENABLE_MASK(0xf), priv->ctl_addr);
409 
410 	return 0;
411 }
412 
413 static const struct sdhci_ops sdhci_cdns_ops = {
414 	.set_clock = sdhci_set_clock,
415 	.get_timeout_clock = sdhci_cdns_get_timeout_clock,
416 	.set_bus_width = sdhci_set_bus_width,
417 	.reset = sdhci_reset,
418 	.platform_execute_tuning = sdhci_cdns_execute_tuning,
419 	.set_uhs_signaling = sdhci_cdns_set_uhs_signaling,
420 };
421 
422 static const struct sdhci_cdns_drv_data sdhci_cdns_uniphier_drv_data = {
423 	.pltfm_data = {
424 		.ops = &sdhci_cdns_ops,
425 		.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
426 	},
427 };
428 
429 static const struct sdhci_cdns_drv_data sdhci_elba_drv_data = {
430 	.init = elba_drv_init,
431 	.pltfm_data = {
432 		.ops = &sdhci_elba_ops,
433 	},
434 };
435 
436 static const struct sdhci_cdns_drv_data sdhci_cdns_drv_data = {
437 	.pltfm_data = {
438 		.ops = &sdhci_cdns_ops,
439 	},
440 };
441 
442 static void sdhci_cdns_hs400_enhanced_strobe(struct mmc_host *mmc,
443 					     struct mmc_ios *ios)
444 {
445 	struct sdhci_host *host = mmc_priv(mmc);
446 	struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host);
447 	u32 mode;
448 
449 	priv->enhanced_strobe = ios->enhanced_strobe;
450 
451 	mode = sdhci_cdns_get_emmc_mode(priv);
452 
453 	if (mode == SDHCI_CDNS_HRS06_MODE_MMC_HS400 && ios->enhanced_strobe)
454 		sdhci_cdns_set_emmc_mode(priv,
455 					 SDHCI_CDNS_HRS06_MODE_MMC_HS400ES);
456 
457 	if (mode == SDHCI_CDNS_HRS06_MODE_MMC_HS400ES && !ios->enhanced_strobe)
458 		sdhci_cdns_set_emmc_mode(priv,
459 					 SDHCI_CDNS_HRS06_MODE_MMC_HS400);
460 }
461 
462 static void sdhci_cdns_mmc_hw_reset(struct mmc_host *mmc)
463 {
464 	struct sdhci_host *host = mmc_priv(mmc);
465 	struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host);
466 
467 	dev_dbg(mmc_dev(host->mmc), "emmc hardware reset\n");
468 
469 	reset_control_assert(priv->rst_hw);
470 	/* For eMMC, minimum is 1us but give it 3us for good measure */
471 	udelay(3);
472 
473 	reset_control_deassert(priv->rst_hw);
474 	/* For eMMC, minimum is 200us but give it 300us for good measure */
475 	usleep_range(300, 1000);
476 }
477 
478 static int sdhci_cdns_probe(struct platform_device *pdev)
479 {
480 	struct sdhci_host *host;
481 	const struct sdhci_cdns_drv_data *data;
482 	struct sdhci_pltfm_host *pltfm_host;
483 	struct sdhci_cdns_priv *priv;
484 	struct clk *clk;
485 	unsigned int nr_phy_params;
486 	int ret;
487 	struct device *dev = &pdev->dev;
488 	static const u16 version = SDHCI_SPEC_400 << SDHCI_SPEC_VER_SHIFT;
489 
490 	clk = devm_clk_get_enabled(dev, NULL);
491 	if (IS_ERR(clk))
492 		return PTR_ERR(clk);
493 
494 	data = of_device_get_match_data(dev);
495 	if (!data)
496 		data = &sdhci_cdns_drv_data;
497 
498 	nr_phy_params = sdhci_cdns_phy_param_count(dev->of_node);
499 	host = sdhci_pltfm_init(pdev, &data->pltfm_data,
500 				struct_size(priv, phy_params, nr_phy_params));
501 	if (IS_ERR(host))
502 		return PTR_ERR(host);
503 
504 	pltfm_host = sdhci_priv(host);
505 	pltfm_host->clk = clk;
506 
507 	priv = sdhci_pltfm_priv(pltfm_host);
508 	priv->nr_phy_params = nr_phy_params;
509 	priv->hrs_addr = host->ioaddr;
510 	priv->enhanced_strobe = false;
511 	priv->priv_writel = cdns_writel;
512 	host->ioaddr += SDHCI_CDNS_SRS_BASE;
513 	host->mmc_host_ops.hs400_enhanced_strobe =
514 				sdhci_cdns_hs400_enhanced_strobe;
515 	if (data->init) {
516 		ret = data->init(pdev);
517 		if (ret)
518 			goto free;
519 	}
520 	sdhci_enable_v4_mode(host);
521 	__sdhci_read_caps(host, &version, NULL, NULL);
522 
523 	sdhci_get_of_property(pdev);
524 
525 	ret = mmc_of_parse(host->mmc);
526 	if (ret)
527 		goto free;
528 
529 	sdhci_cdns_phy_param_parse(dev->of_node, priv);
530 
531 	ret = sdhci_cdns_phy_init(priv);
532 	if (ret)
533 		goto free;
534 
535 	if (host->mmc->caps & MMC_CAP_HW_RESET) {
536 		priv->rst_hw = devm_reset_control_get_optional_exclusive(dev, NULL);
537 		if (IS_ERR(priv->rst_hw)) {
538 			ret = dev_err_probe(mmc_dev(host->mmc), PTR_ERR(priv->rst_hw),
539 					    "reset controller error\n");
540 			goto free;
541 		}
542 		if (priv->rst_hw)
543 			host->mmc_host_ops.card_hw_reset = sdhci_cdns_mmc_hw_reset;
544 	}
545 
546 	ret = sdhci_add_host(host);
547 	if (ret)
548 		goto free;
549 
550 	return 0;
551 free:
552 	sdhci_pltfm_free(pdev);
553 	return ret;
554 }
555 
556 #ifdef CONFIG_PM_SLEEP
557 static int sdhci_cdns_resume(struct device *dev)
558 {
559 	struct sdhci_host *host = dev_get_drvdata(dev);
560 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
561 	struct sdhci_cdns_priv *priv = sdhci_pltfm_priv(pltfm_host);
562 	int ret;
563 
564 	ret = clk_prepare_enable(pltfm_host->clk);
565 	if (ret)
566 		return ret;
567 
568 	ret = sdhci_cdns_phy_init(priv);
569 	if (ret)
570 		goto disable_clk;
571 
572 	ret = sdhci_resume_host(host);
573 	if (ret)
574 		goto disable_clk;
575 
576 	return 0;
577 
578 disable_clk:
579 	clk_disable_unprepare(pltfm_host->clk);
580 
581 	return ret;
582 }
583 #endif
584 
585 static const struct dev_pm_ops sdhci_cdns_pm_ops = {
586 	SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, sdhci_cdns_resume)
587 };
588 
589 static const struct of_device_id sdhci_cdns_match[] = {
590 	{
591 		.compatible = "socionext,uniphier-sd4hc",
592 		.data = &sdhci_cdns_uniphier_drv_data,
593 	},
594 	{
595 		.compatible = "amd,pensando-elba-sd4hc",
596 		.data = &sdhci_elba_drv_data,
597 	},
598 	{ .compatible = "cdns,sd4hc" },
599 	{ /* sentinel */ }
600 };
601 MODULE_DEVICE_TABLE(of, sdhci_cdns_match);
602 
603 static struct platform_driver sdhci_cdns_driver = {
604 	.driver = {
605 		.name = "sdhci-cdns",
606 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
607 		.pm = &sdhci_cdns_pm_ops,
608 		.of_match_table = sdhci_cdns_match,
609 	},
610 	.probe = sdhci_cdns_probe,
611 	.remove_new = sdhci_pltfm_remove,
612 };
613 module_platform_driver(sdhci_cdns_driver);
614 
615 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
616 MODULE_DESCRIPTION("Cadence SD/SDIO/eMMC Host Controller Driver");
617 MODULE_LICENSE("GPL");
618