Lines Matching +full:sdhci +full:- +full:5

1 // SPDX-License-Identifier: GPL-2.0-only
3 * SDHCI Controller driver for TI's OMAP SoCs
11 #include <linux/mmc/slot-gpio.h>
23 #include "sdhci-pltfm.h"
33 #define CON_DW8 BIT(5)
97 /* sdhci-omap controller flags */
103 u32 offset; /* Offset for SDHCI regs from base */
142 return readl(host->base + host->omap_offset + offset); in sdhci_omap_readl()
148 writel(data, host->base + host->omap_offset + offset); in sdhci_omap_writel()
155 struct device *dev = omap_host->dev; in sdhci_omap_set_pbias()
157 if (IS_ERR(omap_host->pbias)) in sdhci_omap_set_pbias()
161 ret = regulator_set_voltage(omap_host->pbias, iov, iov); in sdhci_omap_set_pbias()
167 if (omap_host->pbias_enabled) in sdhci_omap_set_pbias()
170 ret = regulator_enable(omap_host->pbias); in sdhci_omap_set_pbias()
176 omap_host->pbias_enabled = true; in sdhci_omap_set_pbias()
178 if (!omap_host->pbias_enabled) in sdhci_omap_set_pbias()
181 ret = regulator_disable(omap_host->pbias); in sdhci_omap_set_pbias()
186 omap_host->pbias_enabled = false; in sdhci_omap_set_pbias()
196 struct sdhci_host *host = omap_host->host; in sdhci_omap_enable_iov()
197 struct mmc_host *mmc = host->mmc; in sdhci_omap_enable_iov()
203 if (!IS_ERR(mmc->supply.vqmmc)) { in sdhci_omap_enable_iov()
205 ret = mmc_regulator_set_vqmmc(mmc, &mmc->ios); in sdhci_omap_enable_iov()
236 dev_warn(omap_host->dev, "misconfigured CAPA: %08x\n", in sdhci_omap_conf_bus_power()
259 usleep_range(5, 10); in sdhci_omap_conf_bus_power()
322 struct device *dev = omap_host->dev; in sdhci_omap_execute_tuning()
323 struct mmc_ios *ios = &mmc->ios; in sdhci_omap_execute_tuning()
336 if (ios->clock <= 52000000) in sdhci_omap_execute_tuning()
340 if (ios->timing == MMC_TIMING_UHS_SDR50 && !(reg & CAPA2_TSDR50)) in sdhci_omap_execute_tuning()
363 if (host->ier & SDHCI_INT_DATA_CRC) { in sdhci_omap_execute_tuning()
364 host->ier &= ~SDHCI_INT_DATA_CRC; in sdhci_omap_execute_tuning()
368 omap_host->is_tuning = true; in sdhci_omap_execute_tuning()
404 ret = -EIO; in sdhci_omap_execute_tuning()
412 if (temperature < -20000) in sdhci_omap_execute_tuning()
413 phase_delay = min(max_window + 4 * (max_len - 1) - 24, in sdhci_omap_execute_tuning()
423 phase_delay = max_window + DIV_ROUND_UP(5 * max_len, 16) * 4; in sdhci_omap_execute_tuning()
432 * +2 to -10 range. If found, move away from it in the appropriate in sdhci_omap_execute_tuning()
442 phase_delay += i - 12; in sdhci_omap_execute_tuning()
444 phase_delay += i - 8; in sdhci_omap_execute_tuning()
446 phase_delay += i - 6; in sdhci_omap_execute_tuning()
452 for (i = 2; i >= -10; i--) { in sdhci_omap_execute_tuning()
474 ret = -EIO; in sdhci_omap_execute_tuning()
480 omap_host->is_tuning = false; in sdhci_omap_execute_tuning()
485 omap_host->is_tuning = false; in sdhci_omap_execute_tuning()
493 host->ier |= SDHCI_INT_DATA_CRC; in sdhci_omap_execute_tuning()
494 sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); in sdhci_omap_execute_tuning()
495 sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); in sdhci_omap_execute_tuning()
506 u32 ier = host->ier; in sdhci_omap_card_busy()
519 disable_irq(host->irq); in sdhci_omap_card_busy()
537 sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); in sdhci_omap_card_busy()
538 sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); in sdhci_omap_card_busy()
539 enable_irq(host->irq); in sdhci_omap_card_busy()
557 dev = omap_host->dev; in sdhci_omap_start_signal_voltage_switch()
559 if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) { in sdhci_omap_start_signal_voltage_switch()
562 return -EOPNOTSUPP; in sdhci_omap_start_signal_voltage_switch()
569 sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage); in sdhci_omap_start_signal_voltage_switch()
575 } else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) { in sdhci_omap_start_signal_voltage_switch()
578 return -EOPNOTSUPP; in sdhci_omap_start_signal_voltage_switch()
582 sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage); in sdhci_omap_start_signal_voltage_switch()
588 return -EOPNOTSUPP; in sdhci_omap_start_signal_voltage_switch()
605 struct device *dev = omap_host->dev; in sdhci_omap_set_timing()
607 if (!(omap_host->flags & SDHCI_OMAP_REQUIRE_IODELAY)) in sdhci_omap_set_timing()
610 if (omap_host->timing == timing) in sdhci_omap_set_timing()
615 pinctrl_state = omap_host->pinctrl_state[timing]; in sdhci_omap_set_timing()
616 ret = pinctrl_select_state(omap_host->pinctrl, pinctrl_state); in sdhci_omap_set_timing()
623 omap_host->timing = timing; in sdhci_omap_set_timing()
629 if (omap_host->bus_mode == MMC_POWER_OFF) in sdhci_omap_set_power_mode()
631 omap_host->power_mode = power_mode; in sdhci_omap_set_power_mode()
639 if (omap_host->bus_mode == mode) in sdhci_omap_set_bus_mode()
649 omap_host->bus_mode = mode; in sdhci_omap_set_bus_mode()
661 sdhci_omap_set_bus_mode(omap_host, ios->bus_mode); in sdhci_omap_set_ios()
662 sdhci_omap_set_timing(omap_host, ios->timing); in sdhci_omap_set_ios()
664 sdhci_omap_set_power_mode(omap_host, ios->power_mode); in sdhci_omap_set_ios()
672 dsor = DIV_ROUND_UP(clk_get_rate(host->clk), clock); in sdhci_omap_calc_divisor()
718 struct mmc_host *mmc = host->mmc; in sdhci_omap_set_power()
720 if (!IS_ERR(mmc->supply.vmmc)) in sdhci_omap_set_power()
721 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); in sdhci_omap_set_power()
728 * omap registers and sdhci registers. The offset can vary for omap
737 return readl(omap_host->base + 4) & 1; in sdhci_omap_has_adma()
749 if (!host->use_external_dma) in sdhci_omap_enable_dma()
761 return clk_get_rate(pltfm_host->clk) / SYSCTL_CLKD_MAX; in sdhci_omap_get_min_clock()
787 if (omap_host->power_mode == power_mode) in sdhci_omap_init_74_clocks()
793 disable_irq(host->irq); in sdhci_omap_init_74_clocks()
809 usleep_range(5, 10); in sdhci_omap_init_74_clocks()
817 enable_irq(host->irq); in sdhci_omap_init_74_clocks()
854 if (omap_host->is_tuning) in sdhci_omap_reset()
857 if (omap_host->flags & SDHCI_OMAP_SPECIAL_RESET) { in sdhci_omap_reset()
868 dev_err(mmc_dev(host->mmc), in sdhci_omap_reset()
891 if (omap_host->is_tuning && host->cmd && !host->data_early && in sdhci_omap_irq()
901 host->cmd->error = -ETIMEDOUT; in sdhci_omap_irq()
903 host->cmd->error = -EILSEQ; in sdhci_omap_irq()
905 host->cmd = NULL; in sdhci_omap_irq()
922 if (cmd->opcode == MMC_ERASE) in sdhci_omap_set_timeout()
968 struct device *dev = omap_host->dev; in sdhci_omap_set_capabilities()
1005 host->caps &= ~mask; in sdhci_omap_set_capabilities()
1006 host->caps |= caps; in sdhci_omap_set_capabilities()
1070 { .compatible = "ti,omap2430-sdhci", .data = &omap2430_data },
1071 { .compatible = "ti,omap3-sdhci", .data = &omap3_data },
1072 { .compatible = "ti,omap4-sdhci", .data = &omap4_data },
1073 { .compatible = "ti,omap5-sdhci", .data = &omap5_data },
1074 { .compatible = "ti,dra7-sdhci", .data = &dra7_data },
1075 { .compatible = "ti,k2g-sdhci", .data = &k2g_data },
1076 { .compatible = "ti,am335-sdhci", .data = &am335_data },
1077 { .compatible = "ti,am437-sdhci", .data = &am437_data },
1086 struct device *dev = omap_host->dev; in sdhci_omap_iodelay_pinctrl_state()
1087 char *version = omap_host->version; in sdhci_omap_iodelay_pinctrl_state()
1088 struct pinctrl_state *pinctrl_state = ERR_PTR(-ENODEV); in sdhci_omap_iodelay_pinctrl_state()
1095 snprintf(str, 20, "%s-%s", mode, version); in sdhci_omap_iodelay_pinctrl_state()
1096 pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, str); in sdhci_omap_iodelay_pinctrl_state()
1100 pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, mode); in sdhci_omap_iodelay_pinctrl_state()
1114 struct device *dev = omap_host->dev; in sdhci_omap_config_iodelay_pinctrl_state()
1115 struct sdhci_host *host = omap_host->host; in sdhci_omap_config_iodelay_pinctrl_state()
1116 struct mmc_host *mmc = host->mmc; in sdhci_omap_config_iodelay_pinctrl_state()
1117 u32 *caps = &mmc->caps; in sdhci_omap_config_iodelay_pinctrl_state()
1118 u32 *caps2 = &mmc->caps2; in sdhci_omap_config_iodelay_pinctrl_state()
1122 if (!(omap_host->flags & SDHCI_OMAP_REQUIRE_IODELAY)) in sdhci_omap_config_iodelay_pinctrl_state()
1130 return -ENOMEM; in sdhci_omap_config_iodelay_pinctrl_state()
1132 omap_host->pinctrl = devm_pinctrl_get(omap_host->dev); in sdhci_omap_config_iodelay_pinctrl_state()
1133 if (IS_ERR(omap_host->pinctrl)) { in sdhci_omap_config_iodelay_pinctrl_state()
1135 return PTR_ERR(omap_host->pinctrl); in sdhci_omap_config_iodelay_pinctrl_state()
1138 state = pinctrl_lookup_state(omap_host->pinctrl, "default"); in sdhci_omap_config_iodelay_pinctrl_state()
1197 omap_host->pinctrl_state = pinctrl_state; in sdhci_omap_config_iodelay_pinctrl_state()
1216 struct device *dev = &pdev->dev; in sdhci_omap_probe()
1225 data = of_device_get_match_data(&pdev->dev); in sdhci_omap_probe()
1227 dev_err(dev, "no sdhci omap data\n"); in sdhci_omap_probe()
1228 return -EINVAL; in sdhci_omap_probe()
1230 offset = data->offset; in sdhci_omap_probe()
1234 return -ENXIO; in sdhci_omap_probe()
1245 omap_host->host = host; in sdhci_omap_probe()
1246 omap_host->base = host->ioaddr; in sdhci_omap_probe()
1247 omap_host->dev = dev; in sdhci_omap_probe()
1248 omap_host->power_mode = MMC_POWER_UNDEFINED; in sdhci_omap_probe()
1249 omap_host->timing = MMC_TIMING_LEGACY; in sdhci_omap_probe()
1250 omap_host->flags = data->flags; in sdhci_omap_probe()
1251 omap_host->omap_offset = data->omap_offset; in sdhci_omap_probe()
1252 omap_host->con = -EINVAL; /* Prevent invalid restore on first resume */ in sdhci_omap_probe()
1253 host->ioaddr += offset; in sdhci_omap_probe()
1254 host->mapbase = regs->start + offset; in sdhci_omap_probe()
1256 mmc = host->mmc; in sdhci_omap_probe()
1264 omap_host->version = "rev11"; in sdhci_omap_probe()
1266 mmc->f_max = 96000000; in sdhci_omap_probe()
1268 mmc->f_max = 48000000; in sdhci_omap_probe()
1270 mmc->f_max = 48000000; in sdhci_omap_probe()
1274 mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT; in sdhci_omap_probe()
1276 pltfm_host->clk = devm_clk_get(dev, "fck"); in sdhci_omap_probe()
1277 if (IS_ERR(pltfm_host->clk)) { in sdhci_omap_probe()
1278 ret = PTR_ERR(pltfm_host->clk); in sdhci_omap_probe()
1282 ret = clk_set_rate(pltfm_host->clk, mmc->f_max); in sdhci_omap_probe()
1284 dev_err(dev, "failed to set clock to %d\n", mmc->f_max); in sdhci_omap_probe()
1288 omap_host->pbias = devm_regulator_get_optional(dev, "pbias"); in sdhci_omap_probe()
1289 if (IS_ERR(omap_host->pbias)) { in sdhci_omap_probe()
1290 ret = PTR_ERR(omap_host->pbias); in sdhci_omap_probe()
1291 if (ret != -ENODEV) in sdhci_omap_probe()
1295 omap_host->pbias_enabled = false; in sdhci_omap_probe()
1319 host->mmc_host_ops.start_signal_voltage_switch = in sdhci_omap_probe()
1321 host->mmc_host_ops.set_ios = sdhci_omap_set_ios; in sdhci_omap_probe()
1322 host->mmc_host_ops.card_busy = sdhci_omap_card_busy; in sdhci_omap_probe()
1323 host->mmc_host_ops.execute_tuning = sdhci_omap_execute_tuning; in sdhci_omap_probe()
1324 host->mmc_host_ops.enable_sdio_irq = sdhci_omap_enable_sdio_irq; in sdhci_omap_probe()
1334 if (device_property_read_bool(dev, "ti,non-removable")) { in sdhci_omap_probe()
1335 dev_warn_once(dev, "using old ti,non-removable property\n"); in sdhci_omap_probe()
1336 mmc->caps |= MMC_CAP_NONREMOVABLE; in sdhci_omap_probe()
1340 mmc->caps |= MMC_CAP_NEED_RSP_BUSY; in sdhci_omap_probe()
1343 mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_AGGRESSIVE_PM; in sdhci_omap_probe()
1358 * SDIO devices can use the dat1 pin as a wake-up interrupt. Some in sdhci_omap_probe()
1359 * devices like wl1xxx, use an out-of-band GPIO interrupt instead. in sdhci_omap_probe()
1361 omap_host->wakeirq = of_irq_get_byname(dev->of_node, "wakeup"); in sdhci_omap_probe()
1362 if (omap_host->wakeirq == -EPROBE_DEFER) { in sdhci_omap_probe()
1363 ret = -EPROBE_DEFER; in sdhci_omap_probe()
1366 if (omap_host->wakeirq > 0) { in sdhci_omap_probe()
1368 ret = dev_pm_set_dedicated_wake_irq(dev, omap_host->wakeirq); in sdhci_omap_probe()
1373 host->mmc->pm_caps |= MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ; in sdhci_omap_probe()
1398 struct device *dev = &pdev->dev; in sdhci_omap_remove()
1415 omap_host->con = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); in sdhci_omap_context_save()
1416 omap_host->hctl = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL); in sdhci_omap_context_save()
1417 omap_host->sysctl = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL); in sdhci_omap_context_save()
1418 omap_host->capa = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA); in sdhci_omap_context_save()
1419 omap_host->ie = sdhci_omap_readl(omap_host, SDHCI_OMAP_IE); in sdhci_omap_context_save()
1420 omap_host->ise = sdhci_omap_readl(omap_host, SDHCI_OMAP_ISE); in sdhci_omap_context_save()
1426 sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, omap_host->hctl); in sdhci_omap_context_restore()
1427 sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, omap_host->capa); in sdhci_omap_context_restore()
1428 sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, omap_host->hctl); in sdhci_omap_context_restore()
1430 sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, omap_host->sysctl); in sdhci_omap_context_restore()
1431 sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, omap_host->con); in sdhci_omap_context_restore()
1432 sdhci_omap_writel(omap_host, SDHCI_OMAP_IE, omap_host->ie); in sdhci_omap_context_restore()
1433 sdhci_omap_writel(omap_host, SDHCI_OMAP_ISE, omap_host->ise); in sdhci_omap_context_restore()
1442 if (host->tuning_mode != SDHCI_TUNING_MODE_3) in sdhci_omap_runtime_suspend()
1443 mmc_retune_needed(host->mmc); in sdhci_omap_runtime_suspend()
1445 if (omap_host->con != -EINVAL) in sdhci_omap_runtime_suspend()
1463 if (omap_host->con != -EINVAL) { in sdhci_omap_runtime_resume()
1483 .name = "sdhci-omap",
1492 MODULE_DESCRIPTION("SDHCI driver for OMAP SoCs");