Commit 11cec15b authored by Thierry Reding's avatar Thierry Reding

iommu/tegra-smmu: Parameterize number of TLB lines

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: 89184651 ("memory: Add NVIDIA Tegra memory controller support")
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 4080e99b
...@@ -27,6 +27,7 @@ struct tegra_smmu { ...@@ -27,6 +27,7 @@ struct tegra_smmu {
const struct tegra_smmu_soc *soc; const struct tegra_smmu_soc *soc;
unsigned long pfn_mask; unsigned long pfn_mask;
unsigned long tlb_mask;
unsigned long *asids; unsigned long *asids;
struct mutex lock; struct mutex lock;
...@@ -70,7 +71,8 @@ static inline u32 smmu_readl(struct tegra_smmu *smmu, unsigned long offset) ...@@ -70,7 +71,8 @@ static inline u32 smmu_readl(struct tegra_smmu *smmu, unsigned long offset)
#define SMMU_TLB_CONFIG 0x14 #define SMMU_TLB_CONFIG 0x14
#define SMMU_TLB_CONFIG_HIT_UNDER_MISS (1 << 29) #define SMMU_TLB_CONFIG_HIT_UNDER_MISS (1 << 29)
#define SMMU_TLB_CONFIG_ROUND_ROBIN_ARBITRATION (1 << 28) #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 0x18
#define SMMU_PTC_CONFIG_ENABLE (1 << 29) #define SMMU_PTC_CONFIG_ENABLE (1 << 29)
...@@ -901,6 +903,9 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev, ...@@ -901,6 +903,9 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev,
smmu->pfn_mask = BIT_MASK(mc->soc->num_address_bits - PAGE_SHIFT) - 1; smmu->pfn_mask = BIT_MASK(mc->soc->num_address_bits - PAGE_SHIFT) - 1;
dev_dbg(dev, "address bits: %u, PFN mask: %#lx\n", dev_dbg(dev, "address bits: %u, PFN mask: %#lx\n",
mc->soc->num_address_bits, smmu->pfn_mask); 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); value = SMMU_PTC_CONFIG_ENABLE | SMMU_PTC_CONFIG_INDEX_MAP(0x3f);
...@@ -910,7 +915,7 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev, ...@@ -910,7 +915,7 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev,
smmu_writel(smmu, value, SMMU_PTC_CONFIG); smmu_writel(smmu, value, SMMU_PTC_CONFIG);
value = SMMU_TLB_CONFIG_HIT_UNDER_MISS | 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) if (soc->supports_round_robin_arbitration)
value |= SMMU_TLB_CONFIG_ROUND_ROBIN_ARBITRATION; value |= SMMU_TLB_CONFIG_ROUND_ROBIN_ARBITRATION;
......
...@@ -919,6 +919,7 @@ static const struct tegra_smmu_soc tegra114_smmu_soc = { ...@@ -919,6 +919,7 @@ static const struct tegra_smmu_soc tegra114_smmu_soc = {
.num_swgroups = ARRAY_SIZE(tegra114_swgroups), .num_swgroups = ARRAY_SIZE(tegra114_swgroups),
.supports_round_robin_arbitration = false, .supports_round_robin_arbitration = false,
.supports_request_limit = false, .supports_request_limit = false,
.num_tlb_lines = 32,
.num_asids = 4, .num_asids = 4,
}; };
......
...@@ -1029,6 +1029,7 @@ static const struct tegra_smmu_soc tegra132_smmu_soc = { ...@@ -1029,6 +1029,7 @@ static const struct tegra_smmu_soc tegra132_smmu_soc = {
.num_swgroups = ARRAY_SIZE(tegra124_swgroups), .num_swgroups = ARRAY_SIZE(tegra124_swgroups),
.supports_round_robin_arbitration = true, .supports_round_robin_arbitration = true,
.supports_request_limit = true, .supports_request_limit = true,
.num_tlb_lines = 32,
.num_asids = 128, .num_asids = 128,
}; };
......
...@@ -941,6 +941,7 @@ static const struct tegra_smmu_soc tegra30_smmu_soc = { ...@@ -941,6 +941,7 @@ static const struct tegra_smmu_soc tegra30_smmu_soc = {
.num_swgroups = ARRAY_SIZE(tegra30_swgroups), .num_swgroups = ARRAY_SIZE(tegra30_swgroups),
.supports_round_robin_arbitration = false, .supports_round_robin_arbitration = false,
.supports_request_limit = false, .supports_request_limit = false,
.num_tlb_lines = 16,
.num_asids = 4, .num_asids = 4,
}; };
......
...@@ -61,6 +61,7 @@ struct tegra_smmu_soc { ...@@ -61,6 +61,7 @@ struct tegra_smmu_soc {
bool supports_round_robin_arbitration; bool supports_round_robin_arbitration;
bool supports_request_limit; bool supports_request_limit;
unsigned int num_tlb_lines;
unsigned int num_asids; unsigned int num_asids;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment