Skip to content

Commit 505c581

Browse files
liamfraserpopcornmix
authored andcommitted
mmc: sdhci-of-dwcmshc: define sdio timeout clocks
Signed-off-by: Liam Fraser <liam@raspberrypi.com> mmc: sdhci-of-dwcmshc: rp1 sdio changes Signed-off-by: Phil Elwell <phil@raspberrypi.com> drivers: mmc: sdhci-of-dwcmshc: add RP1 dt ID and quirks Differentiate the RP1 variant of the Designware MSHC controller(s). Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
1 parent 0f638f4 commit 505c581

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

drivers/mmc/host/sdhci-of-dwcmshc.c

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ struct rk35xx_priv {
221221

222222
struct dwcmshc_priv {
223223
struct clk *bus_clk;
224+
struct clk *sdio_clk;
224225
int vendor_specific_area1; /* P_VENDOR_SPECIFIC_AREA1 reg */
225226
int vendor_specific_area2; /* P_VENDOR_SPECIFIC_AREA2 reg */
226227

@@ -302,6 +303,17 @@ static void dwcmshc_reset(struct sdhci_host *host, u8 mask)
302303
sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
303304
}
304305

306+
static void dwcmshc_set_clock(struct sdhci_host *host, unsigned int clock)
307+
{
308+
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
309+
struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
310+
311+
if (priv->sdio_clk)
312+
clk_set_rate(priv->sdio_clk, clock);
313+
314+
sdhci_set_clock(host, clock);
315+
}
316+
305317
static unsigned int dwcmshc_get_max_clock(struct sdhci_host *host)
306318
{
307319
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -1143,10 +1155,11 @@ static int sg2042_init(struct device *dev, struct sdhci_host *host,
11431155
}
11441156

11451157
static const struct sdhci_ops sdhci_dwcmshc_ops = {
1146-
.set_clock = sdhci_set_clock,
1158+
.set_clock = dwcmshc_set_clock,
11471159
.set_bus_width = sdhci_set_bus_width,
11481160
.set_uhs_signaling = dwcmshc_set_uhs_signaling,
11491161
.get_max_clock = dwcmshc_get_max_clock,
1162+
.get_timeout_clock = sdhci_pltfm_clk_get_timeout_clock,
11501163
.reset = dwcmshc_reset,
11511164
.adma_write_desc = dwcmshc_adma_write_desc,
11521165
.irq = dwcmshc_cqe_irq_handler,
@@ -1219,8 +1232,10 @@ static const struct sdhci_ops sdhci_dwcmshc_sg2042_ops = {
12191232
static const struct dwcmshc_pltfm_data sdhci_dwcmshc_pdata = {
12201233
.pdata = {
12211234
.ops = &sdhci_dwcmshc_ops,
1222-
.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
1223-
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
1235+
.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
1236+
SDHCI_QUIRK_BROKEN_CARD_DETECTION,
1237+
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
1238+
SDHCI_QUIRK2_BROKEN_HS200,
12241239
},
12251240
};
12261241

@@ -1235,6 +1250,15 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc_bf3_pdata = {
12351250
};
12361251
#endif
12371252

1253+
static const struct sdhci_pltfm_data sdhci_dwcmshc_rp1_pdata = {
1254+
.ops = &sdhci_dwcmshc_ops,
1255+
.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
1256+
SDHCI_QUIRK_BROKEN_CARD_DETECTION,
1257+
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
1258+
SDHCI_QUIRK2_BROKEN_HS200 |
1259+
SDHCI_QUIRK2_SPURIOUS_INT_RESP,
1260+
};
1261+
12381262
static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk35xx_pdata = {
12391263
.pdata = {
12401264
.ops = &sdhci_dwcmshc_rk35xx_ops,
@@ -1357,6 +1381,10 @@ static void dwcmshc_cqhci_init(struct sdhci_host *host, struct platform_device *
13571381
}
13581382

13591383
static const struct of_device_id sdhci_dwcmshc_dt_ids[] = {
1384+
{
1385+
.compatible = "raspberrypi,rp1-dwcmshc",
1386+
.data = &sdhci_dwcmshc_rp1_pdata,
1387+
},
13601388
{
13611389
.compatible = "rockchip,rk3588-dwcmshc",
13621390
.data = &sdhci_dwcmshc_rk35xx_pdata,
@@ -1450,13 +1478,32 @@ static int dwcmshc_probe(struct platform_device *pdev)
14501478
priv->bus_clk = devm_clk_get(dev, "bus");
14511479
if (!IS_ERR(priv->bus_clk))
14521480
clk_prepare_enable(priv->bus_clk);
1481+
1482+
pltfm_host->timeout_clk = devm_clk_get(dev, "timeout");
1483+
if (!IS_ERR(pltfm_host->timeout_clk))
1484+
err = clk_prepare_enable(pltfm_host->timeout_clk);
1485+
if (err)
1486+
goto free_pltfm;
1487+
1488+
priv->sdio_clk = devm_clk_get_optional(&pdev->dev, "sdio");
1489+
}
1490+
1491+
pltfm_host->timeout_clk = devm_clk_get(&pdev->dev, "timeout");
1492+
if (IS_ERR(pltfm_host->timeout_clk)) {
1493+
err = PTR_ERR(pltfm_host->timeout_clk);
1494+
dev_err(&pdev->dev, "failed to get timeout clk: %d\n", err);
1495+
goto free_pltfm;
14531496
}
1497+
err = clk_prepare_enable(pltfm_host->timeout_clk);
1498+
if (err)
1499+
goto free_pltfm;
14541500

14551501
err = mmc_of_parse(host->mmc);
14561502
if (err)
14571503
goto err_clk;
14581504

14591505
sdhci_get_of_property(pdev);
1506+
sdhci_enable_v4_mode(host);
14601507

14611508
priv->vendor_specific_area1 =
14621509
sdhci_readl(host, DWCMSHC_P_VENDOR_AREA1) & DWCMSHC_AREA1_MASK;
@@ -1516,6 +1563,7 @@ static int dwcmshc_probe(struct platform_device *pdev)
15161563
pm_runtime_put_noidle(dev);
15171564
err_clk:
15181565
clk_disable_unprepare(pltfm_host->clk);
1566+
clk_disable_unprepare(pltfm_host->timeout_clk);
15191567
clk_disable_unprepare(priv->bus_clk);
15201568
clk_bulk_disable_unprepare(priv->num_other_clks, priv->other_clks);
15211569
free_pltfm:

drivers/mmc/host/sdhci-pltfm.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host)
3232
}
3333
EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
3434

35+
unsigned int sdhci_pltfm_clk_get_timeout_clock(struct sdhci_host *host)
36+
{
37+
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
38+
39+
return clk_get_rate(pltfm_host->timeout_clk);
40+
}
41+
EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_timeout_clock);
42+
3543
static const struct sdhci_ops sdhci_pltfm_ops = {
3644
.set_clock = sdhci_set_clock,
3745
.set_bus_width = sdhci_set_bus_width,

drivers/mmc/host/sdhci-pltfm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct sdhci_pltfm_data {
2020

2121
struct sdhci_pltfm_host {
2222
struct clk *clk;
23+
struct clk *timeout_clk;
2324

2425
/* migrate from sdhci_of_host */
2526
unsigned int clock;
@@ -106,6 +107,8 @@ extern void sdhci_pltfm_remove(struct platform_device *pdev);
106107

107108
extern unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host);
108109

110+
extern unsigned int sdhci_pltfm_clk_get_timeout_clock(struct sdhci_host *host);
111+
109112
static inline void *sdhci_pltfm_priv(struct sdhci_pltfm_host *host)
110113
{
111114
return host->private;

0 commit comments

Comments
 (0)