diff mbox series

[v7,2/4] mmc: sdhci-tegra: Add support to program MC stream ID

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

Commit Message

Prathamesh Shete Oct. 6, 2022, 1:06 p.m. UTC
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(+)

Comments

Ulf Hansson Oct. 11, 2022, 9:58 a.m. UTC | #1
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
Prathamesh Shete Oct. 11, 2022, 11:44 a.m. UTC | #2
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
Ulf Hansson Oct. 11, 2022, 12:33 p.m. UTC | #3
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
Prathamesh Shete Oct. 13, 2022, 6:33 a.m. UTC | #4
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
Ulf Hansson Oct. 13, 2022, 1:43 p.m. UTC | #5
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
Thierry Reding Oct. 17, 2022, 2:11 p.m. UTC | #6
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
Ulf Hansson Oct. 18, 2022, 10:10 a.m. UTC | #7
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 mbox series

Patch

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;