From: Tony Lindgren Date: Tue, 21 Sep 2021 11:00:29 +0000 (+0300) Subject: mmc: sdhci-omap: Check MMCHS_HL_HWINFO register for ADMA X-Git-Tag: microblaze-v5.18~646^2~41 X-Git-Url: http://git.monstr.eu/?p=linux-2.6-microblaze.git;a=commitdiff_plain;h=c66e21fdc42dcc1c5c559fc4682f3a7f8b4c93f1 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 Link: https://lore.kernel.org/r/20210921110029.21944-6-tony@atomide.com Signed-off-by: Ulf Hansson --- 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")) {