Message ID | 20190306225009.3391-2-digetx@gmail.com |
---|---|
State | Deferred |
Headers | show |
Series | IOMMU: Tegra SMMU fixes | expand |
On Thu, Mar 07, 2019 at 01:50:07AM +0300, Dmitry Osipenko wrote: > Both Tegra30 and Tegra114 have 4 ASID's and the corresponding bitfield of > the TLB_FLUSH register differs from later Tegra generations that have 128 > ASID's. > > In a result the PTE's are now flushed correctly from TLB and this fixes > problems with graphics (randomly failing tests) on Tegra30. > > Cc: stable <stable@vger.kernel.org> > Signed-off-by: Dmitry Osipenko <digetx@gmail.com> > --- > drivers/iommu/tegra-smmu.c | 25 ++++++++++++++++++------- > 1 file changed, 18 insertions(+), 7 deletions(-) > > diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c > index 5182c7d6171e..8d30653cd13a 100644 > --- a/drivers/iommu/tegra-smmu.c > +++ b/drivers/iommu/tegra-smmu.c > @@ -102,7 +102,6 @@ static inline u32 smmu_readl(struct tegra_smmu *smmu, unsigned long offset) > #define SMMU_TLB_FLUSH_VA_MATCH_ALL (0 << 0) > #define SMMU_TLB_FLUSH_VA_MATCH_SECTION (2 << 0) > #define SMMU_TLB_FLUSH_VA_MATCH_GROUP (3 << 0) > -#define SMMU_TLB_FLUSH_ASID(x) (((x) & 0x7f) << 24) Given that the same operation is repeated three times below, it might have been worth to fold the conditional into the macro. That'd require the macro to take an smmu parameter, but would otherwise leave the individual instances shorter. But either way, the fix is good, so: Acked-by: Thierry Reding <treding@nvidia.com>
03.04.2019 11:41, Thierry Reding пишет: > On Thu, Mar 07, 2019 at 01:50:07AM +0300, Dmitry Osipenko wrote: >> Both Tegra30 and Tegra114 have 4 ASID's and the corresponding bitfield of >> the TLB_FLUSH register differs from later Tegra generations that have 128 >> ASID's. >> >> In a result the PTE's are now flushed correctly from TLB and this fixes >> problems with graphics (randomly failing tests) on Tegra30. >> >> Cc: stable <stable@vger.kernel.org> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> >> --- >> drivers/iommu/tegra-smmu.c | 25 ++++++++++++++++++------- >> 1 file changed, 18 insertions(+), 7 deletions(-) >> >> diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c >> index 5182c7d6171e..8d30653cd13a 100644 >> --- a/drivers/iommu/tegra-smmu.c >> +++ b/drivers/iommu/tegra-smmu.c >> @@ -102,7 +102,6 @@ static inline u32 smmu_readl(struct tegra_smmu *smmu, unsigned long offset) >> #define SMMU_TLB_FLUSH_VA_MATCH_ALL (0 << 0) >> #define SMMU_TLB_FLUSH_VA_MATCH_SECTION (2 << 0) >> #define SMMU_TLB_FLUSH_VA_MATCH_GROUP (3 << 0) >> -#define SMMU_TLB_FLUSH_ASID(x) (((x) & 0x7f) << 24) > > Given that the same operation is repeated three times below, it might > have been worth to fold the conditional into the macro. That'd require > the macro to take an smmu parameter, but would otherwise leave the > individual instances shorter. I had that variant initially and the result felt more clumsy to me. > But either way, the fix is good, so: > > Acked-by: Thierry Reding <treding@nvidia.com> > Thanks
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 5182c7d6171e..8d30653cd13a 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -102,7 +102,6 @@ static inline u32 smmu_readl(struct tegra_smmu *smmu, unsigned long offset) #define SMMU_TLB_FLUSH_VA_MATCH_ALL (0 << 0) #define SMMU_TLB_FLUSH_VA_MATCH_SECTION (2 << 0) #define SMMU_TLB_FLUSH_VA_MATCH_GROUP (3 << 0) -#define SMMU_TLB_FLUSH_ASID(x) (((x) & 0x7f) << 24) #define SMMU_TLB_FLUSH_VA_SECTION(addr) ((((addr) & 0xffc00000) >> 12) | \ SMMU_TLB_FLUSH_VA_MATCH_SECTION) #define SMMU_TLB_FLUSH_VA_GROUP(addr) ((((addr) & 0xffffc000) >> 12) | \ @@ -205,8 +204,12 @@ static inline void smmu_flush_tlb_asid(struct tegra_smmu *smmu, { u32 value; - value = SMMU_TLB_FLUSH_ASID_MATCH | SMMU_TLB_FLUSH_ASID(asid) | - SMMU_TLB_FLUSH_VA_MATCH_ALL; + if (smmu->soc->num_asids == 4) + value = (asid & 0x3) << 29; + else + value = (asid & 0x7f) << 24; + + value |= SMMU_TLB_FLUSH_ASID_MATCH | SMMU_TLB_FLUSH_VA_MATCH_ALL; smmu_writel(smmu, value, SMMU_TLB_FLUSH); } @@ -216,8 +219,12 @@ static inline void smmu_flush_tlb_section(struct tegra_smmu *smmu, { u32 value; - value = SMMU_TLB_FLUSH_ASID_MATCH | SMMU_TLB_FLUSH_ASID(asid) | - SMMU_TLB_FLUSH_VA_SECTION(iova); + if (smmu->soc->num_asids == 4) + value = (asid & 0x3) << 29; + else + value = (asid & 0x7f) << 24; + + value |= SMMU_TLB_FLUSH_ASID_MATCH | SMMU_TLB_FLUSH_VA_SECTION(iova); smmu_writel(smmu, value, SMMU_TLB_FLUSH); } @@ -227,8 +234,12 @@ static inline void smmu_flush_tlb_group(struct tegra_smmu *smmu, { u32 value; - value = SMMU_TLB_FLUSH_ASID_MATCH | SMMU_TLB_FLUSH_ASID(asid) | - SMMU_TLB_FLUSH_VA_GROUP(iova); + if (smmu->soc->num_asids == 4) + value = (asid & 0x3) << 29; + else + value = (asid & 0x7f) << 24; + + value |= SMMU_TLB_FLUSH_ASID_MATCH | SMMU_TLB_FLUSH_VA_GROUP(iova); smmu_writel(smmu, value, SMMU_TLB_FLUSH); }
Both Tegra30 and Tegra114 have 4 ASID's and the corresponding bitfield of the TLB_FLUSH register differs from later Tegra generations that have 128 ASID's. In a result the PTE's are now flushed correctly from TLB and this fixes problems with graphics (randomly failing tests) on Tegra30. Cc: stable <stable@vger.kernel.org> Signed-off-by: Dmitry Osipenko <digetx@gmail.com> --- drivers/iommu/tegra-smmu.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)