Message ID | 1418662867-9210-2-git-send-email-stripathi@apm.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
On Monday 15 December 2014 22:31:06 Suman Tripathi wrote: > @@ -162,6 +206,16 @@ static int sdhci_arasan_probe(struct platform_device *pdev) > goto clk_dis_ahb; > } > > +#if defined(CONFIG_IOMMU_SUPPORT) > + sdhci_arasan->domain = iommu_domain_alloc(&amba_bustype); > + if (!sdhci_arasan->domain) { > + dev_err(&pdev->dev, "Unable to allocate iommu domain\n"); > + return PTR_ERR(sdhci_arasan->domain); > + } > + > + iommu_attach_device(sdhci_arasan->domain, &pdev->dev); > +#endif > + > Device drivers should never care about the implementation details of the iommu. Please change the code to use the regular dma_map_* interfaces that will work both with and without IOMMU. Arnd
Hi Arnd, On Monday 15 December 2014 22:31:06 Suman Tripathi wrote: > @@ -162,6 +206,16 @@ static int sdhci_arasan_probe(struct platform_device *pdev) > goto clk_dis_ahb; > } > > +#if defined(CONFIG_IOMMU_SUPPORT) > + sdhci_arasan->domain = iommu_domain_alloc(&amba_bustype); > + if (!sdhci_arasan->domain) { > + dev_err(&pdev->dev, "Unable to allocate iommu domain\n"); > + return PTR_ERR(sdhci_arasan->domain); > + } > + > + iommu_attach_device(sdhci_arasan->domain, &pdev->dev); > +#endif > + > Device drivers should never care about the implementation details of the iommu. Please change the code to use the regular dma_map_* interfaces that will work both with and without IOMMU. After refer to iommu binding , there is a service that allows "Remap address space to allow devices to access physical memory ranges that they otherwise wouldn't be capable of accessing." eg : 32-bit to 64 bit DMA . So do we have any existing driver that uses this service ? Just asking for suggestions. On Tue, Dec 16, 2014 at 2:57 AM, Arnd Bergmann <arnd@arndb.de> wrote: > On Monday 15 December 2014 22:31:06 Suman Tripathi wrote: >> @@ -162,6 +206,16 @@ static int sdhci_arasan_probe(struct platform_device *pdev) >> goto clk_dis_ahb; >> } >> >> +#if defined(CONFIG_IOMMU_SUPPORT) >> + sdhci_arasan->domain = iommu_domain_alloc(&amba_bustype); >> + if (!sdhci_arasan->domain) { >> + dev_err(&pdev->dev, "Unable to allocate iommu domain\n"); >> + return PTR_ERR(sdhci_arasan->domain); >> + } >> + >> + iommu_attach_device(sdhci_arasan->domain, &pdev->dev); >> +#endif >> + >> > > Device drivers should never care about the implementation details > of the iommu. Please change the code to use the regular dma_map_* > interfaces that will work both with and without IOMMU. > > Arnd
On Tuesday 06 January 2015 17:10:29 Suman Tripathi wrote: > Hi Arnd, > > On Monday 15 December 2014 22:31:06 Suman Tripathi wrote: > > > @@ -162,6 +206,16 @@ static int sdhci_arasan_probe(struct > > > platform_device *pdev)> > > > > > goto clk_dis_ahb; > > > > > > } > > > > > > +#if defined(CONFIG_IOMMU_SUPPORT) > > > + sdhci_arasan->domain = iommu_domain_alloc(&amba_bustype); > > > + if (!sdhci_arasan->domain) { > > > + dev_err(&pdev->dev, "Unable to allocate iommu > > > domain\n"); > > > + return PTR_ERR(sdhci_arasan->domain); > > > + } > > > + > > > + iommu_attach_device(sdhci_arasan->domain, &pdev->dev); > > > +#endif > > > + > > > > Device drivers should never care about the implementation details > > of the iommu. Please change the code to use the regular dma_map_* > > interfaces that will work both with and without IOMMU. > > After refer to iommu binding , there is a service that allows "Remap > address space to allow devices to access physical memory ranges that > they otherwise wouldn't be capable of accessing." eg : 32-bit to 64 > bit DMA . > > So do we have any existing driver that uses this service ? Just asking > for suggestions. The interface is completely transparent to device drivers, it is implemented as a separate 'struct dma_map_ops' that is normally architecture independent, and that handles all sorts of DMA remapping issues for the driver, including - address space limits - offsets between CPU and device addresses for the same memory - cache flushes - bus-level synchronization On arm32, we currently support six sets of dma_map_ops including two for IOMMU (coherent and noncoherent). On arm64, we currently always use swiotlb, which solves your problem by copying memory to bounce buffers. This is rather inefficient, and a new implementation is being worked on, based on the arm32 implementation to support IOMMUs in a generic way. Arnd
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 4511358..0c6dc47 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -108,6 +108,7 @@ config MMC_SDHCI_OF_ARASAN tristate "SDHCI OF support for the Arasan SDHCI controllers" depends on MMC_SDHCI_PLTFM depends on OF + select MMC_SDHCI_IO_ACCESSORS help This selects the Arasan Secure Digital Host Controller Interface (SDHCI). This hardware is found e.g. in Xilinx' Zynq SoC. diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 5bd1092..c0e0c9b 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -20,6 +20,10 @@ */ #include <linux/module.h> +#if defined(CONFIG_IOMMU_SUPPORT) +#include <linux/amba/bus.h> +#include <linux/iommu.h> +#endif #include "sdhci-pltfm.h" #define SDHCI_ARASAN_CLK_CTRL_OFFSET 0x2c @@ -34,8 +38,46 @@ */ struct sdhci_arasan_data { struct clk *clk_ahb; +#if defined(CONFIG_IOMMU_SUPPORT) + struct iommu_domain *domain; +#endif }; +static void sdhci_arasan_write_l(struct sdhci_host *host, u32 val, int reg) +{ +#if defined(CONFIG_IOMMU_SUPPORT) + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_arasan_data *sdhci_arasan = pltfm_host->priv; + /* + * This allows the arasan IP to integrate with 64-bit platform. + * As the AHB dma masters generates 32-bit address so it needs + * IO translation of 32-bit to 42-bit AXI address with help of IOMMU. + */ + if (reg == SDHCI_DMA_ADDRESS) { + phys_addr_t dma_addr = sg_dma_address(host->data->sg); + sdhci_arasan->domain->ops->map(sdhci_arasan->domain, 0, + dma_addr, 0, 0); + } +#endif + writel(val, host->ioaddr + reg); +} + +static u32 xgene_sdhci_readl(struct sdhci_host *host, int reg) +{ +#if defined(CONFIG_IOMMU_SUPPORT) + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_arasan_data *sdhci_arasan = pltfm_host->priv; + + if (reg == SDHCI_INT_STATUS ) { + if ((readl(host->ioaddr + reg) & SDHCI_INT_DATA_MASK) == + SDHCI_INT_DMA_END) + sdhci_arasan->domain->ops->unmap(sdhci_arasan->domain, + 0, 0); + } +#endif + return readl(host->ioaddr + reg); +} + static unsigned int sdhci_arasan_get_timeout_clock(struct sdhci_host *host) { u32 div; @@ -58,6 +100,8 @@ static struct sdhci_ops sdhci_arasan_ops = { .set_bus_width = sdhci_set_bus_width, .reset = sdhci_reset, .set_uhs_signaling = sdhci_set_uhs_signaling, + .write_l = sdhci_arasan_write_l, + .read_l = xgene_sdhci_readl, }; static struct sdhci_pltfm_data sdhci_arasan_pdata = { @@ -162,6 +206,16 @@ static int sdhci_arasan_probe(struct platform_device *pdev) goto clk_dis_ahb; } +#if defined(CONFIG_IOMMU_SUPPORT) + sdhci_arasan->domain = iommu_domain_alloc(&amba_bustype); + if (!sdhci_arasan->domain) { + dev_err(&pdev->dev, "Unable to allocate iommu domain\n"); + return PTR_ERR(sdhci_arasan->domain); + } + + iommu_attach_device(sdhci_arasan->domain, &pdev->dev); +#endif + host = sdhci_pltfm_init(pdev, &sdhci_arasan_pdata, 0); if (IS_ERR(host)) { ret = PTR_ERR(host); diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index 7e834fb..08a97dc 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c @@ -90,6 +90,18 @@ void sdhci_get_of_property(struct platform_device *pdev) if (of_get_property(np, "broken-cd", NULL)) host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; + if (of_get_property(np, "delay-after-power", NULL)) + host->quirks |= SDHCI_QUIRK_DELAY_AFTER_POWER; + + if (of_get_property(np, "no-hispd", NULL)) + host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT; + + if (of_get_property(np, "broken-adma", NULL)) + host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; + + if (of_get_property(np, "no-cmd23", NULL)) + host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; + if (of_get_property(np, "no-1-8-v", NULL)) host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
Due to the fact that the existing of-arasan driver works with 32-bit platforms. This patch tweaks existing of-arasan driver to work with 64-bit platform using IOMMU translation. In addition it adds support for more quirks and quirks2 obtained from device tree inside the generic sdhci-platform(sdhci-pltfm.c) driver. Signed-off-by: Suman Tripathi <stripathi@apm.com> --- drivers/mmc/host/Kconfig | 1 + drivers/mmc/host/sdhci-of-arasan.c | 54 ++++++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci-pltfm.c | 12 +++++++++ 3 files changed, 67 insertions(+) -- 1.8.2.1