Linux MultiMedia Card development
 help / color / mirror / Atom feed
* [PATCH v2] mmc: xenon: Add ac5 support via bounce buffer
@ 2024-01-04 17:30 Elad Nachman
  2024-01-04 18:52 ` Adrian Hunter
  2024-01-05 10:18 ` Ulf Hansson
  0 siblings, 2 replies; 3+ messages in thread
From: Elad Nachman @ 2024-01-04 17:30 UTC (permalink / raw)
  To: huziji, ulf.hansson, adrian.hunter, linux-mmc, linux-kernel; +Cc: enachman

From: Elad Nachman <enachman@marvell.com>

AC5/X/IM SOCs has a variant of the Xenon eMMC controller,
in which only 31-bit of addressing pass from the controller
on the AXI bus.
Since we cannot guarantee that only buffers from the first 2GB
of memory will reach the driver, the driver is configured for
SDMA mode, without 64-bit mode, overriding the DMA mask to 34-bit
to support the DDR memory mapping, which starts at offset 8GB.

Signed-off-by: Elad Nachman <enachman@marvell.com>
---
 drivers/mmc/host/sdhci-xenon.c | 31 +++++++++++++++++++++++++++++++
 drivers/mmc/host/sdhci-xenon.h |  3 ++-
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-xenon.c b/drivers/mmc/host/sdhci-xenon.c
index 25ba7aecc3be..0e52867f6e91 100644
--- a/drivers/mmc/host/sdhci-xenon.c
+++ b/drivers/mmc/host/sdhci-xenon.c
@@ -18,6 +18,8 @@
 #include <linux/of.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
 
 #include "sdhci-pltfm.h"
 #include "sdhci-xenon.h"
@@ -422,6 +424,7 @@ static int xenon_probe_params(struct platform_device *pdev)
 	struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
 	u32 sdhc_id, nr_sdhc;
 	u32 tuning_count;
+	struct sysinfo si;
 
 	/* Disable HS200 on Armada AP806 */
 	if (priv->hw_version == XENON_AP806)
@@ -450,6 +453,23 @@ static int xenon_probe_params(struct platform_device *pdev)
 	}
 	priv->tuning_count = tuning_count;
 
+	/*
+	 * AC5/X/IM HW has only 31-bits passed in the crossbar switch.
+	 * If we have more than 2GB of memory, this means we might pass
+	 * memory pointers which are above 2GB and which cannot be properly
+	 * represented. In this case, disable ADMA, 64-bit DMA and allow only SDMA.
+	 * This effectively will enable bounce buffer quirk in the
+	 * generic SDHCI driver, which will make sure DMA is only done
+	 * from supported memory regions:
+	 */
+	if (priv->hw_version == XENON_AC5) {
+		si_meminfo(&si);
+		if (si.totalram * si.mem_unit > SZ_2G) {
+			host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
+			host->quirks2 |= SDHCI_QUIRK2_BROKEN_64_BIT_DMA;
+		}
+	}
+
 	return xenon_phy_parse_params(dev, host);
 }
 
@@ -562,6 +582,16 @@ static int xenon_probe(struct platform_device *pdev)
 		goto remove_sdhc;
 
 	pm_runtime_put_autosuspend(&pdev->dev);
+	/*
+	 * If we previously detected AC5 with over 2GB of memory,
+	 * then we disable ADMA and 64-bit DMA.
+	 * This means generic SDHCI driver has set the DMA mask to
+	 * 32-bit. Since DDR starts at 0x2_0000_0000, we must use
+	 * 34-bit DMA mask to access this DDR memory:
+	 */
+	if (priv->hw_version == XENON_AC5 &&
+	    host->quirks2 & SDHCI_QUIRK2_BROKEN_64_BIT_DMA)
+		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
 
 	return 0;
 
@@ -680,6 +710,7 @@ static const struct of_device_id sdhci_xenon_dt_ids[] = {
 	{ .compatible = "marvell,armada-ap807-sdhci", .data = (void *)XENON_AP807},
 	{ .compatible = "marvell,armada-cp110-sdhci", .data =  (void *)XENON_CP110},
 	{ .compatible = "marvell,armada-3700-sdhci", .data =  (void *)XENON_A3700},
+	{ .compatible = "marvell,ac5-sdhci",	     .data =  (void *)XENON_AC5},
 	{}
 };
 MODULE_DEVICE_TABLE(of, sdhci_xenon_dt_ids);
diff --git a/drivers/mmc/host/sdhci-xenon.h b/drivers/mmc/host/sdhci-xenon.h
index 3e9c6c908a79..0460d97aad26 100644
--- a/drivers/mmc/host/sdhci-xenon.h
+++ b/drivers/mmc/host/sdhci-xenon.h
@@ -57,7 +57,8 @@ enum xenon_variant {
 	XENON_A3700,
 	XENON_AP806,
 	XENON_AP807,
-	XENON_CP110
+	XENON_CP110,
+	XENON_AC5
 };
 
 struct xenon_priv {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] mmc: xenon: Add ac5 support via bounce buffer
  2024-01-04 17:30 [PATCH v2] mmc: xenon: Add ac5 support via bounce buffer Elad Nachman
@ 2024-01-04 18:52 ` Adrian Hunter
  2024-01-05 10:18 ` Ulf Hansson
  1 sibling, 0 replies; 3+ messages in thread
From: Adrian Hunter @ 2024-01-04 18:52 UTC (permalink / raw)
  To: Elad Nachman, huziji, ulf.hansson, linux-mmc, linux-kernel

On 4/01/24 19:30, Elad Nachman wrote:
> From: Elad Nachman <enachman@marvell.com>
> 
> AC5/X/IM SOCs has a variant of the Xenon eMMC controller,
> in which only 31-bit of addressing pass from the controller
> on the AXI bus.
> Since we cannot guarantee that only buffers from the first 2GB
> of memory will reach the driver, the driver is configured for
> SDMA mode, without 64-bit mode, overriding the DMA mask to 34-bit
> to support the DDR memory mapping, which starts at offset 8GB.
> 
> Signed-off-by: Elad Nachman <enachman@marvell.com>

Acked-by: Adrian Hunter <adrian.hunter@intel.com>

> ---
>  drivers/mmc/host/sdhci-xenon.c | 31 +++++++++++++++++++++++++++++++
>  drivers/mmc/host/sdhci-xenon.h |  3 ++-
>  2 files changed, 33 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/host/sdhci-xenon.c b/drivers/mmc/host/sdhci-xenon.c
> index 25ba7aecc3be..0e52867f6e91 100644
> --- a/drivers/mmc/host/sdhci-xenon.c
> +++ b/drivers/mmc/host/sdhci-xenon.c
> @@ -18,6 +18,8 @@
>  #include <linux/of.h>
>  #include <linux/pm.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/mm.h>
> +#include <linux/dma-mapping.h>
>  
>  #include "sdhci-pltfm.h"
>  #include "sdhci-xenon.h"
> @@ -422,6 +424,7 @@ static int xenon_probe_params(struct platform_device *pdev)
>  	struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
>  	u32 sdhc_id, nr_sdhc;
>  	u32 tuning_count;
> +	struct sysinfo si;
>  
>  	/* Disable HS200 on Armada AP806 */
>  	if (priv->hw_version == XENON_AP806)
> @@ -450,6 +453,23 @@ static int xenon_probe_params(struct platform_device *pdev)
>  	}
>  	priv->tuning_count = tuning_count;
>  
> +	/*
> +	 * AC5/X/IM HW has only 31-bits passed in the crossbar switch.
> +	 * If we have more than 2GB of memory, this means we might pass
> +	 * memory pointers which are above 2GB and which cannot be properly
> +	 * represented. In this case, disable ADMA, 64-bit DMA and allow only SDMA.
> +	 * This effectively will enable bounce buffer quirk in the
> +	 * generic SDHCI driver, which will make sure DMA is only done
> +	 * from supported memory regions:
> +	 */
> +	if (priv->hw_version == XENON_AC5) {
> +		si_meminfo(&si);
> +		if (si.totalram * si.mem_unit > SZ_2G) {
> +			host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
> +			host->quirks2 |= SDHCI_QUIRK2_BROKEN_64_BIT_DMA;
> +		}
> +	}
> +
>  	return xenon_phy_parse_params(dev, host);
>  }
>  
> @@ -562,6 +582,16 @@ static int xenon_probe(struct platform_device *pdev)
>  		goto remove_sdhc;
>  
>  	pm_runtime_put_autosuspend(&pdev->dev);
> +	/*
> +	 * If we previously detected AC5 with over 2GB of memory,
> +	 * then we disable ADMA and 64-bit DMA.
> +	 * This means generic SDHCI driver has set the DMA mask to
> +	 * 32-bit. Since DDR starts at 0x2_0000_0000, we must use
> +	 * 34-bit DMA mask to access this DDR memory:
> +	 */
> +	if (priv->hw_version == XENON_AC5 &&
> +	    host->quirks2 & SDHCI_QUIRK2_BROKEN_64_BIT_DMA)
> +		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
>  
>  	return 0;
>  
> @@ -680,6 +710,7 @@ static const struct of_device_id sdhci_xenon_dt_ids[] = {
>  	{ .compatible = "marvell,armada-ap807-sdhci", .data = (void *)XENON_AP807},
>  	{ .compatible = "marvell,armada-cp110-sdhci", .data =  (void *)XENON_CP110},
>  	{ .compatible = "marvell,armada-3700-sdhci", .data =  (void *)XENON_A3700},
> +	{ .compatible = "marvell,ac5-sdhci",	     .data =  (void *)XENON_AC5},
>  	{}
>  };
>  MODULE_DEVICE_TABLE(of, sdhci_xenon_dt_ids);
> diff --git a/drivers/mmc/host/sdhci-xenon.h b/drivers/mmc/host/sdhci-xenon.h
> index 3e9c6c908a79..0460d97aad26 100644
> --- a/drivers/mmc/host/sdhci-xenon.h
> +++ b/drivers/mmc/host/sdhci-xenon.h
> @@ -57,7 +57,8 @@ enum xenon_variant {
>  	XENON_A3700,
>  	XENON_AP806,
>  	XENON_AP807,
> -	XENON_CP110
> +	XENON_CP110,
> +	XENON_AC5
>  };
>  
>  struct xenon_priv {


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] mmc: xenon: Add ac5 support via bounce buffer
  2024-01-04 17:30 [PATCH v2] mmc: xenon: Add ac5 support via bounce buffer Elad Nachman
  2024-01-04 18:52 ` Adrian Hunter
@ 2024-01-05 10:18 ` Ulf Hansson
  1 sibling, 0 replies; 3+ messages in thread
From: Ulf Hansson @ 2024-01-05 10:18 UTC (permalink / raw)
  To: Elad Nachman; +Cc: huziji, adrian.hunter, linux-mmc, linux-kernel

On Thu, 4 Jan 2024 at 18:31, Elad Nachman <enachman@marvell.com> wrote:
>
> From: Elad Nachman <enachman@marvell.com>
>
> AC5/X/IM SOCs has a variant of the Xenon eMMC controller,
> in which only 31-bit of addressing pass from the controller
> on the AXI bus.
> Since we cannot guarantee that only buffers from the first 2GB
> of memory will reach the driver, the driver is configured for
> SDMA mode, without 64-bit mode, overriding the DMA mask to 34-bit
> to support the DDR memory mapping, which starts at offset 8GB.
>
> Signed-off-by: Elad Nachman <enachman@marvell.com>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/sdhci-xenon.c | 31 +++++++++++++++++++++++++++++++
>  drivers/mmc/host/sdhci-xenon.h |  3 ++-
>  2 files changed, 33 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-xenon.c b/drivers/mmc/host/sdhci-xenon.c
> index 25ba7aecc3be..0e52867f6e91 100644
> --- a/drivers/mmc/host/sdhci-xenon.c
> +++ b/drivers/mmc/host/sdhci-xenon.c
> @@ -18,6 +18,8 @@
>  #include <linux/of.h>
>  #include <linux/pm.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/mm.h>
> +#include <linux/dma-mapping.h>
>
>  #include "sdhci-pltfm.h"
>  #include "sdhci-xenon.h"
> @@ -422,6 +424,7 @@ static int xenon_probe_params(struct platform_device *pdev)
>         struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host);
>         u32 sdhc_id, nr_sdhc;
>         u32 tuning_count;
> +       struct sysinfo si;
>
>         /* Disable HS200 on Armada AP806 */
>         if (priv->hw_version == XENON_AP806)
> @@ -450,6 +453,23 @@ static int xenon_probe_params(struct platform_device *pdev)
>         }
>         priv->tuning_count = tuning_count;
>
> +       /*
> +        * AC5/X/IM HW has only 31-bits passed in the crossbar switch.
> +        * If we have more than 2GB of memory, this means we might pass
> +        * memory pointers which are above 2GB and which cannot be properly
> +        * represented. In this case, disable ADMA, 64-bit DMA and allow only SDMA.
> +        * This effectively will enable bounce buffer quirk in the
> +        * generic SDHCI driver, which will make sure DMA is only done
> +        * from supported memory regions:
> +        */
> +       if (priv->hw_version == XENON_AC5) {
> +               si_meminfo(&si);
> +               if (si.totalram * si.mem_unit > SZ_2G) {
> +                       host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
> +                       host->quirks2 |= SDHCI_QUIRK2_BROKEN_64_BIT_DMA;
> +               }
> +       }
> +
>         return xenon_phy_parse_params(dev, host);
>  }
>
> @@ -562,6 +582,16 @@ static int xenon_probe(struct platform_device *pdev)
>                 goto remove_sdhc;
>
>         pm_runtime_put_autosuspend(&pdev->dev);
> +       /*
> +        * If we previously detected AC5 with over 2GB of memory,
> +        * then we disable ADMA and 64-bit DMA.
> +        * This means generic SDHCI driver has set the DMA mask to
> +        * 32-bit. Since DDR starts at 0x2_0000_0000, we must use
> +        * 34-bit DMA mask to access this DDR memory:
> +        */
> +       if (priv->hw_version == XENON_AC5 &&
> +           host->quirks2 & SDHCI_QUIRK2_BROKEN_64_BIT_DMA)
> +               dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
>
>         return 0;
>
> @@ -680,6 +710,7 @@ static const struct of_device_id sdhci_xenon_dt_ids[] = {
>         { .compatible = "marvell,armada-ap807-sdhci", .data = (void *)XENON_AP807},
>         { .compatible = "marvell,armada-cp110-sdhci", .data =  (void *)XENON_CP110},
>         { .compatible = "marvell,armada-3700-sdhci", .data =  (void *)XENON_A3700},
> +       { .compatible = "marvell,ac5-sdhci",         .data =  (void *)XENON_AC5},
>         {}
>  };
>  MODULE_DEVICE_TABLE(of, sdhci_xenon_dt_ids);
> diff --git a/drivers/mmc/host/sdhci-xenon.h b/drivers/mmc/host/sdhci-xenon.h
> index 3e9c6c908a79..0460d97aad26 100644
> --- a/drivers/mmc/host/sdhci-xenon.h
> +++ b/drivers/mmc/host/sdhci-xenon.h
> @@ -57,7 +57,8 @@ enum xenon_variant {
>         XENON_A3700,
>         XENON_AP806,
>         XENON_AP807,
> -       XENON_CP110
> +       XENON_CP110,
> +       XENON_AC5
>  };
>
>  struct xenon_priv {
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-01-05 10:19 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-04 17:30 [PATCH v2] mmc: xenon: Add ac5 support via bounce buffer Elad Nachman
2024-01-04 18:52 ` Adrian Hunter
2024-01-05 10:18 ` Ulf Hansson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox