xref: /openbmc/linux/drivers/mmc/host/sdhci-iproc.c (revision d2f4a190)
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright (C) 2014 Broadcom Corporation
3 
4 /*
5  * iProc SDHCI platform driver
6  */
7 
8 #include <linux/acpi.h>
9 #include <linux/delay.h>
10 #include <linux/module.h>
11 #include <linux/mmc/host.h>
12 #include <linux/of.h>
13 #include <linux/of_device.h>
14 #include "sdhci-pltfm.h"
15 
16 struct sdhci_iproc_data {
17 	const struct sdhci_pltfm_data *pdata;
18 	u32 caps;
19 	u32 caps1;
20 	u32 mmc_caps;
21 	bool missing_caps;
22 };
23 
24 struct sdhci_iproc_host {
25 	const struct sdhci_iproc_data *data;
26 	u32 shadow_cmd;
27 	u32 shadow_blk;
28 	bool is_cmd_shadowed;
29 	bool is_blk_shadowed;
30 };
31 
32 #define REG_OFFSET_IN_BITS(reg) ((reg) << 3 & 0x18)
33 
34 static inline u32 sdhci_iproc_readl(struct sdhci_host *host, int reg)
35 {
36 	u32 val = readl(host->ioaddr + reg);
37 
38 	pr_debug("%s: readl [0x%02x] 0x%08x\n",
39 		 mmc_hostname(host->mmc), reg, val);
40 	return val;
41 }
42 
43 static u16 sdhci_iproc_readw(struct sdhci_host *host, int reg)
44 {
45 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
46 	struct sdhci_iproc_host *iproc_host = sdhci_pltfm_priv(pltfm_host);
47 	u32 val;
48 	u16 word;
49 
50 	if ((reg == SDHCI_TRANSFER_MODE) && iproc_host->is_cmd_shadowed) {
51 		/* Get the saved transfer mode */
52 		val = iproc_host->shadow_cmd;
53 	} else if ((reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) &&
54 		   iproc_host->is_blk_shadowed) {
55 		/* Get the saved block info */
56 		val = iproc_host->shadow_blk;
57 	} else {
58 		val = sdhci_iproc_readl(host, (reg & ~3));
59 	}
60 	word = val >> REG_OFFSET_IN_BITS(reg) & 0xffff;
61 	return word;
62 }
63 
64 static u8 sdhci_iproc_readb(struct sdhci_host *host, int reg)
65 {
66 	u32 val = sdhci_iproc_readl(host, (reg & ~3));
67 	u8 byte = val >> REG_OFFSET_IN_BITS(reg) & 0xff;
68 	return byte;
69 }
70 
71 static inline void sdhci_iproc_writel(struct sdhci_host *host, u32 val, int reg)
72 {
73 	pr_debug("%s: writel [0x%02x] 0x%08x\n",
74 		 mmc_hostname(host->mmc), reg, val);
75 
76 	writel(val, host->ioaddr + reg);
77 
78 	if (host->clock <= 400000) {
79 		/* Round up to micro-second four SD clock delay */
80 		if (host->clock)
81 			udelay((4 * 1000000 + host->clock - 1) / host->clock);
82 		else
83 			udelay(10);
84 	}
85 }
86 
87 /*
88  * The Arasan has a bugette whereby it may lose the content of successive
89  * writes to the same register that are within two SD-card clock cycles of
90  * each other (a clock domain crossing problem). The data
91  * register does not have this problem, which is just as well - otherwise we'd
92  * have to nobble the DMA engine too.
93  *
94  * This wouldn't be a problem with the code except that we can only write the
95  * controller with 32-bit writes.  So two different 16-bit registers are
96  * written back to back creates the problem.
97  *
98  * In reality, this only happens when SDHCI_BLOCK_SIZE and SDHCI_BLOCK_COUNT
99  * are written followed by SDHCI_TRANSFER_MODE and SDHCI_COMMAND.
100  * The BLOCK_SIZE and BLOCK_COUNT are meaningless until a command issued so
101  * the work around can be further optimized. We can keep shadow values of
102  * BLOCK_SIZE, BLOCK_COUNT, and TRANSFER_MODE until a COMMAND is issued.
103  * Then, write the BLOCK_SIZE+BLOCK_COUNT in a single 32-bit write followed
104  * by the TRANSFER+COMMAND in another 32-bit write.
105  */
106 static void sdhci_iproc_writew(struct sdhci_host *host, u16 val, int reg)
107 {
108 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
109 	struct sdhci_iproc_host *iproc_host = sdhci_pltfm_priv(pltfm_host);
110 	u32 word_shift = REG_OFFSET_IN_BITS(reg);
111 	u32 mask = 0xffff << word_shift;
112 	u32 oldval, newval;
113 
114 	if (reg == SDHCI_COMMAND) {
115 		/* Write the block now as we are issuing a command */
116 		if (iproc_host->is_blk_shadowed) {
117 			sdhci_iproc_writel(host, iproc_host->shadow_blk,
118 				SDHCI_BLOCK_SIZE);
119 			iproc_host->is_blk_shadowed = false;
120 		}
121 		oldval = iproc_host->shadow_cmd;
122 		iproc_host->is_cmd_shadowed = false;
123 	} else if ((reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) &&
124 		   iproc_host->is_blk_shadowed) {
125 		/* Block size and count are stored in shadow reg */
126 		oldval = iproc_host->shadow_blk;
127 	} else {
128 		/* Read reg, all other registers are not shadowed */
129 		oldval = sdhci_iproc_readl(host, (reg & ~3));
130 	}
131 	newval = (oldval & ~mask) | (val << word_shift);
132 
133 	if (reg == SDHCI_TRANSFER_MODE) {
134 		/* Save the transfer mode until the command is issued */
135 		iproc_host->shadow_cmd = newval;
136 		iproc_host->is_cmd_shadowed = true;
137 	} else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) {
138 		/* Save the block info until the command is issued */
139 		iproc_host->shadow_blk = newval;
140 		iproc_host->is_blk_shadowed = true;
141 	} else {
142 		/* Command or other regular 32-bit write */
143 		sdhci_iproc_writel(host, newval, reg & ~3);
144 	}
145 }
146 
147 static void sdhci_iproc_writeb(struct sdhci_host *host, u8 val, int reg)
148 {
149 	u32 oldval = sdhci_iproc_readl(host, (reg & ~3));
150 	u32 byte_shift = REG_OFFSET_IN_BITS(reg);
151 	u32 mask = 0xff << byte_shift;
152 	u32 newval = (oldval & ~mask) | (val << byte_shift);
153 
154 	sdhci_iproc_writel(host, newval, reg & ~3);
155 }
156 
157 static unsigned int sdhci_iproc_get_max_clock(struct sdhci_host *host)
158 {
159 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
160 
161 	if (pltfm_host->clk)
162 		return sdhci_pltfm_clk_get_max_clock(host);
163 	else
164 		return pltfm_host->clock;
165 }
166 
167 /*
168  * There is a known bug on BCM2711's SDHCI core integration where the
169  * controller will hang when the difference between the core clock and the bus
170  * clock is too great. Specifically this can be reproduced under the following
171  * conditions:
172  *
173  *  - No SD card plugged in, polling thread is running, probing cards at
174  *    100 kHz.
175  *  - BCM2711's core clock configured at 500MHz or more
176  *
177  * So we set 200kHz as the minimum clock frequency available for that SoC.
178  */
179 static unsigned int sdhci_iproc_bcm2711_get_min_clock(struct sdhci_host *host)
180 {
181 	return 200000;
182 }
183 
184 static const struct sdhci_ops sdhci_iproc_ops = {
185 	.set_clock = sdhci_set_clock,
186 	.get_max_clock = sdhci_iproc_get_max_clock,
187 	.set_bus_width = sdhci_set_bus_width,
188 	.reset = sdhci_reset,
189 	.set_uhs_signaling = sdhci_set_uhs_signaling,
190 };
191 
192 static const struct sdhci_ops sdhci_iproc_32only_ops = {
193 	.read_l = sdhci_iproc_readl,
194 	.read_w = sdhci_iproc_readw,
195 	.read_b = sdhci_iproc_readb,
196 	.write_l = sdhci_iproc_writel,
197 	.write_w = sdhci_iproc_writew,
198 	.write_b = sdhci_iproc_writeb,
199 	.set_clock = sdhci_set_clock,
200 	.get_max_clock = sdhci_iproc_get_max_clock,
201 	.set_bus_width = sdhci_set_bus_width,
202 	.reset = sdhci_reset,
203 	.set_uhs_signaling = sdhci_set_uhs_signaling,
204 };
205 
206 static const struct sdhci_pltfm_data sdhci_iproc_cygnus_pltfm_data = {
207 	.quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
208 		  SDHCI_QUIRK_NO_HISPD_BIT,
209 	.quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN | SDHCI_QUIRK2_HOST_OFF_CARD_ON,
210 	.ops = &sdhci_iproc_32only_ops,
211 };
212 
213 static const struct sdhci_iproc_data iproc_cygnus_data = {
214 	.pdata = &sdhci_iproc_cygnus_pltfm_data,
215 	.caps = ((0x1 << SDHCI_MAX_BLOCK_SHIFT)
216 			& SDHCI_MAX_BLOCK_MASK) |
217 		SDHCI_CAN_VDD_330 |
218 		SDHCI_CAN_VDD_180 |
219 		SDHCI_CAN_DO_SUSPEND |
220 		SDHCI_CAN_DO_HISPD |
221 		SDHCI_CAN_DO_ADMA2 |
222 		SDHCI_CAN_DO_SDMA,
223 	.caps1 = SDHCI_DRIVER_TYPE_C |
224 		 SDHCI_DRIVER_TYPE_D |
225 		 SDHCI_SUPPORT_DDR50,
226 	.mmc_caps = MMC_CAP_1_8V_DDR,
227 };
228 
229 static const struct sdhci_pltfm_data sdhci_iproc_pltfm_data = {
230 	.quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
231 		  SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
232 		  SDHCI_QUIRK_NO_HISPD_BIT,
233 	.quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN,
234 	.ops = &sdhci_iproc_ops,
235 };
236 
237 static const struct sdhci_iproc_data iproc_data = {
238 	.pdata = &sdhci_iproc_pltfm_data,
239 	.caps = ((0x1 << SDHCI_MAX_BLOCK_SHIFT)
240 			& SDHCI_MAX_BLOCK_MASK) |
241 		SDHCI_CAN_VDD_330 |
242 		SDHCI_CAN_VDD_180 |
243 		SDHCI_CAN_DO_SUSPEND |
244 		SDHCI_CAN_DO_HISPD |
245 		SDHCI_CAN_DO_ADMA2 |
246 		SDHCI_CAN_DO_SDMA,
247 	.caps1 = SDHCI_DRIVER_TYPE_C |
248 		 SDHCI_DRIVER_TYPE_D |
249 		 SDHCI_SUPPORT_DDR50,
250 };
251 
252 static const struct sdhci_pltfm_data sdhci_bcm2835_pltfm_data = {
253 	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
254 		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
255 		  SDHCI_QUIRK_NO_HISPD_BIT,
256 	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
257 	.ops = &sdhci_iproc_32only_ops,
258 };
259 
260 static const struct sdhci_iproc_data bcm2835_data = {
261 	.pdata = &sdhci_bcm2835_pltfm_data,
262 	.caps = ((0x1 << SDHCI_MAX_BLOCK_SHIFT)
263 			& SDHCI_MAX_BLOCK_MASK) |
264 		SDHCI_CAN_VDD_330 |
265 		SDHCI_CAN_DO_HISPD,
266 	.caps1 = SDHCI_DRIVER_TYPE_A |
267 		 SDHCI_DRIVER_TYPE_C,
268 	.mmc_caps = 0x00000000,
269 	.missing_caps = true,
270 };
271 
272 static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
273 	.read_l = sdhci_iproc_readl,
274 	.read_w = sdhci_iproc_readw,
275 	.read_b = sdhci_iproc_readb,
276 	.write_l = sdhci_iproc_writel,
277 	.write_w = sdhci_iproc_writew,
278 	.write_b = sdhci_iproc_writeb,
279 	.set_clock = sdhci_set_clock,
280 	.set_power = sdhci_set_power_and_bus_voltage,
281 	.get_max_clock = sdhci_iproc_get_max_clock,
282 	.get_min_clock = sdhci_iproc_bcm2711_get_min_clock,
283 	.set_bus_width = sdhci_set_bus_width,
284 	.reset = sdhci_reset,
285 	.set_uhs_signaling = sdhci_set_uhs_signaling,
286 };
287 
288 static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
289 	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
290 	.ops = &sdhci_iproc_bcm2711_ops,
291 };
292 
293 static const struct sdhci_iproc_data bcm2711_data = {
294 	.pdata = &sdhci_bcm2711_pltfm_data,
295 	.mmc_caps = MMC_CAP_3_3V_DDR,
296 };
297 
298 static const struct sdhci_pltfm_data sdhci_bcm7211a0_pltfm_data = {
299 	.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
300 		SDHCI_QUIRK_BROKEN_DMA |
301 		SDHCI_QUIRK_BROKEN_ADMA,
302 	.ops = &sdhci_iproc_ops,
303 };
304 
305 #define BCM7211A0_BASE_CLK_MHZ 100
306 static const struct sdhci_iproc_data bcm7211a0_data = {
307 	.pdata = &sdhci_bcm7211a0_pltfm_data,
308 	.caps = ((BCM7211A0_BASE_CLK_MHZ / 2) << SDHCI_TIMEOUT_CLK_SHIFT) |
309 		(BCM7211A0_BASE_CLK_MHZ << SDHCI_CLOCK_BASE_SHIFT) |
310 		((0x2 << SDHCI_MAX_BLOCK_SHIFT)
311 			& SDHCI_MAX_BLOCK_MASK) |
312 		SDHCI_CAN_VDD_330 |
313 		SDHCI_CAN_VDD_180 |
314 		SDHCI_CAN_DO_SUSPEND |
315 		SDHCI_CAN_DO_HISPD,
316 	.caps1 = SDHCI_DRIVER_TYPE_C |
317 		 SDHCI_DRIVER_TYPE_D,
318 	.missing_caps = true,
319 };
320 
321 static const struct of_device_id sdhci_iproc_of_match[] = {
322 	{ .compatible = "brcm,bcm2835-sdhci", .data = &bcm2835_data },
323 	{ .compatible = "brcm,bcm2711-emmc2", .data = &bcm2711_data },
324 	{ .compatible = "brcm,sdhci-iproc-cygnus", .data = &iproc_cygnus_data},
325 	{ .compatible = "brcm,sdhci-iproc", .data = &iproc_data },
326 	{ .compatible = "brcm,bcm7211a0-sdhci", .data = &bcm7211a0_data },
327 	{ }
328 };
329 MODULE_DEVICE_TABLE(of, sdhci_iproc_of_match);
330 
331 #ifdef CONFIG_ACPI
332 /*
333  * This is a duplicate of bcm2835_(pltfrm_)data without caps quirks
334  * which are provided by the ACPI table.
335  */
336 static const struct sdhci_pltfm_data sdhci_bcm_arasan_data = {
337 	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
338 		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
339 		  SDHCI_QUIRK_NO_HISPD_BIT,
340 	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
341 	.ops = &sdhci_iproc_32only_ops,
342 };
343 
344 static const struct sdhci_iproc_data bcm_arasan_data = {
345 	.pdata = &sdhci_bcm_arasan_data,
346 };
347 
348 static const struct acpi_device_id sdhci_iproc_acpi_ids[] = {
349 	{ .id = "BRCM5871", .driver_data = (kernel_ulong_t)&iproc_cygnus_data },
350 	{ .id = "BRCM5872", .driver_data = (kernel_ulong_t)&iproc_data },
351 	{ .id = "BCM2847",  .driver_data = (kernel_ulong_t)&bcm_arasan_data },
352 	{ .id = "BRCME88C", .driver_data = (kernel_ulong_t)&bcm2711_data },
353 	{ /* sentinel */ }
354 };
355 MODULE_DEVICE_TABLE(acpi, sdhci_iproc_acpi_ids);
356 #endif
357 
358 static int sdhci_iproc_probe(struct platform_device *pdev)
359 {
360 	struct device *dev = &pdev->dev;
361 	const struct sdhci_iproc_data *iproc_data = NULL;
362 	struct sdhci_host *host;
363 	struct sdhci_iproc_host *iproc_host;
364 	struct sdhci_pltfm_host *pltfm_host;
365 	int ret;
366 
367 	iproc_data = device_get_match_data(dev);
368 	if (!iproc_data)
369 		return -ENODEV;
370 
371 	host = sdhci_pltfm_init(pdev, iproc_data->pdata, sizeof(*iproc_host));
372 	if (IS_ERR(host))
373 		return PTR_ERR(host);
374 
375 	pltfm_host = sdhci_priv(host);
376 	iproc_host = sdhci_pltfm_priv(pltfm_host);
377 
378 	iproc_host->data = iproc_data;
379 
380 	ret = mmc_of_parse(host->mmc);
381 	if (ret)
382 		goto err;
383 
384 	sdhci_get_property(pdev);
385 
386 	host->mmc->caps |= iproc_host->data->mmc_caps;
387 
388 	if (dev->of_node) {
389 		pltfm_host->clk = devm_clk_get(dev, NULL);
390 		if (IS_ERR(pltfm_host->clk)) {
391 			ret = PTR_ERR(pltfm_host->clk);
392 			goto err;
393 		}
394 		ret = clk_prepare_enable(pltfm_host->clk);
395 		if (ret) {
396 			dev_err(dev, "failed to enable host clk\n");
397 			goto err;
398 		}
399 	}
400 
401 	if (iproc_host->data->missing_caps) {
402 		__sdhci_read_caps(host, NULL,
403 				  &iproc_host->data->caps,
404 				  &iproc_host->data->caps1);
405 	}
406 
407 	ret = sdhci_add_host(host);
408 	if (ret)
409 		goto err_clk;
410 
411 	return 0;
412 
413 err_clk:
414 	if (dev->of_node)
415 		clk_disable_unprepare(pltfm_host->clk);
416 err:
417 	sdhci_pltfm_free(pdev);
418 	return ret;
419 }
420 
421 static void sdhci_iproc_shutdown(struct platform_device *pdev)
422 {
423 	sdhci_pltfm_suspend(&pdev->dev);
424 }
425 
426 static struct platform_driver sdhci_iproc_driver = {
427 	.driver = {
428 		.name = "sdhci-iproc",
429 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
430 		.of_match_table = sdhci_iproc_of_match,
431 		.acpi_match_table = ACPI_PTR(sdhci_iproc_acpi_ids),
432 		.pm = &sdhci_pltfm_pmops,
433 	},
434 	.probe = sdhci_iproc_probe,
435 	.remove = sdhci_pltfm_unregister,
436 	.shutdown = sdhci_iproc_shutdown,
437 };
438 module_platform_driver(sdhci_iproc_driver);
439 
440 MODULE_AUTHOR("Broadcom");
441 MODULE_DESCRIPTION("IPROC SDHCI driver");
442 MODULE_LICENSE("GPL v2");
443