hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/mmc/host/sdhci-iproc.c
....@@ -15,6 +15,7 @@
1515 * iProc SDHCI platform driver
1616 */
1717
18
+#include <linux/acpi.h>
1819 #include <linux/delay.h>
1920 #include <linux/module.h>
2021 #include <linux/mmc/host.h>
....@@ -162,9 +163,36 @@
162163 sdhci_iproc_writel(host, newval, reg & ~3);
163164 }
164165
166
+static unsigned int sdhci_iproc_get_max_clock(struct sdhci_host *host)
167
+{
168
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
169
+
170
+ if (pltfm_host->clk)
171
+ return sdhci_pltfm_clk_get_max_clock(host);
172
+ else
173
+ return pltfm_host->clock;
174
+}
175
+
176
+/*
177
+ * There is a known bug on BCM2711's SDHCI core integration where the
178
+ * controller will hang when the difference between the core clock and the bus
179
+ * clock is too great. Specifically this can be reproduced under the following
180
+ * conditions:
181
+ *
182
+ * - No SD card plugged in, polling thread is running, probing cards at
183
+ * 100 kHz.
184
+ * - BCM2711's core clock configured at 500MHz or more
185
+ *
186
+ * So we set 200kHz as the minimum clock frequency available for that SoC.
187
+ */
188
+static unsigned int sdhci_iproc_bcm2711_get_min_clock(struct sdhci_host *host)
189
+{
190
+ return 200000;
191
+}
192
+
165193 static const struct sdhci_ops sdhci_iproc_ops = {
166194 .set_clock = sdhci_set_clock,
167
- .get_max_clock = sdhci_pltfm_clk_get_max_clock,
195
+ .get_max_clock = sdhci_iproc_get_max_clock,
168196 .set_bus_width = sdhci_set_bus_width,
169197 .reset = sdhci_reset,
170198 .set_uhs_signaling = sdhci_set_uhs_signaling,
....@@ -178,7 +206,7 @@
178206 .write_w = sdhci_iproc_writew,
179207 .write_b = sdhci_iproc_writeb,
180208 .set_clock = sdhci_set_clock,
181
- .get_max_clock = sdhci_pltfm_clk_get_max_clock,
209
+ .get_max_clock = sdhci_iproc_get_max_clock,
182210 .set_bus_width = sdhci_set_bus_width,
183211 .reset = sdhci_reset,
184212 .set_uhs_signaling = sdhci_set_uhs_signaling,
....@@ -250,27 +278,80 @@
250278 .mmc_caps = 0x00000000,
251279 };
252280
281
+static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
282
+ .read_l = sdhci_iproc_readl,
283
+ .read_w = sdhci_iproc_readw,
284
+ .read_b = sdhci_iproc_readb,
285
+ .write_l = sdhci_iproc_writel,
286
+ .write_w = sdhci_iproc_writew,
287
+ .write_b = sdhci_iproc_writeb,
288
+ .set_clock = sdhci_set_clock,
289
+ .set_power = sdhci_set_power_and_bus_voltage,
290
+ .get_max_clock = sdhci_iproc_get_max_clock,
291
+ .get_min_clock = sdhci_iproc_bcm2711_get_min_clock,
292
+ .set_bus_width = sdhci_set_bus_width,
293
+ .reset = sdhci_reset,
294
+ .set_uhs_signaling = sdhci_set_uhs_signaling,
295
+};
296
+
297
+static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
298
+ .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
299
+ .ops = &sdhci_iproc_bcm2711_ops,
300
+};
301
+
302
+static const struct sdhci_iproc_data bcm2711_data = {
303
+ .pdata = &sdhci_bcm2711_pltfm_data,
304
+ .mmc_caps = MMC_CAP_3_3V_DDR,
305
+};
306
+
253307 static const struct of_device_id sdhci_iproc_of_match[] = {
254308 { .compatible = "brcm,bcm2835-sdhci", .data = &bcm2835_data },
309
+ { .compatible = "brcm,bcm2711-emmc2", .data = &bcm2711_data },
255310 { .compatible = "brcm,sdhci-iproc-cygnus", .data = &iproc_cygnus_data},
256311 { .compatible = "brcm,sdhci-iproc", .data = &iproc_data },
257312 { }
258313 };
259314 MODULE_DEVICE_TABLE(of, sdhci_iproc_of_match);
260315
316
+#ifdef CONFIG_ACPI
317
+/*
318
+ * This is a duplicate of bcm2835_(pltfrm_)data without caps quirks
319
+ * which are provided by the ACPI table.
320
+ */
321
+static const struct sdhci_pltfm_data sdhci_bcm_arasan_data = {
322
+ .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
323
+ SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
324
+ SDHCI_QUIRK_NO_HISPD_BIT,
325
+ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
326
+ .ops = &sdhci_iproc_32only_ops,
327
+};
328
+
329
+static const struct sdhci_iproc_data bcm_arasan_data = {
330
+ .pdata = &sdhci_bcm_arasan_data,
331
+};
332
+
333
+static const struct acpi_device_id sdhci_iproc_acpi_ids[] = {
334
+ { .id = "BRCM5871", .driver_data = (kernel_ulong_t)&iproc_cygnus_data },
335
+ { .id = "BRCM5872", .driver_data = (kernel_ulong_t)&iproc_data },
336
+ { .id = "BCM2847", .driver_data = (kernel_ulong_t)&bcm_arasan_data },
337
+ { .id = "BRCME88C", .driver_data = (kernel_ulong_t)&bcm2711_data },
338
+ { /* sentinel */ }
339
+};
340
+MODULE_DEVICE_TABLE(acpi, sdhci_iproc_acpi_ids);
341
+#endif
342
+
261343 static int sdhci_iproc_probe(struct platform_device *pdev)
262344 {
263
- const struct of_device_id *match;
264
- const struct sdhci_iproc_data *iproc_data;
345
+ struct device *dev = &pdev->dev;
346
+ const struct sdhci_iproc_data *iproc_data = NULL;
265347 struct sdhci_host *host;
266348 struct sdhci_iproc_host *iproc_host;
267349 struct sdhci_pltfm_host *pltfm_host;
268350 int ret;
269351
270
- match = of_match_device(sdhci_iproc_of_match, &pdev->dev);
271
- if (!match)
272
- return -EINVAL;
273
- iproc_data = match->data;
352
+ iproc_data = device_get_match_data(dev);
353
+ if (!iproc_data)
354
+ return -ENODEV;
274355
275356 host = sdhci_pltfm_init(pdev, iproc_data->pdata, sizeof(*iproc_host));
276357 if (IS_ERR(host))
....@@ -285,19 +366,21 @@
285366 if (ret)
286367 goto err;
287368
288
- sdhci_get_of_property(pdev);
369
+ sdhci_get_property(pdev);
289370
290371 host->mmc->caps |= iproc_host->data->mmc_caps;
291372
292
- pltfm_host->clk = devm_clk_get(&pdev->dev, NULL);
293
- if (IS_ERR(pltfm_host->clk)) {
294
- ret = PTR_ERR(pltfm_host->clk);
295
- goto err;
296
- }
297
- ret = clk_prepare_enable(pltfm_host->clk);
298
- if (ret) {
299
- dev_err(&pdev->dev, "failed to enable host clk\n");
300
- goto err;
373
+ if (dev->of_node) {
374
+ pltfm_host->clk = devm_clk_get(dev, NULL);
375
+ if (IS_ERR(pltfm_host->clk)) {
376
+ ret = PTR_ERR(pltfm_host->clk);
377
+ goto err;
378
+ }
379
+ ret = clk_prepare_enable(pltfm_host->clk);
380
+ if (ret) {
381
+ dev_err(dev, "failed to enable host clk\n");
382
+ goto err;
383
+ }
301384 }
302385
303386 if (iproc_host->data->pdata->quirks & SDHCI_QUIRK_MISSING_CAPS) {
....@@ -312,7 +395,8 @@
312395 return 0;
313396
314397 err_clk:
315
- clk_disable_unprepare(pltfm_host->clk);
398
+ if (dev->of_node)
399
+ clk_disable_unprepare(pltfm_host->clk);
316400 err:
317401 sdhci_pltfm_free(pdev);
318402 return ret;
....@@ -323,6 +407,7 @@
323407 .name = "sdhci-iproc",
324408 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
325409 .of_match_table = sdhci_iproc_of_match,
410
+ .acpi_match_table = ACPI_PTR(sdhci_iproc_acpi_ids),
326411 .pm = &sdhci_pltfm_pmops,
327412 },
328413 .probe = sdhci_iproc_probe,