1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2016 Socionext Inc.
4 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
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>
14 #include <linux/platform_device.h>
15 #include <linux/reset.h>
17 #include "sdhci-pltfm.h"
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)
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
39 /* SRS - Slot Register Set (SDHCI-compatible) */
40 #define SDHCI_CDNS_SRS_BASE 0x200
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
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.
61 #define SDHCI_CDNS_MAX_TUNING_LOOP 40
63 struct sdhci_cdns_phy_param
{
68 struct sdhci_cdns_priv
{
69 void __iomem
*hrs_addr
;
70 void __iomem
*ctl_addr
; /* write control */
71 spinlock_t wrlock
; /* write lock */
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
[];
79 struct sdhci_cdns_phy_cfg
{
84 struct sdhci_cdns_drv_data
{
85 int (*init
)(struct platform_device
*pdev
);
86 const struct sdhci_pltfm_data pltfm_data
;
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
, },
103 static inline void cdns_writel(struct sdhci_cdns_priv
*priv
, u32 val
,
109 static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv
*priv
,
112 void __iomem
*reg
= priv
->hrs_addr
+ SDHCI_CDNS_HRS04
;
116 ret
= readl_poll_timeout(reg
, tmp
, !(tmp
& SDHCI_CDNS_HRS04_ACK
),
121 tmp
= FIELD_PREP(SDHCI_CDNS_HRS04_WDATA
, data
) |
122 FIELD_PREP(SDHCI_CDNS_HRS04_ADDR
, addr
);
123 priv
->priv_writel(priv
, tmp
, reg
);
125 tmp
|= SDHCI_CDNS_HRS04_WR
;
126 priv
->priv_writel(priv
, tmp
, reg
);
128 ret
= readl_poll_timeout(reg
, tmp
, tmp
& SDHCI_CDNS_HRS04_ACK
, 0, 10);
132 tmp
&= ~SDHCI_CDNS_HRS04_WR
;
133 priv
->priv_writel(priv
, tmp
, reg
);
135 ret
= readl_poll_timeout(reg
, tmp
, !(tmp
& SDHCI_CDNS_HRS04_ACK
),
141 static unsigned int sdhci_cdns_phy_param_count(struct device_node
*np
)
143 unsigned int count
= 0;
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
))
153 static void sdhci_cdns_phy_param_parse(struct device_node
*np
,
154 struct sdhci_cdns_priv
*priv
)
156 struct sdhci_cdns_phy_param
*p
= priv
->phy_params
;
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
,
166 p
->addr
= sdhci_cdns_phy_cfgs
[i
].addr
;
172 static int sdhci_cdns_phy_init(struct sdhci_cdns_priv
*priv
)
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
);
186 static void *sdhci_cdns_priv(struct sdhci_host
*host
)
188 struct sdhci_pltfm_host
*pltfm_host
= sdhci_priv(host
);
190 return sdhci_pltfm_priv(pltfm_host
);
193 static unsigned int sdhci_cdns_get_timeout_clock(struct sdhci_host
*host
)
196 * Cadence's spec says the Timeout Clock Frequency is the same as the
197 * Base Clock Frequency.
199 return host
->max_clk
;
202 static void sdhci_cdns_set_emmc_mode(struct sdhci_cdns_priv
*priv
, u32 mode
)
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
);
213 static u32
sdhci_cdns_get_emmc_mode(struct sdhci_cdns_priv
*priv
)
217 tmp
= readl(priv
->hrs_addr
+ SDHCI_CDNS_HRS06
);
218 return FIELD_GET(SDHCI_CDNS_HRS06_MODE
, tmp
);
221 static int sdhci_cdns_set_tune_val(struct sdhci_host
*host
, unsigned int val
)
223 struct sdhci_cdns_priv
*priv
= sdhci_cdns_priv(host
);
224 void __iomem
*reg
= priv
->hrs_addr
+ SDHCI_CDNS_HRS06
;
228 if (WARN_ON(!FIELD_FIT(SDHCI_CDNS_HRS06_TUNE
, val
)))
232 tmp
&= ~SDHCI_CDNS_HRS06_TUNE
;
233 tmp
|= FIELD_PREP(SDHCI_CDNS_HRS06_TUNE
, val
);
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.
240 for (i
= 0; i
< 2; i
++) {
241 tmp
|= SDHCI_CDNS_HRS06_TUNE_UP
;
242 priv
->priv_writel(priv
, tmp
, reg
);
244 ret
= readl_poll_timeout(reg
, tmp
,
245 !(tmp
& SDHCI_CDNS_HRS06_TUNE_UP
),
255 * In SD mode, software must not use the hardware tuning and instead perform
256 * an almost identical procedure to eMMC.
258 static int sdhci_cdns_execute_tuning(struct sdhci_host
*host
, u32 opcode
)
262 int end_of_streak
= 0;
266 * Do not execute tuning for UHS_SDR50 or UHS_DDR50.
267 * The delay is set by probe, based on the DT properties.
269 if (host
->timing
!= MMC_TIMING_MMC_HS200
&&
270 host
->timing
!= MMC_TIMING_UHS_SDR104
)
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 */
279 if (cur_streak
> max_streak
) {
280 max_streak
= cur_streak
;
287 dev_err(mmc_dev(host
->mmc
), "no tuning point found\n");
291 return sdhci_cdns_set_tune_val(host
, end_of_streak
- max_streak
/ 2);
294 static void sdhci_cdns_set_uhs_signaling(struct sdhci_host
*host
,
297 struct sdhci_cdns_priv
*priv
= sdhci_cdns_priv(host
);
301 case MMC_TIMING_MMC_HS
:
302 mode
= SDHCI_CDNS_HRS06_MODE_MMC_SDR
;
304 case MMC_TIMING_MMC_DDR52
:
305 mode
= SDHCI_CDNS_HRS06_MODE_MMC_DDR
;
307 case MMC_TIMING_MMC_HS200
:
308 mode
= SDHCI_CDNS_HRS06_MODE_MMC_HS200
;
310 case MMC_TIMING_MMC_HS400
:
311 if (priv
->enhanced_strobe
)
312 mode
= SDHCI_CDNS_HRS06_MODE_MMC_HS400ES
;
314 mode
= SDHCI_CDNS_HRS06_MODE_MMC_HS400
;
317 mode
= SDHCI_CDNS_HRS06_MODE_SD
;
321 sdhci_cdns_set_emmc_mode(priv
, mode
);
323 /* For SD, fall back to the default handler */
324 if (mode
== SDHCI_CDNS_HRS06_MODE_SD
)
325 sdhci_set_uhs_signaling(host
, timing
);
328 /* Elba control register bits [6:3] are byte-lane enables */
329 #define ELBA_BYTE_ENABLE_MASK(x) ((x) << 3)
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.
337 static void elba_priv_writel(struct sdhci_cdns_priv
*priv
, u32 val
,
342 spin_lock_irqsave(&priv
->wrlock
, flags
);
343 writel(GENMASK(7, 3), priv
->ctl_addr
);
345 spin_unlock_irqrestore(&priv
->wrlock
, flags
);
348 static void elba_write_l(struct sdhci_host
*host
, u32 val
, int reg
)
350 elba_priv_writel(sdhci_cdns_priv(host
), val
, host
->ioaddr
+ reg
);
353 static void elba_write_w(struct sdhci_host
*host
, u16 val
, int reg
)
355 struct sdhci_cdns_priv
*priv
= sdhci_cdns_priv(host
);
356 u32 shift
= reg
& GENMASK(1, 0);
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
);
367 static void elba_write_b(struct sdhci_host
*host
, u8 val
, int reg
)
369 struct sdhci_cdns_priv
*priv
= sdhci_cdns_priv(host
);
370 u32 shift
= reg
& GENMASK(1, 0);
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
);
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
,
392 static int elba_drv_init(struct platform_device
*pdev
)
394 struct sdhci_host
*host
= platform_get_drvdata(pdev
);
395 struct sdhci_cdns_priv
*priv
= sdhci_cdns_priv(host
);
396 void __iomem
*ioaddr
;
398 host
->mmc
->caps
|= MMC_CAP_1_8V_DDR
| MMC_CAP_8_BIT_DATA
;
399 spin_lock_init(&priv
->wrlock
);
401 /* Byte-lane control register */
402 ioaddr
= devm_platform_ioremap_resource(pdev
, 1);
404 return PTR_ERR(ioaddr
);
406 priv
->ctl_addr
= ioaddr
;
407 priv
->priv_writel
= elba_priv_writel
;
408 writel(ELBA_BYTE_ENABLE_MASK(0xf), priv
->ctl_addr
);
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
,
422 static const struct sdhci_cdns_drv_data sdhci_cdns_uniphier_drv_data
= {
424 .ops
= &sdhci_cdns_ops
,
425 .quirks2
= SDHCI_QUIRK2_PRESET_VALUE_BROKEN
,
429 static const struct sdhci_cdns_drv_data sdhci_elba_drv_data
= {
430 .init
= elba_drv_init
,
432 .ops
= &sdhci_elba_ops
,
436 static const struct sdhci_cdns_drv_data sdhci_cdns_drv_data
= {
438 .ops
= &sdhci_cdns_ops
,
442 static void sdhci_cdns_hs400_enhanced_strobe(struct mmc_host
*mmc
,
445 struct sdhci_host
*host
= mmc_priv(mmc
);
446 struct sdhci_cdns_priv
*priv
= sdhci_cdns_priv(host
);
449 priv
->enhanced_strobe
= ios
->enhanced_strobe
;
451 mode
= sdhci_cdns_get_emmc_mode(priv
);
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
);
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
);
462 static void sdhci_cdns_mmc_hw_reset(struct mmc_host
*mmc
)
464 struct sdhci_host
*host
= mmc_priv(mmc
);
465 struct sdhci_cdns_priv
*priv
= sdhci_cdns_priv(host
);
467 dev_dbg(mmc_dev(host
->mmc
), "emmc hardware reset\n");
469 reset_control_assert(priv
->rst_hw
);
470 /* For eMMC, minimum is 1us but give it 3us for good measure */
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);
478 static int sdhci_cdns_probe(struct platform_device
*pdev
)
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
;
485 unsigned int nr_phy_params
;
487 struct device
*dev
= &pdev
->dev
;
488 static const u16 version
= SDHCI_SPEC_400
<< SDHCI_SPEC_VER_SHIFT
;
490 clk
= devm_clk_get_enabled(dev
, NULL
);
494 data
= of_device_get_match_data(dev
);
496 data
= &sdhci_cdns_drv_data
;
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
));
502 return PTR_ERR(host
);
504 pltfm_host
= sdhci_priv(host
);
505 pltfm_host
->clk
= clk
;
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
;
516 ret
= data
->init(pdev
);
520 sdhci_enable_v4_mode(host
);
521 __sdhci_read_caps(host
, &version
, NULL
, NULL
);
523 sdhci_get_of_property(pdev
);
525 ret
= mmc_of_parse(host
->mmc
);
529 sdhci_cdns_phy_param_parse(dev
->of_node
, priv
);
531 ret
= sdhci_cdns_phy_init(priv
);
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");
543 host
->mmc_host_ops
.card_hw_reset
= sdhci_cdns_mmc_hw_reset
;
546 ret
= sdhci_add_host(host
);
552 sdhci_pltfm_free(pdev
);
556 #ifdef CONFIG_PM_SLEEP
557 static int sdhci_cdns_resume(struct device
*dev
)
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
);
564 ret
= clk_prepare_enable(pltfm_host
->clk
);
568 ret
= sdhci_cdns_phy_init(priv
);
572 ret
= sdhci_resume_host(host
);
579 clk_disable_unprepare(pltfm_host
->clk
);
585 static const struct dev_pm_ops sdhci_cdns_pm_ops
= {
586 SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend
, sdhci_cdns_resume
)
589 static const struct of_device_id sdhci_cdns_match
[] = {
591 .compatible
= "socionext,uniphier-sd4hc",
592 .data
= &sdhci_cdns_uniphier_drv_data
,
595 .compatible
= "amd,pensando-elba-sd4hc",
596 .data
= &sdhci_elba_drv_data
,
598 { .compatible
= "cdns,sd4hc" },
601 MODULE_DEVICE_TABLE(of
, sdhci_cdns_match
);
603 static struct platform_driver sdhci_cdns_driver
= {
605 .name
= "sdhci-cdns",
606 .probe_type
= PROBE_PREFER_ASYNCHRONOUS
,
607 .pm
= &sdhci_cdns_pm_ops
,
608 .of_match_table
= sdhci_cdns_match
,
610 .probe
= sdhci_cdns_probe
,
611 .remove
= sdhci_pltfm_remove
,
613 module_platform_driver(sdhci_cdns_driver
);
615 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
616 MODULE_DESCRIPTION("Cadence SD/SDIO/eMMC Host Controller Driver");
617 MODULE_LICENSE("GPL");