]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iommu/tegra-smmu: Parameterize number of TLB lines
authorThierry Reding <treding@nvidia.com>
Thu, 6 Aug 2015 12:20:31 +0000 (14:20 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 29 Sep 2015 17:33:33 +0000 (19:33 +0200)
commit 11cec15bf3fb498206ef63b1fa26c27689e02d0e upstream.

The number of TLB lines was increased from 16 on Tegra30 to 32 on
Tegra114 and later. Parameterize the value so that the initial default
can be set accordingly.

On Tegra30, initializing the value to 32 would effectively disable the
TLB and hence cause massive latencies for memory accesses translated
through the SMMU. This is especially noticeable for isochronuous clients
such as display, whose FIFOs would continuously underrun.

Fixes: 891846516317 ("memory: Add NVIDIA Tegra memory controller support")
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/iommu/tegra-smmu.c
drivers/memory/tegra/tegra114.c
drivers/memory/tegra/tegra124.c
drivers/memory/tegra/tegra30.c
include/soc/tegra/mc.h

index c1f2e521dc52cdb383b528c27d07f0786e4ffc43..2cd439203d0f936f4a61f192384dbf27ba6e648e 100644 (file)
@@ -27,6 +27,7 @@ struct tegra_smmu {
        const struct tegra_smmu_soc *soc;
 
        unsigned long pfn_mask;
+       unsigned long tlb_mask;
 
        unsigned long *asids;
        struct mutex lock;
@@ -68,7 +69,8 @@ static inline u32 smmu_readl(struct tegra_smmu *smmu, unsigned long offset)
 #define SMMU_TLB_CONFIG 0x14
 #define  SMMU_TLB_CONFIG_HIT_UNDER_MISS (1 << 29)
 #define  SMMU_TLB_CONFIG_ROUND_ROBIN_ARBITRATION (1 << 28)
-#define  SMMU_TLB_CONFIG_ACTIVE_LINES(x) ((x) & 0x3f)
+#define  SMMU_TLB_CONFIG_ACTIVE_LINES(smmu) \
+       ((smmu)->soc->num_tlb_lines & (smmu)->tlb_mask)
 
 #define SMMU_PTC_CONFIG 0x18
 #define  SMMU_PTC_CONFIG_ENABLE (1 << 29)
@@ -816,6 +818,9 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev,
        smmu->pfn_mask = BIT_MASK(mc->soc->num_address_bits - PAGE_SHIFT) - 1;
        dev_dbg(dev, "address bits: %u, PFN mask: %#lx\n",
                mc->soc->num_address_bits, smmu->pfn_mask);
+       smmu->tlb_mask = (smmu->soc->num_tlb_lines << 1) - 1;
+       dev_dbg(dev, "TLB lines: %u, mask: %#lx\n", smmu->soc->num_tlb_lines,
+               smmu->tlb_mask);
 
        value = SMMU_PTC_CONFIG_ENABLE | SMMU_PTC_CONFIG_INDEX_MAP(0x3f);
 
@@ -825,7 +830,7 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev,
        smmu_writel(smmu, value, SMMU_PTC_CONFIG);
 
        value = SMMU_TLB_CONFIG_HIT_UNDER_MISS |
-               SMMU_TLB_CONFIG_ACTIVE_LINES(0x20);
+               SMMU_TLB_CONFIG_ACTIVE_LINES(smmu);
 
        if (soc->supports_round_robin_arbitration)
                value |= SMMU_TLB_CONFIG_ROUND_ROBIN_ARBITRATION;
index 9f579589e8000aaac06333c8d7162bdd5b6041ae..9bf11ea90549ebd447975ef8211dc591f166bc57 100644 (file)
@@ -935,6 +935,7 @@ static const struct tegra_smmu_soc tegra114_smmu_soc = {
        .num_swgroups = ARRAY_SIZE(tegra114_swgroups),
        .supports_round_robin_arbitration = false,
        .supports_request_limit = false,
+       .num_tlb_lines = 32,
        .num_asids = 4,
        .ops = &tegra114_smmu_ops,
 };
index 966e1557e6f414598868a8392b5487cb05e09f61..70ed80d234317ef06bfa80331b060dd9f24d0a43 100644 (file)
@@ -1023,6 +1023,7 @@ static const struct tegra_smmu_soc tegra124_smmu_soc = {
        .num_swgroups = ARRAY_SIZE(tegra124_swgroups),
        .supports_round_robin_arbitration = true,
        .supports_request_limit = true,
+       .num_tlb_lines = 32,
        .num_asids = 128,
        .ops = &tegra124_smmu_ops,
 };
index 1abcd8f6f3ba60ed6cdabcc28478123061af0b63..b2a34fefabefe253399fa2448ec3f5f96c533117 100644 (file)
@@ -957,6 +957,7 @@ static const struct tegra_smmu_soc tegra30_smmu_soc = {
        .num_swgroups = ARRAY_SIZE(tegra30_swgroups),
        .supports_round_robin_arbitration = false,
        .supports_request_limit = false,
+       .num_tlb_lines = 16,
        .num_asids = 4,
        .ops = &tegra30_smmu_ops,
 };
index 1ab2813273cd1cf7d0116ca3d64b08de18013304..bf2058690cebb8601f40398e05e7558c96636f63 100644 (file)
@@ -66,6 +66,7 @@ struct tegra_smmu_soc {
        bool supports_round_robin_arbitration;
        bool supports_request_limit;
 
+       unsigned int num_tlb_lines;
        unsigned int num_asids;
 
        const struct tegra_smmu_ops *ops;