summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2021-09-21 14:00:29 +0300
committerUlf Hansson <ulf.hansson@linaro.org>2021-10-12 11:21:19 +0300
commitc66e21fdc42dcc1c5c559fc4682f3a7f8b4c93f1 (patch)
tree05ca8036cc13ead77e8783ca9d40b6aaffca3e8c
parent3781d28805eca89796fd50af8e05569c210fc87d (diff)
downloadlinux-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.c24
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")) {