]> Git Repo - J-linux.git/blob - drivers/mmc/host/sdhci-of-ma35d1.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / mmc / host / sdhci-of-ma35d1.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2024 Nuvoton Technology Corp.
4  *
5  * Author: Shan-Chun Hung <[email protected]>
6  */
7
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>
31
32 #include "sdhci-pltfm.h"
33 #include "sdhci.h"
34
35 #define MA35_SYS_MISCFCR0       0x070
36 #define MA35_SDHCI_MSHCCTL      0x508
37 #define MA35_SDHCI_MBIUCTL      0x510
38
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)
43
44 struct ma35_priv {
45         struct reset_control    *rst;
46         struct pinctrl          *pinctrl;
47         struct pinctrl_state    *pins_uhs;
48         struct pinctrl_state    *pins_default;
49 };
50
51 struct ma35_restore_data {
52         u32     reg;
53         u32     width;
54 };
55
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)},
66 };
67
68 /*
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.
71  */
72 static void ma35_adma_write_desc(struct sdhci_host *host, void **desc, dma_addr_t addr, int len,
73                                  unsigned int cmd)
74 {
75         int tmplen, offset;
76
77         if (likely(!len || (ALIGN(addr, SZ_128M) == ALIGN(addr + len - 1, SZ_128M)))) {
78                 sdhci_adma_write_desc(host, desc, addr, len, cmd);
79                 return;
80         }
81
82         offset = addr & (SZ_128M - 1);
83         tmplen = SZ_128M - offset;
84         sdhci_adma_write_desc(host, desc, addr, tmplen, cmd);
85
86         addr += tmplen;
87         len -= tmplen;
88         sdhci_adma_write_desc(host, desc, addr, len, cmd);
89 }
90
91 static void ma35_set_clock(struct sdhci_host *host, unsigned int clock)
92 {
93         u32 ctl;
94
95         /*
96          * If the clock frequency exceeds MMC_HIGH_52_MAX_DTR,
97          * disable command conflict check.
98          */
99         ctl = sdhci_readw(host, MA35_SDHCI_MSHCCTL);
100         if (clock > MMC_HIGH_52_MAX_DTR)
101                 ctl &= ~MA35_SDHCI_CMD_CONFLICT_CHK;
102         else
103                 ctl |= MA35_SDHCI_CMD_CONFLICT_CHK;
104         sdhci_writew(host, ctl, MA35_SDHCI_MSHCCTL);
105
106         sdhci_set_clock(host, clock);
107 }
108
109 static int ma35_start_signal_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
110 {
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);
114
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);
119                 break;
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);
123                 break;
124         default:
125                 dev_err(mmc_dev(host->mmc), "Unsupported signal voltage!\n");
126                 return -EINVAL;
127         }
128
129         return sdhci_start_signal_voltage_switch(mmc, ios);
130 }
131
132 static void ma35_voltage_switch(struct sdhci_host *host)
133 {
134         /* Wait for 5ms after set 1.8V signal enable bit */
135         fsleep(5000);
136 }
137
138 static int ma35_execute_tuning(struct mmc_host *mmc, u32 opcode)
139 {
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);
143         int idx;
144         u32 regs[ARRAY_SIZE(restore_data)] = {};
145
146         /*
147          * Limitations require a reset of SD/eMMC before tuning and
148          * saving the registers before resetting, then restoring
149          * after the reset.
150          */
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);
158         }
159
160         reset_control_assert(priv->rst);
161         reset_control_deassert(priv->rst);
162
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);
170         }
171
172         return sdhci_execute_tuning(mmc, opcode);
173 }
174
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,
183 };
184
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,
190 };
191
192 static int ma35_probe(struct platform_device *pdev)
193 {
194         struct device *dev = &pdev->dev;
195         struct sdhci_pltfm_host *pltfm_host;
196         struct sdhci_host *host;
197         struct ma35_priv *priv;
198         int err;
199         u32 extra, ctl;
200
201         host = sdhci_pltfm_init(pdev, &sdhci_ma35_pdata, sizeof(struct ma35_priv));
202         if (IS_ERR(host))
203                 return PTR_ERR(host);
204
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);
208
209         host->adma_table_cnt += extra;
210         pltfm_host = sdhci_priv(host);
211         priv = sdhci_pltfm_priv(pltfm_host);
212
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");
216                 goto err_sdhci;
217         }
218
219         err = mmc_of_parse(host->mmc);
220         if (err)
221                 goto err_sdhci;
222
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");
226                 goto err_sdhci;
227         }
228
229         sdhci_get_of_property(pdev);
230
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);
236         }
237
238         if (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V)) {
239                 struct regmap   *regmap;
240                 u32             reg;
241
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, &reg);
246                         reg |= BIT(17);
247                         regmap_write(regmap, MA35_SYS_MISCFCR0, reg);
248                 }
249
250                 host->mmc_host_ops.start_signal_voltage_switch =
251                                         ma35_start_signal_voltage_switch;
252         }
253
254         host->mmc_host_ops.execute_tuning = ma35_execute_tuning;
255
256         err = sdhci_add_host(host);
257         if (err)
258                 goto err_sdhci;
259
260         /*
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.
264          */
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);
269
270         return 0;
271
272 err_sdhci:
273         sdhci_pltfm_free(pdev);
274         return err;
275 }
276
277 static void ma35_disable_card_clk(struct sdhci_host *host)
278 {
279         u16 ctrl;
280
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);
285         }
286 }
287
288 static void ma35_remove(struct platform_device *pdev)
289 {
290         struct sdhci_host *host = platform_get_drvdata(pdev);
291
292         sdhci_remove_host(host, 0);
293         ma35_disable_card_clk(host);
294         sdhci_pltfm_free(pdev);
295 }
296
297 static const struct of_device_id sdhci_ma35_dt_ids[] = {
298         { .compatible = "nuvoton,ma35d1-sdhci" },
299         {}
300 };
301
302 static struct platform_driver sdhci_ma35_driver = {
303         .driver = {
304                 .name   = "sdhci-ma35",
305                 .of_match_table = sdhci_ma35_dt_ids,
306         },
307         .probe  = ma35_probe,
308         .remove = ma35_remove,
309 };
310 module_platform_driver(sdhci_ma35_driver);
311
312 MODULE_DESCRIPTION("SDHCI platform driver for Nuvoton MA35");
313 MODULE_AUTHOR("Shan-Chun Hung <[email protected]>");
314 MODULE_LICENSE("GPL");
This page took 0.04345 seconds and 4 git commands to generate.