Message ID | 20221006130622.22900-2-pshete@nvidia.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v7,1/4] mmc: sdhci-tegra: Separate Tegra194 and Tegra234 SoC data | expand |
On Thu, 6 Oct 2022 at 15:07, Prathamesh Shete <pshete@nvidia.com> wrote: > > SMMU clients are supposed to program stream ID from > their respective address spaces instead of MC override. > Define NVQUIRK_PROGRAM_STREAMID and use it to program > SMMU stream ID from the SDMMC client address space. > > Signed-off-by: Aniruddha TVS Rao <anrao@nvidia.com> > Signed-off-by: Prathamesh Shete <pshete@nvidia.com> > Acked-by: Adrian Hunter <adrian.hunter@intel.com> > Acked-by: Thierry Reding <treding@nvidia.com> > --- > drivers/mmc/host/sdhci-tegra.c | 53 ++++++++++++++++++++++++++++++++++ > 1 file changed, 53 insertions(+) > > diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c > index a6c5bbae77b4..e88294a6912d 100644 > --- a/drivers/mmc/host/sdhci-tegra.c > +++ b/drivers/mmc/host/sdhci-tegra.c > @@ -25,6 +25,10 @@ > #include <linux/mmc/slot-gpio.h> > #include <linux/gpio/consumer.h> > #include <linux/ktime.h> > +#ifdef CONFIG_IOMMU_API > +#include <linux/iommu.h> > +#include <linux/bitops.h> > +#endif > > #include <soc/tegra/common.h> > > @@ -94,6 +98,8 @@ > #define SDHCI_TEGRA_AUTO_CAL_STATUS 0x1ec > #define SDHCI_TEGRA_AUTO_CAL_ACTIVE BIT(31) > > +#define SDHCI_TEGRA_CIF2AXI_CTRL_0 0x1fc > + > #define NVQUIRK_FORCE_SDHCI_SPEC_200 BIT(0) > #define NVQUIRK_ENABLE_BLOCK_GAP_DET BIT(1) > #define NVQUIRK_ENABLE_SDHCI_SPEC_300 BIT(2) > @@ -121,6 +127,7 @@ > #define NVQUIRK_HAS_TMCLK BIT(10) > > #define NVQUIRK_HAS_ANDROID_GPT_SECTOR BIT(11) > +#define NVQUIRK_PROGRAM_STREAMID BIT(12) > > /* SDMMC CQE Base Address for Tegra Host Ver 4.1 and Higher */ > #define SDHCI_TEGRA_CQE_BASE_ADDR 0xF000 > @@ -177,6 +184,9 @@ struct sdhci_tegra { > bool enable_hwcq; > unsigned long curr_clk_rate; > u8 tuned_tap_delay; > +#ifdef CONFIG_IOMMU_API I would rather avoid these kinds of "#ifdef" micro optimizations. Please just add the streamid without the #ifdef. > + u32 streamid; > +#endif > }; > > static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg) > @@ -1564,6 +1574,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra234 = { > NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | > NVQUIRK_ENABLE_SDR50 | > NVQUIRK_ENABLE_SDR104 | > + NVQUIRK_PROGRAM_STREAMID | > NVQUIRK_HAS_TMCLK, > .min_tap_delay = 95, > .max_tap_delay = 111, > @@ -1775,6 +1786,25 @@ static int sdhci_tegra_probe(struct platform_device *pdev) > if (rc) > goto err_add_host; > > + /* Program MC streamID for DMA transfers */ > +#ifdef CONFIG_IOMMU_API Again, please drop the #ifdefs here. We already have stub functions for dev_iommu_fwspec_get() in case CONFIG_IOMMU_API is unset. > + if (soc_data->nvquirks & NVQUIRK_PROGRAM_STREAMID) { > + struct iommu_fwspec *fwspec; > + > + fwspec = dev_iommu_fwspec_get(&pdev->dev); > + if (fwspec == NULL) { > + dev_warn(mmc_dev(host->mmc), > + "iommu fwspec is NULL, continue without stream ID\n"); > + } else { > + tegra_host->streamid = fwspec->ids[0] & 0xff; > + tegra_sdhci_writel(host, tegra_host->streamid | > + FIELD_PREP(GENMASK(15, 8), > + tegra_host->streamid), > + SDHCI_TEGRA_CIF2AXI_CTRL_0); > + } > + } > +#endif > + > return 0; > > err_add_host: > @@ -1861,6 +1891,10 @@ static int sdhci_tegra_suspend(struct device *dev) > static int sdhci_tegra_resume(struct device *dev) > { > struct sdhci_host *host = dev_get_drvdata(dev); > +#ifdef CONFIG_IOMMU_API Ditto. > + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); > + struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host); > +#endif > int ret; > > ret = mmc_gpio_set_cd_wake(host->mmc, false); > @@ -1871,6 +1905,25 @@ static int sdhci_tegra_resume(struct device *dev) > if (ret) > return ret; > > + /* Re-program MC streamID for DMA transfers */ > +#ifdef CONFIG_IOMMU_API Ditto. > + if (tegra_host->soc_data->nvquirks & NVQUIRK_PROGRAM_STREAMID) { > + struct iommu_fwspec *fwspec; > + > + fwspec = dev_iommu_fwspec_get(dev); > + if (fwspec == NULL) { > + dev_warn(mmc_dev(host->mmc), > + "iommu fwspec is NULL, continue without stream ID\n"); > + } else { > + tegra_host->streamid = fwspec->ids[0] & 0xff; > + tegra_sdhci_writel(host, tegra_host->streamid | > + FIELD_PREP(GENMASK(15, 8), > + tegra_host->streamid), > + SDHCI_TEGRA_CIF2AXI_CTRL_0); > + } > + } > +#endif > + > ret = sdhci_resume_host(host); > if (ret) > goto disable_clk; > -- > 2.17.1 > Kind regards Uffe
Hi Ulf The initial patches were without the #ifdef. #ifdef is being added as per review comments and kernel robot errors. Following error was detected by kernel robot >> All errors (new ones prefixed by >>): drivers/mmc/host/sdhci-tegra.c: In function 'sdhci_tegra_probe': >> drivers/mmc/host/sdhci-tegra.c:1794:54: error: 'struct iommu_fwspec' has no member named 'ids' 1794 | tegra_host->streamid = fwspec->ids[0] & 0xffff; | ^~ vim +1794 drivers/mmc/host/sdhci-tegra.c >> Adrian also pointed out this issue so to address these issues #ifdef was added Thanks Prathamesh > -----Original Message----- > From: Ulf Hansson <ulf.hansson@linaro.org> > Sent: Tuesday, October 11, 2022 3:29 PM > To: Prathamesh Shete <pshete@nvidia.com> > Cc: adrian.hunter@intel.com; thierry.reding@gmail.com; Jonathan Hunter > <jonathanh@nvidia.com>; p.zabel@pengutronix.de; linux- > mmc@vger.kernel.org; linux-tegra@vger.kernel.org; linux- > kernel@vger.kernel.org; Aniruddha Tvs Rao <anrao@nvidia.com>; Suresh > Mangipudi <smangipudi@nvidia.com>; Krishna Yarlagadda > <kyarlagadda@nvidia.com> > Subject: Re: [PATCH v7 2/4] mmc: sdhci-tegra: Add support to program MC > stream ID > > External email: Use caution opening links or attachments > > > On Thu, 6 Oct 2022 at 15:07, Prathamesh Shete <pshete@nvidia.com> wrote: > > > > SMMU clients are supposed to program stream ID from their respective > > address spaces instead of MC override. > > Define NVQUIRK_PROGRAM_STREAMID and use it to program SMMU stream > ID > > from the SDMMC client address space. > > > > Signed-off-by: Aniruddha TVS Rao <anrao@nvidia.com> > > Signed-off-by: Prathamesh Shete <pshete@nvidia.com> > > Acked-by: Adrian Hunter <adrian.hunter@intel.com> > > Acked-by: Thierry Reding <treding@nvidia.com> > > --- > > drivers/mmc/host/sdhci-tegra.c | 53 > > ++++++++++++++++++++++++++++++++++ > > 1 file changed, 53 insertions(+) > > > > diff --git a/drivers/mmc/host/sdhci-tegra.c > > b/drivers/mmc/host/sdhci-tegra.c index a6c5bbae77b4..e88294a6912d > > 100644 > > --- a/drivers/mmc/host/sdhci-tegra.c > > +++ b/drivers/mmc/host/sdhci-tegra.c > > @@ -25,6 +25,10 @@ > > #include <linux/mmc/slot-gpio.h> > > #include <linux/gpio/consumer.h> > > #include <linux/ktime.h> > > +#ifdef CONFIG_IOMMU_API > > +#include <linux/iommu.h> > > +#include <linux/bitops.h> > > +#endif > > > > #include <soc/tegra/common.h> > > > > @@ -94,6 +98,8 @@ > > #define SDHCI_TEGRA_AUTO_CAL_STATUS 0x1ec > > #define SDHCI_TEGRA_AUTO_CAL_ACTIVE BIT(31) > > > > +#define SDHCI_TEGRA_CIF2AXI_CTRL_0 0x1fc > > + > > #define NVQUIRK_FORCE_SDHCI_SPEC_200 BIT(0) > > #define NVQUIRK_ENABLE_BLOCK_GAP_DET BIT(1) > > #define NVQUIRK_ENABLE_SDHCI_SPEC_300 BIT(2) > > @@ -121,6 +127,7 @@ > > #define NVQUIRK_HAS_TMCLK BIT(10) > > > > #define NVQUIRK_HAS_ANDROID_GPT_SECTOR BIT(11) > > +#define NVQUIRK_PROGRAM_STREAMID BIT(12) > > > > /* SDMMC CQE Base Address for Tegra Host Ver 4.1 and Higher */ > > #define SDHCI_TEGRA_CQE_BASE_ADDR 0xF000 > > @@ -177,6 +184,9 @@ struct sdhci_tegra { > > bool enable_hwcq; > > unsigned long curr_clk_rate; > > u8 tuned_tap_delay; > > +#ifdef CONFIG_IOMMU_API > > I would rather avoid these kinds of "#ifdef" micro optimizations. > Please just add the streamid without the #ifdef. > > > + u32 streamid; > > +#endif > > }; > > > > static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg) @@ > > -1564,6 +1574,7 @@ static const struct sdhci_tegra_soc_data > soc_data_tegra234 = { > > NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | > > NVQUIRK_ENABLE_SDR50 | > > NVQUIRK_ENABLE_SDR104 | > > + NVQUIRK_PROGRAM_STREAMID | > > NVQUIRK_HAS_TMCLK, > > .min_tap_delay = 95, > > .max_tap_delay = 111, > > @@ -1775,6 +1786,25 @@ static int sdhci_tegra_probe(struct > platform_device *pdev) > > if (rc) > > goto err_add_host; > > > > + /* Program MC streamID for DMA transfers */ #ifdef > > +CONFIG_IOMMU_API > > Again, please drop the #ifdefs here. > > We already have stub functions for dev_iommu_fwspec_get() in case > CONFIG_IOMMU_API is unset. > > > + if (soc_data->nvquirks & NVQUIRK_PROGRAM_STREAMID) { > > + struct iommu_fwspec *fwspec; > > + > > + fwspec = dev_iommu_fwspec_get(&pdev->dev); > > + if (fwspec == NULL) { > > + dev_warn(mmc_dev(host->mmc), > > + "iommu fwspec is NULL, continue without stream ID\n"); > > + } else { > > + tegra_host->streamid = fwspec->ids[0] & 0xff; > > + tegra_sdhci_writel(host, tegra_host->streamid | > > + FIELD_PREP(GENMASK(15, 8), > > + tegra_host->streamid), > > + SDHCI_TEGRA_CIF2AXI_CTRL_0); > > + } > > + } > > +#endif > > + > > return 0; > > > > err_add_host: > > @@ -1861,6 +1891,10 @@ static int sdhci_tegra_suspend(struct device > > *dev) static int sdhci_tegra_resume(struct device *dev) { > > struct sdhci_host *host = dev_get_drvdata(dev); > > +#ifdef CONFIG_IOMMU_API > > Ditto. > > > + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); > > + struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host); > > +#endif > > int ret; > > > > ret = mmc_gpio_set_cd_wake(host->mmc, false); > > @@ -1871,6 +1905,25 @@ static int sdhci_tegra_resume(struct device *dev) > > if (ret) > > return ret; > > > > + /* Re-program MC streamID for DMA transfers */ > > +#ifdef CONFIG_IOMMU_API > > Ditto. > > > + if (tegra_host->soc_data->nvquirks & NVQUIRK_PROGRAM_STREAMID) { > > + struct iommu_fwspec *fwspec; > > + > > + fwspec = dev_iommu_fwspec_get(dev); > > + if (fwspec == NULL) { > > + dev_warn(mmc_dev(host->mmc), > > + "iommu fwspec is NULL, continue without stream ID\n"); > > + } else { > > + tegra_host->streamid = fwspec->ids[0] & 0xff; > > + tegra_sdhci_writel(host, tegra_host->streamid | > > + FIELD_PREP(GENMASK(15, 8), > > + tegra_host->streamid), > > + SDHCI_TEGRA_CIF2AXI_CTRL_0); > > + } > > + } > > +#endif > > + > > ret = sdhci_resume_host(host); > > if (ret) > > goto disable_clk; > > -- > > 2.17.1 > > > > Kind regards > Uffe
On Tue, 11 Oct 2022 at 13:44, Prathamesh Shete <pshete@nvidia.com> wrote: > > Hi Ulf > > The initial patches were without the #ifdef. #ifdef is being added as per review comments and kernel robot errors. > Following error was detected by kernel robot > >> > All errors (new ones prefixed by >>): > > drivers/mmc/host/sdhci-tegra.c: In function 'sdhci_tegra_probe': > >> drivers/mmc/host/sdhci-tegra.c:1794:54: error: 'struct iommu_fwspec' has no member named 'ids' > 1794 | tegra_host->streamid = fwspec->ids[0] & 0xffff; > | ^~ > > > vim +1794 drivers/mmc/host/sdhci-tegra.c > >> > Adrian also pointed out this issue so to address these issues #ifdef was added I see! In that case, perhaps we can add a "depends on IOMMU_API" in the Kconfig instead? Or is the tegra driver used on platforms where IOMMU_API could be unset? [...] Kind regards Uffe
Hi Ulf, >> In that case, perhaps we can add a "depends on IOMMU_API" in the Kconfig >> instead? Or is the tegra driver used on platforms where IOMMU_API could be >> unset? Yes it can/will work with IOMMU disabled so its not recommended to add a "depends on" condition in Kconfig. Thanks Prathamesh > -----Original Message----- > From: Ulf Hansson <ulf.hansson@linaro.org> > Sent: Tuesday, October 11, 2022 6:04 PM > To: Prathamesh Shete <pshete@nvidia.com> > Cc: adrian.hunter@intel.com; thierry.reding@gmail.com; Jonathan Hunter > <jonathanh@nvidia.com>; p.zabel@pengutronix.de; linux- > mmc@vger.kernel.org; linux-tegra@vger.kernel.org; linux- > kernel@vger.kernel.org; Aniruddha Tvs Rao <anrao@nvidia.com>; Suresh > Mangipudi <smangipudi@nvidia.com>; Krishna Yarlagadda > <kyarlagadda@nvidia.com> > Subject: Re: [PATCH v7 2/4] mmc: sdhci-tegra: Add support to program MC > stream ID > > External email: Use caution opening links or attachments > > > On Tue, 11 Oct 2022 at 13:44, Prathamesh Shete <pshete@nvidia.com> wrote: > > > > Hi Ulf > > > > The initial patches were without the #ifdef. #ifdef is being added as per review > comments and kernel robot errors. > > Following error was detected by kernel robot > > >> > > All errors (new ones prefixed by >>): > > > > drivers/mmc/host/sdhci-tegra.c: In function 'sdhci_tegra_probe': > > >> drivers/mmc/host/sdhci-tegra.c:1794:54: error: 'struct iommu_fwspec' has > no member named 'ids' > > 1794 | tegra_host->streamid = fwspec->ids[0] & 0xffff; > > | ^~ > > > > > > vim +1794 drivers/mmc/host/sdhci-tegra.c > > >> > > Adrian also pointed out this issue so to address these issues #ifdef > > was added > > I see! > > In that case, perhaps we can add a "depends on IOMMU_API" in the Kconfig > instead? Or is the tegra driver used on platforms where IOMMU_API could be > unset? > > [...] > > Kind regards > Uffe
On Thu, 13 Oct 2022 at 08:33, Prathamesh Shete <pshete@nvidia.com> wrote: > > Hi Ulf, > > >> In that case, perhaps we can add a "depends on IOMMU_API" in the Kconfig > >> instead? Or is the tegra driver used on platforms where IOMMU_API could be > >> unset? > Yes it can/will work with IOMMU disabled so its not recommended to add a "depends on" condition in Kconfig. Alright, in that case it looks to me that there are two other options to move forward. 1) Add proper definitions of the struct iommu_fwspec in include/linux/iommu.h even when CONFIG_IOMMU_API is unset. In a way it seems a bit silly to me, to have the iommu stubs around, unless those can be used for cases like this, right!? 2) Move the code within the "ifdef CONFIG_IOMMU_API" sections into separate functions - and add stubs for these functions too. In this way the functions can be called, independently of whether CONFIG_IOMMU_API is set/unse, which would make the code in drivers/mmc/host/sdhci-tegra.c cleaner and thus easier to maintain. > > Thanks > Prathamesh > > > -----Original Message----- > > From: Ulf Hansson <ulf.hansson@linaro.org> > > Sent: Tuesday, October 11, 2022 6:04 PM > > To: Prathamesh Shete <pshete@nvidia.com> > > Cc: adrian.hunter@intel.com; thierry.reding@gmail.com; Jonathan Hunter > > <jonathanh@nvidia.com>; p.zabel@pengutronix.de; linux- > > mmc@vger.kernel.org; linux-tegra@vger.kernel.org; linux- > > kernel@vger.kernel.org; Aniruddha Tvs Rao <anrao@nvidia.com>; Suresh > > Mangipudi <smangipudi@nvidia.com>; Krishna Yarlagadda > > <kyarlagadda@nvidia.com> > > Subject: Re: [PATCH v7 2/4] mmc: sdhci-tegra: Add support to program MC > > stream ID > > > > External email: Use caution opening links or attachments > > > > > > On Tue, 11 Oct 2022 at 13:44, Prathamesh Shete <pshete@nvidia.com> wrote: > > > > > > Hi Ulf > > > > > > The initial patches were without the #ifdef. #ifdef is being added as per review > > comments and kernel robot errors. > > > Following error was detected by kernel robot > > > >> > > > All errors (new ones prefixed by >>): > > > > > > drivers/mmc/host/sdhci-tegra.c: In function 'sdhci_tegra_probe': > > > >> drivers/mmc/host/sdhci-tegra.c:1794:54: error: 'struct iommu_fwspec' has > > no member named 'ids' > > > 1794 | tegra_host->streamid = fwspec->ids[0] & 0xffff; > > > | ^~ > > > > > > > > > vim +1794 drivers/mmc/host/sdhci-tegra.c > > > >> > > > Adrian also pointed out this issue so to address these issues #ifdef > > > was added > > > > I see! > > > > In that case, perhaps we can add a "depends on IOMMU_API" in the Kconfig > > instead? Or is the tegra driver used on platforms where IOMMU_API could be > > unset? > > > > [...] Kind regards Uffe
On Thu, Oct 13, 2022 at 03:43:18PM +0200, Ulf Hansson wrote: > On Thu, 13 Oct 2022 at 08:33, Prathamesh Shete <pshete@nvidia.com> wrote: > > > > Hi Ulf, > > > > >> In that case, perhaps we can add a "depends on IOMMU_API" in the Kconfig > > >> instead? Or is the tegra driver used on platforms where IOMMU_API could be > > >> unset? > > Yes it can/will work with IOMMU disabled so its not recommended to add a "depends on" condition in Kconfig. > > Alright, in that case it looks to me that there are two other options > to move forward. > > 1) Add proper definitions of the struct iommu_fwspec in > include/linux/iommu.h even when CONFIG_IOMMU_API is unset. In a way it > seems a bit silly to me, to have the iommu stubs around, unless those > can be used for cases like this, right!? I recall that I had proposed a patch for this a long time ago: https://lore.kernel.org/all/20191209120005.2254786-3-thierry.reding@gmail.com/ Given that Joerg had acked it at the time, I think the only reason why it never ended up getting merged is because the rest of the series did not get enough traction. I wonder if I should peel it out of the series and propose it separately. I agree it doesn't make any sense to have the stubs to allow compilation and then break compilation because users of the stubs will end up wanting to dereference the structure. Thierry
On Mon, 17 Oct 2022 at 16:11, Thierry Reding <thierry.reding@gmail.com> wrote: > > On Thu, Oct 13, 2022 at 03:43:18PM +0200, Ulf Hansson wrote: > > On Thu, 13 Oct 2022 at 08:33, Prathamesh Shete <pshete@nvidia.com> wrote: > > > > > > Hi Ulf, > > > > > > >> In that case, perhaps we can add a "depends on IOMMU_API" in the Kconfig > > > >> instead? Or is the tegra driver used on platforms where IOMMU_API could be > > > >> unset? > > > Yes it can/will work with IOMMU disabled so its not recommended to add a "depends on" condition in Kconfig. > > > > Alright, in that case it looks to me that there are two other options > > to move forward. > > > > 1) Add proper definitions of the struct iommu_fwspec in > > include/linux/iommu.h even when CONFIG_IOMMU_API is unset. In a way it > > seems a bit silly to me, to have the iommu stubs around, unless those > > can be used for cases like this, right!? > > I recall that I had proposed a patch for this a long time ago: > > https://lore.kernel.org/all/20191209120005.2254786-3-thierry.reding@gmail.com/ That looks exactly what we would need! > > Given that Joerg had acked it at the time, I think the only reason why > it never ended up getting merged is because the rest of the series did > not get enough traction. I wonder if I should peel it out of the series > and propose it separately. Yes, please. > > I agree it doesn't make any sense to have the stubs to allow compilation > and then break compilation because users of the stubs will end up > wanting to dereference the structure. Thanks for sharing your thoughts around this! If you submit a new version of the old patch, I would certainly give it my blessing. Kind regards Uffe
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index a6c5bbae77b4..e88294a6912d 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -25,6 +25,10 @@ #include <linux/mmc/slot-gpio.h> #include <linux/gpio/consumer.h> #include <linux/ktime.h> +#ifdef CONFIG_IOMMU_API +#include <linux/iommu.h> +#include <linux/bitops.h> +#endif #include <soc/tegra/common.h> @@ -94,6 +98,8 @@ #define SDHCI_TEGRA_AUTO_CAL_STATUS 0x1ec #define SDHCI_TEGRA_AUTO_CAL_ACTIVE BIT(31) +#define SDHCI_TEGRA_CIF2AXI_CTRL_0 0x1fc + #define NVQUIRK_FORCE_SDHCI_SPEC_200 BIT(0) #define NVQUIRK_ENABLE_BLOCK_GAP_DET BIT(1) #define NVQUIRK_ENABLE_SDHCI_SPEC_300 BIT(2) @@ -121,6 +127,7 @@ #define NVQUIRK_HAS_TMCLK BIT(10) #define NVQUIRK_HAS_ANDROID_GPT_SECTOR BIT(11) +#define NVQUIRK_PROGRAM_STREAMID BIT(12) /* SDMMC CQE Base Address for Tegra Host Ver 4.1 and Higher */ #define SDHCI_TEGRA_CQE_BASE_ADDR 0xF000 @@ -177,6 +184,9 @@ struct sdhci_tegra { bool enable_hwcq; unsigned long curr_clk_rate; u8 tuned_tap_delay; +#ifdef CONFIG_IOMMU_API + u32 streamid; +#endif }; static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg) @@ -1564,6 +1574,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra234 = { NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | NVQUIRK_ENABLE_SDR50 | NVQUIRK_ENABLE_SDR104 | + NVQUIRK_PROGRAM_STREAMID | NVQUIRK_HAS_TMCLK, .min_tap_delay = 95, .max_tap_delay = 111, @@ -1775,6 +1786,25 @@ static int sdhci_tegra_probe(struct platform_device *pdev) if (rc) goto err_add_host; + /* Program MC streamID for DMA transfers */ +#ifdef CONFIG_IOMMU_API + if (soc_data->nvquirks & NVQUIRK_PROGRAM_STREAMID) { + struct iommu_fwspec *fwspec; + + fwspec = dev_iommu_fwspec_get(&pdev->dev); + if (fwspec == NULL) { + dev_warn(mmc_dev(host->mmc), + "iommu fwspec is NULL, continue without stream ID\n"); + } else { + tegra_host->streamid = fwspec->ids[0] & 0xff; + tegra_sdhci_writel(host, tegra_host->streamid | + FIELD_PREP(GENMASK(15, 8), + tegra_host->streamid), + SDHCI_TEGRA_CIF2AXI_CTRL_0); + } + } +#endif + return 0; err_add_host: @@ -1861,6 +1891,10 @@ static int sdhci_tegra_suspend(struct device *dev) static int sdhci_tegra_resume(struct device *dev) { struct sdhci_host *host = dev_get_drvdata(dev); +#ifdef CONFIG_IOMMU_API + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host); +#endif int ret; ret = mmc_gpio_set_cd_wake(host->mmc, false); @@ -1871,6 +1905,25 @@ static int sdhci_tegra_resume(struct device *dev) if (ret) return ret; + /* Re-program MC streamID for DMA transfers */ +#ifdef CONFIG_IOMMU_API + if (tegra_host->soc_data->nvquirks & NVQUIRK_PROGRAM_STREAMID) { + struct iommu_fwspec *fwspec; + + fwspec = dev_iommu_fwspec_get(dev); + if (fwspec == NULL) { + dev_warn(mmc_dev(host->mmc), + "iommu fwspec is NULL, continue without stream ID\n"); + } else { + tegra_host->streamid = fwspec->ids[0] & 0xff; + tegra_sdhci_writel(host, tegra_host->streamid | + FIELD_PREP(GENMASK(15, 8), + tegra_host->streamid), + SDHCI_TEGRA_CIF2AXI_CTRL_0); + } + } +#endif + ret = sdhci_resume_host(host); if (ret) goto disable_clk;