1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2024 Nuvoton Technology Corp.
5 * Author: Shan-Chun Hung <shanchun1218@gmail.com>
8 #include <linux/align.h>
9 #include <linux/array_size.h>
10 #include <linux/bits.h>
11 #include <linux/build_bug.h>
12 #include <linux/clk.h>
13 #include <linux/delay.h>
14 #include <linux/dev_printk.h>
15 #include <linux/device.h>
16 #include <linux/dma-mapping.h>
17 #include <linux/err.h>
18 #include <linux/math.h>
19 #include <linux/mfd/syscon.h>
20 #include <linux/minmax.h>
21 #include <linux/mmc/card.h>
22 #include <linux/mmc/host.h>
23 #include <linux/mod_devicetable.h>
24 #include <linux/module.h>
25 #include <linux/pinctrl/consumer.h>
26 #include <linux/platform_device.h>
27 #include <linux/regmap.h>
28 #include <linux/reset.h>
29 #include <linux/sizes.h>
30 #include <linux/types.h>
32 #include "sdhci-pltfm.h"
35 #define MA35_SYS_MISCFCR0 0x070
36 #define MA35_SDHCI_MSHCCTL 0x508
37 #define MA35_SDHCI_MBIUCTL 0x510
39 #define MA35_SDHCI_CMD_CONFLICT_CHK BIT(0)
40 #define MA35_SDHCI_INCR_MSK GENMASK(3, 0)
41 #define MA35_SDHCI_INCR16 BIT(3)
42 #define MA35_SDHCI_INCR8 BIT(2)
45 struct reset_control
*rst
;
46 struct pinctrl
*pinctrl
;
47 struct pinctrl_state
*pins_uhs
;
48 struct pinctrl_state
*pins_default
;
51 struct ma35_restore_data
{
56 static const struct ma35_restore_data restore_data
[] = {
57 { SDHCI_CLOCK_CONTROL
, sizeof(u32
)},
58 { SDHCI_BLOCK_SIZE
, sizeof(u32
)},
59 { SDHCI_INT_ENABLE
, sizeof(u32
)},
60 { SDHCI_SIGNAL_ENABLE
, sizeof(u32
)},
61 { SDHCI_AUTO_CMD_STATUS
, sizeof(u32
)},
62 { SDHCI_HOST_CONTROL
, sizeof(u32
)},
63 { SDHCI_TIMEOUT_CONTROL
, sizeof(u8
) },
64 { MA35_SDHCI_MSHCCTL
, sizeof(u16
)},
65 { MA35_SDHCI_MBIUCTL
, sizeof(u16
)},
69 * If DMA addr spans 128MB boundary, we split the DMA transfer into two
70 * so that each DMA transfer doesn't exceed the boundary.
72 static void ma35_adma_write_desc(struct sdhci_host
*host
, void **desc
, dma_addr_t addr
, int len
,
77 if (likely(!len
|| (ALIGN(addr
, SZ_128M
) == ALIGN(addr
+ len
- 1, SZ_128M
)))) {
78 sdhci_adma_write_desc(host
, desc
, addr
, len
, cmd
);
82 offset
= addr
& (SZ_128M
- 1);
83 tmplen
= SZ_128M
- offset
;
84 sdhci_adma_write_desc(host
, desc
, addr
, tmplen
, cmd
);
88 sdhci_adma_write_desc(host
, desc
, addr
, len
, cmd
);
91 static void ma35_set_clock(struct sdhci_host
*host
, unsigned int clock
)
96 * If the clock frequency exceeds MMC_HIGH_52_MAX_DTR,
97 * disable command conflict check.
99 ctl
= sdhci_readw(host
, MA35_SDHCI_MSHCCTL
);
100 if (clock
> MMC_HIGH_52_MAX_DTR
)
101 ctl
&= ~MA35_SDHCI_CMD_CONFLICT_CHK
;
103 ctl
|= MA35_SDHCI_CMD_CONFLICT_CHK
;
104 sdhci_writew(host
, ctl
, MA35_SDHCI_MSHCCTL
);
106 sdhci_set_clock(host
, clock
);
109 static int ma35_start_signal_voltage_switch(struct mmc_host
*mmc
, struct mmc_ios
*ios
)
111 struct sdhci_host
*host
= mmc_priv(mmc
);
112 struct sdhci_pltfm_host
*pltfm_host
= sdhci_priv(host
);
113 struct ma35_priv
*priv
= sdhci_pltfm_priv(pltfm_host
);
115 switch (ios
->signal_voltage
) {
116 case MMC_SIGNAL_VOLTAGE_180
:
117 if (!IS_ERR(priv
->pinctrl
) && !IS_ERR(priv
->pins_uhs
))
118 pinctrl_select_state(priv
->pinctrl
, priv
->pins_uhs
);
120 case MMC_SIGNAL_VOLTAGE_330
:
121 if (!IS_ERR(priv
->pinctrl
) && !IS_ERR(priv
->pins_default
))
122 pinctrl_select_state(priv
->pinctrl
, priv
->pins_default
);
125 dev_err(mmc_dev(host
->mmc
), "Unsupported signal voltage!\n");
129 return sdhci_start_signal_voltage_switch(mmc
, ios
);
132 static void ma35_voltage_switch(struct sdhci_host
*host
)
134 /* Wait for 5ms after set 1.8V signal enable bit */
138 static int ma35_execute_tuning(struct mmc_host
*mmc
, u32 opcode
)
140 struct sdhci_host
*host
= mmc_priv(mmc
);
141 struct sdhci_pltfm_host
*pltfm_host
= sdhci_priv(host
);
142 struct ma35_priv
*priv
= sdhci_pltfm_priv(pltfm_host
);
144 u32 regs
[ARRAY_SIZE(restore_data
)] = {};
147 * Limitations require a reset of SD/eMMC before tuning and
148 * saving the registers before resetting, then restoring
151 for (idx
= 0; idx
< ARRAY_SIZE(restore_data
); idx
++) {
152 if (restore_data
[idx
].width
== sizeof(u32
))
153 regs
[idx
] = sdhci_readl(host
, restore_data
[idx
].reg
);
154 else if (restore_data
[idx
].width
== sizeof(u16
))
155 regs
[idx
] = sdhci_readw(host
, restore_data
[idx
].reg
);
156 else if (restore_data
[idx
].width
== sizeof(u8
))
157 regs
[idx
] = sdhci_readb(host
, restore_data
[idx
].reg
);
160 reset_control_assert(priv
->rst
);
161 reset_control_deassert(priv
->rst
);
163 for (idx
= 0; idx
< ARRAY_SIZE(restore_data
); idx
++) {
164 if (restore_data
[idx
].width
== sizeof(u32
))
165 sdhci_writel(host
, regs
[idx
], restore_data
[idx
].reg
);
166 else if (restore_data
[idx
].width
== sizeof(u16
))
167 sdhci_writew(host
, regs
[idx
], restore_data
[idx
].reg
);
168 else if (restore_data
[idx
].width
== sizeof(u8
))
169 sdhci_writeb(host
, regs
[idx
], restore_data
[idx
].reg
);
172 return sdhci_execute_tuning(mmc
, opcode
);
175 static const struct sdhci_ops sdhci_ma35_ops
= {
176 .set_clock
= ma35_set_clock
,
177 .set_bus_width
= sdhci_set_bus_width
,
178 .set_uhs_signaling
= sdhci_set_uhs_signaling
,
179 .get_max_clock
= sdhci_pltfm_clk_get_max_clock
,
180 .reset
= sdhci_reset
,
181 .adma_write_desc
= ma35_adma_write_desc
,
182 .voltage_switch
= ma35_voltage_switch
,
185 static const struct sdhci_pltfm_data sdhci_ma35_pdata
= {
186 .ops
= &sdhci_ma35_ops
,
187 .quirks
= SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN
,
188 .quirks2
= SDHCI_QUIRK2_PRESET_VALUE_BROKEN
| SDHCI_QUIRK2_BROKEN_DDR50
|
189 SDHCI_QUIRK2_ACMD23_BROKEN
,
192 static int ma35_probe(struct platform_device
*pdev
)
194 struct device
*dev
= &pdev
->dev
;
195 struct sdhci_pltfm_host
*pltfm_host
;
196 struct sdhci_host
*host
;
197 struct ma35_priv
*priv
;
201 host
= sdhci_pltfm_init(pdev
, &sdhci_ma35_pdata
, sizeof(struct ma35_priv
));
203 return PTR_ERR(host
);
205 /* Extra adma table cnt for cross 128M boundary handling. */
206 extra
= DIV_ROUND_UP_ULL(dma_get_required_mask(dev
), SZ_128M
);
207 extra
= min(extra
, SDHCI_MAX_SEGS
);
209 host
->adma_table_cnt
+= extra
;
210 pltfm_host
= sdhci_priv(host
);
211 priv
= sdhci_pltfm_priv(pltfm_host
);
213 pltfm_host
->clk
= devm_clk_get_optional_enabled(dev
, NULL
);
214 if (IS_ERR(pltfm_host
->clk
)) {
215 err
= dev_err_probe(dev
, PTR_ERR(pltfm_host
->clk
), "failed to get clk\n");
219 err
= mmc_of_parse(host
->mmc
);
223 priv
->rst
= devm_reset_control_get_exclusive(dev
, NULL
);
224 if (IS_ERR(priv
->rst
)) {
225 err
= dev_err_probe(dev
, PTR_ERR(priv
->rst
), "failed to get reset control\n");
229 sdhci_get_of_property(pdev
);
231 priv
->pinctrl
= devm_pinctrl_get(dev
);
232 if (!IS_ERR(priv
->pinctrl
)) {
233 priv
->pins_default
= pinctrl_lookup_state(priv
->pinctrl
, "default");
234 priv
->pins_uhs
= pinctrl_lookup_state(priv
->pinctrl
, "state_uhs");
235 pinctrl_select_state(priv
->pinctrl
, priv
->pins_default
);
238 if (!(host
->quirks2
& SDHCI_QUIRK2_NO_1_8_V
)) {
239 struct regmap
*regmap
;
242 regmap
= syscon_regmap_lookup_by_phandle(dev_of_node(dev
), "nuvoton,sys");
243 if (!IS_ERR(regmap
)) {
244 /* Enable SDHCI voltage stable for 1.8V */
245 regmap_read(regmap
, MA35_SYS_MISCFCR0
, ®
);
247 regmap_write(regmap
, MA35_SYS_MISCFCR0
, reg
);
250 host
->mmc_host_ops
.start_signal_voltage_switch
=
251 ma35_start_signal_voltage_switch
;
254 host
->mmc_host_ops
.execute_tuning
= ma35_execute_tuning
;
256 err
= sdhci_add_host(host
);
261 * Split data into chunks of 16 or 8 bytes for transmission.
262 * Each chunk transfer is guaranteed to be uninterrupted on the bus.
263 * This likely corresponds to the AHB bus DMA burst size.
265 ctl
= sdhci_readw(host
, MA35_SDHCI_MBIUCTL
);
266 ctl
&= ~MA35_SDHCI_INCR_MSK
;
267 ctl
|= MA35_SDHCI_INCR16
| MA35_SDHCI_INCR8
;
268 sdhci_writew(host
, ctl
, MA35_SDHCI_MBIUCTL
);
273 sdhci_pltfm_free(pdev
);
277 static void ma35_disable_card_clk(struct sdhci_host
*host
)
281 ctrl
= sdhci_readw(host
, SDHCI_CLOCK_CONTROL
);
282 if (ctrl
& SDHCI_CLOCK_CARD_EN
) {
283 ctrl
&= ~SDHCI_CLOCK_CARD_EN
;
284 sdhci_writew(host
, ctrl
, SDHCI_CLOCK_CONTROL
);
288 static void ma35_remove(struct platform_device
*pdev
)
290 struct sdhci_host
*host
= platform_get_drvdata(pdev
);
292 sdhci_remove_host(host
, 0);
293 ma35_disable_card_clk(host
);
294 sdhci_pltfm_free(pdev
);
297 static const struct of_device_id sdhci_ma35_dt_ids
[] = {
298 { .compatible
= "nuvoton,ma35d1-sdhci" },
302 static struct platform_driver sdhci_ma35_driver
= {
304 .name
= "sdhci-ma35",
305 .of_match_table
= sdhci_ma35_dt_ids
,
308 .remove
= ma35_remove
,
310 module_platform_driver(sdhci_ma35_driver
);
312 MODULE_DESCRIPTION("SDHCI platform driver for Nuvoton MA35");
313 MODULE_AUTHOR("Shan-Chun Hung <shanchun1218@gmail.com>");
314 MODULE_LICENSE("GPL");