|
@@ -24,7 +24,7 @@
|
|
* - v7/v8 long-descriptor format
|
|
* - v7/v8 long-descriptor format
|
|
* - Non-secure access to the SMMU
|
|
* - Non-secure access to the SMMU
|
|
* - 4k and 64k pages, with contiguous pte hints.
|
|
* - 4k and 64k pages, with contiguous pte hints.
|
|
- * - Up to 42-bit addressing (dependent on VA_BITS)
|
|
|
|
|
|
+ * - Up to 48-bit addressing (dependent on VA_BITS)
|
|
* - Context fault reporting
|
|
* - Context fault reporting
|
|
*/
|
|
*/
|
|
|
|
|
|
@@ -375,8 +375,9 @@ struct arm_smmu_device {
|
|
u32 num_mapping_groups;
|
|
u32 num_mapping_groups;
|
|
DECLARE_BITMAP(smr_map, ARM_SMMU_MAX_SMRS);
|
|
DECLARE_BITMAP(smr_map, ARM_SMMU_MAX_SMRS);
|
|
|
|
|
|
- unsigned long input_size;
|
|
|
|
|
|
+ unsigned long s1_input_size;
|
|
unsigned long s1_output_size;
|
|
unsigned long s1_output_size;
|
|
|
|
+ unsigned long s2_input_size;
|
|
unsigned long s2_output_size;
|
|
unsigned long s2_output_size;
|
|
|
|
|
|
u32 num_global_irqs;
|
|
u32 num_global_irqs;
|
|
@@ -762,7 +763,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
|
|
gr1_base + ARM_SMMU_GR1_CBA2R(cfg->cbndx));
|
|
gr1_base + ARM_SMMU_GR1_CBA2R(cfg->cbndx));
|
|
|
|
|
|
/* TTBCR2 */
|
|
/* TTBCR2 */
|
|
- switch (smmu->input_size) {
|
|
|
|
|
|
+ switch (smmu->s1_input_size) {
|
|
case 32:
|
|
case 32:
|
|
reg = (TTBCR2_ADDR_32 << TTBCR2_SEP_SHIFT);
|
|
reg = (TTBCR2_ADDR_32 << TTBCR2_SEP_SHIFT);
|
|
break;
|
|
break;
|
|
@@ -831,7 +832,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
|
|
reg = TTBCR_TG0_64K;
|
|
reg = TTBCR_TG0_64K;
|
|
|
|
|
|
if (!stage1) {
|
|
if (!stage1) {
|
|
- reg |= (64 - smmu->s1_output_size) << TTBCR_T0SZ_SHIFT;
|
|
|
|
|
|
+ reg |= (64 - smmu->s2_input_size) << TTBCR_T0SZ_SHIFT;
|
|
|
|
|
|
switch (smmu->s2_output_size) {
|
|
switch (smmu->s2_output_size) {
|
|
case 32:
|
|
case 32:
|
|
@@ -854,7 +855,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- reg |= (64 - smmu->input_size) << TTBCR_T0SZ_SHIFT;
|
|
|
|
|
|
+ reg |= (64 - smmu->s1_input_size) << TTBCR_T0SZ_SHIFT;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
reg = 0;
|
|
reg = 0;
|
|
@@ -1454,9 +1455,11 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
|
|
|
|
|
|
if (cfg->cbar == CBAR_TYPE_S2_TRANS) {
|
|
if (cfg->cbar == CBAR_TYPE_S2_TRANS) {
|
|
stage = 2;
|
|
stage = 2;
|
|
|
|
+ input_mask = (1ULL << smmu->s2_input_size) - 1;
|
|
output_mask = (1ULL << smmu->s2_output_size) - 1;
|
|
output_mask = (1ULL << smmu->s2_output_size) - 1;
|
|
} else {
|
|
} else {
|
|
stage = 1;
|
|
stage = 1;
|
|
|
|
+ input_mask = (1ULL << smmu->s1_input_size) - 1;
|
|
output_mask = (1ULL << smmu->s1_output_size) - 1;
|
|
output_mask = (1ULL << smmu->s1_output_size) - 1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1466,7 +1469,6 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
|
|
if (size & ~PAGE_MASK)
|
|
if (size & ~PAGE_MASK)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- input_mask = (1ULL << smmu->input_size) - 1;
|
|
|
|
if ((phys_addr_t)iova & ~input_mask)
|
|
if ((phys_addr_t)iova & ~input_mask)
|
|
return -ERANGE;
|
|
return -ERANGE;
|
|
|
|
|
|
@@ -1838,28 +1840,21 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
|
|
/* ID2 */
|
|
/* ID2 */
|
|
id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID2);
|
|
id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID2);
|
|
size = arm_smmu_id_size_to_bits((id >> ID2_IAS_SHIFT) & ID2_IAS_MASK);
|
|
size = arm_smmu_id_size_to_bits((id >> ID2_IAS_SHIFT) & ID2_IAS_MASK);
|
|
|
|
+ smmu->s1_output_size = min_t(unsigned long, PHYS_MASK_SHIFT, size);
|
|
|
|
|
|
- /*
|
|
|
|
- * Stage-1 output limited by stage-2 input size due to pgd
|
|
|
|
- * allocation (PTRS_PER_PGD).
|
|
|
|
- */
|
|
|
|
- if (smmu->features & ARM_SMMU_FEAT_TRANS_NESTED) {
|
|
|
|
|
|
+ /* Stage-2 input size limited due to pgd allocation (PTRS_PER_PGD) */
|
|
#ifdef CONFIG_64BIT
|
|
#ifdef CONFIG_64BIT
|
|
- smmu->s1_output_size = min_t(unsigned long, VA_BITS, size);
|
|
|
|
|
|
+ smmu->s2_input_size = min_t(unsigned long, VA_BITS, size);
|
|
#else
|
|
#else
|
|
- smmu->s1_output_size = min(32UL, size);
|
|
|
|
|
|
+ smmu->s2_input_size = min(32UL, size);
|
|
#endif
|
|
#endif
|
|
- } else {
|
|
|
|
- smmu->s1_output_size = min_t(unsigned long, PHYS_MASK_SHIFT,
|
|
|
|
- size);
|
|
|
|
- }
|
|
|
|
|
|
|
|
/* The stage-2 output mask is also applied for bypass */
|
|
/* The stage-2 output mask is also applied for bypass */
|
|
size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK);
|
|
size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK);
|
|
smmu->s2_output_size = min_t(unsigned long, PHYS_MASK_SHIFT, size);
|
|
smmu->s2_output_size = min_t(unsigned long, PHYS_MASK_SHIFT, size);
|
|
|
|
|
|
if (smmu->version == 1) {
|
|
if (smmu->version == 1) {
|
|
- smmu->input_size = 32;
|
|
|
|
|
|
+ smmu->s1_input_size = 32;
|
|
} else {
|
|
} else {
|
|
#ifdef CONFIG_64BIT
|
|
#ifdef CONFIG_64BIT
|
|
size = (id >> ID2_UBS_SHIFT) & ID2_UBS_MASK;
|
|
size = (id >> ID2_UBS_SHIFT) & ID2_UBS_MASK;
|
|
@@ -1867,7 +1862,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
|
|
#else
|
|
#else
|
|
size = 32;
|
|
size = 32;
|
|
#endif
|
|
#endif
|
|
- smmu->input_size = size;
|
|
|
|
|
|
+ smmu->s1_input_size = size;
|
|
|
|
|
|
if ((PAGE_SIZE == SZ_4K && !(id & ID2_PTFS_4K)) ||
|
|
if ((PAGE_SIZE == SZ_4K && !(id & ID2_PTFS_4K)) ||
|
|
(PAGE_SIZE == SZ_64K && !(id & ID2_PTFS_64K)) ||
|
|
(PAGE_SIZE == SZ_64K && !(id & ID2_PTFS_64K)) ||
|
|
@@ -1878,10 +1873,14 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- dev_notice(smmu->dev,
|
|
|
|
- "\t%lu-bit VA, %lu-bit IPA, %lu-bit PA\n",
|
|
|
|
- smmu->input_size, smmu->s1_output_size,
|
|
|
|
- smmu->s2_output_size);
|
|
|
|
|
|
+ if (smmu->features & ARM_SMMU_FEAT_TRANS_S1)
|
|
|
|
+ dev_notice(smmu->dev, "\tStage-1: %lu-bit VA -> %lu-bit IPA\n",
|
|
|
|
+ smmu->s1_input_size, smmu->s1_output_size);
|
|
|
|
+
|
|
|
|
+ if (smmu->features & ARM_SMMU_FEAT_TRANS_S2)
|
|
|
|
+ dev_notice(smmu->dev, "\tStage-2: %lu-bit IPA -> %lu-bit PA\n",
|
|
|
|
+ smmu->s2_input_size, smmu->s2_output_size);
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|