diff options
author | Tony Lindgren <tony@atomide.com> | 2021-09-21 14:00:29 +0300 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2021-10-12 11:21:19 +0300 |
commit | c66e21fdc42dcc1c5c559fc4682f3a7f8b4c93f1 (patch) | |
tree | 05ca8036cc13ead77e8783ca9d40b6aaffca3e8c | |
parent | 3781d28805eca89796fd50af8e05569c210fc87d (diff) | |
download | linux-c66e21fdc42dcc1c5c559fc4682f3a7f8b4c93f1.tar.xz |
mmc: sdhci-omap: Check MMCHS_HL_HWINFO register for ADMA
ADMA is only available on controller instances that are connected to the
L3 interconnect and are bus mastering capable.
As the MMCHS_HL_HWINFO is in the module registers before omap registers
and sdhci registers, and the omap registers and sdhci registers can be
at different offsets depending on the SoC, let's read MMCHS_HL_HWINFO
directly.
Let's also switch to using device_property_present() while at it.
Signed-off-by: Tony Lindgren <tony@atomide.com>
Link: https://lore.kernel.org/r/20210921110029.21944-6-tony@atomide.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r-- | drivers/mmc/host/sdhci-omap.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c index f28862e03783..9422c9819b77 100644 --- a/drivers/mmc/host/sdhci-omap.c +++ b/drivers/mmc/host/sdhci-omap.c @@ -692,6 +692,22 @@ static void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode, mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); } +/* + * MMCHS_HL_HWINFO has the MADMA_EN bit set if the controller instance + * is connected to L3 interconnect and is bus master capable. Note that + * the MMCHS_HL_HWINFO register is in the module registers before the + * omap registers and sdhci registers. The offset can vary for omap + * registers depending on the SoC. Do not use sdhci_omap_readl() here. + */ +static bool sdhci_omap_has_adma(struct sdhci_omap_host *omap_host, int offset) +{ + /* MMCHS_HL_HWINFO register is only available on omap4 and later */ + if (offset < 0x200) + return false; + + return readl(omap_host->base + 4) & 1; +} + static int sdhci_omap_enable_dma(struct sdhci_host *host) { u32 reg; @@ -1209,8 +1225,12 @@ static int sdhci_omap_probe(struct platform_device *pdev) host->mmc_host_ops.execute_tuning = sdhci_omap_execute_tuning; host->mmc_host_ops.enable_sdio_irq = sdhci_omap_enable_sdio_irq; - /* Switch to external DMA only if there is the "dmas" property */ - if (of_find_property(dev->of_node, "dmas", NULL)) + /* + * Switch to external DMA only if there is the "dmas" property and + * ADMA is not available on the controller instance. + */ + if (device_property_present(dev, "dmas") && + !sdhci_omap_has_adma(omap_host, offset)) sdhci_switch_external_dma(host, true); if (device_property_read_bool(dev, "ti,non-removable")) { |