|
@@ -404,14 +404,15 @@ enum arm_smmu_context_fmt {
|
|
|
struct arm_smmu_cfg {
|
|
|
u8 cbndx;
|
|
|
u8 irptndx;
|
|
|
+ union {
|
|
|
+ u16 asid;
|
|
|
+ u16 vmid;
|
|
|
+ };
|
|
|
u32 cbar;
|
|
|
enum arm_smmu_context_fmt fmt;
|
|
|
};
|
|
|
#define INVALID_IRPTNDX 0xff
|
|
|
|
|
|
-#define ARM_SMMU_CB_ASID(smmu, cfg) ((u16)(smmu)->cavium_id_base + (cfg)->cbndx)
|
|
|
-#define ARM_SMMU_CB_VMID(smmu, cfg) ((u16)(smmu)->cavium_id_base + (cfg)->cbndx + 1)
|
|
|
-
|
|
|
enum arm_smmu_domain_stage {
|
|
|
ARM_SMMU_DOMAIN_S1 = 0,
|
|
|
ARM_SMMU_DOMAIN_S2,
|
|
@@ -603,12 +604,10 @@ static void arm_smmu_tlb_inv_context(void *cookie)
|
|
|
|
|
|
if (stage1) {
|
|
|
base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
|
|
|
- writel_relaxed(ARM_SMMU_CB_ASID(smmu, cfg),
|
|
|
- base + ARM_SMMU_CB_S1_TLBIASID);
|
|
|
+ writel_relaxed(cfg->asid, base + ARM_SMMU_CB_S1_TLBIASID);
|
|
|
} else {
|
|
|
base = ARM_SMMU_GR0(smmu);
|
|
|
- writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg),
|
|
|
- base + ARM_SMMU_GR0_TLBIVMID);
|
|
|
+ writel_relaxed(cfg->vmid, base + ARM_SMMU_GR0_TLBIVMID);
|
|
|
}
|
|
|
|
|
|
__arm_smmu_tlb_sync(smmu);
|
|
@@ -629,14 +628,14 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
|
|
|
|
|
|
if (cfg->fmt != ARM_SMMU_CTX_FMT_AARCH64) {
|
|
|
iova &= ~12UL;
|
|
|
- iova |= ARM_SMMU_CB_ASID(smmu, cfg);
|
|
|
+ iova |= cfg->asid;
|
|
|
do {
|
|
|
writel_relaxed(iova, reg);
|
|
|
iova += granule;
|
|
|
} while (size -= granule);
|
|
|
} else {
|
|
|
iova >>= 12;
|
|
|
- iova |= (u64)ARM_SMMU_CB_ASID(smmu, cfg) << 48;
|
|
|
+ iova |= (u64)cfg->asid << 48;
|
|
|
do {
|
|
|
writeq_relaxed(iova, reg);
|
|
|
iova += granule >> 12;
|
|
@@ -653,7 +652,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
|
|
|
} while (size -= granule);
|
|
|
} else {
|
|
|
reg = ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_TLBIVMID;
|
|
|
- writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg), reg);
|
|
|
+ writel_relaxed(cfg->vmid, reg);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -735,7 +734,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
|
|
|
reg = CBA2R_RW64_32BIT;
|
|
|
/* 16-bit VMIDs live in CBA2R */
|
|
|
if (smmu->features & ARM_SMMU_FEAT_VMID16)
|
|
|
- reg |= ARM_SMMU_CB_VMID(smmu, cfg) << CBA2R_VMID_SHIFT;
|
|
|
+ reg |= cfg->vmid << CBA2R_VMID_SHIFT;
|
|
|
|
|
|
writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBA2R(cfg->cbndx));
|
|
|
}
|
|
@@ -754,7 +753,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
|
|
|
(CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
|
|
|
} else if (!(smmu->features & ARM_SMMU_FEAT_VMID16)) {
|
|
|
/* 8-bit VMIDs live in CBAR */
|
|
|
- reg |= ARM_SMMU_CB_VMID(smmu, cfg) << CBAR_VMID_SHIFT;
|
|
|
+ reg |= cfg->vmid << CBAR_VMID_SHIFT;
|
|
|
}
|
|
|
writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(cfg->cbndx));
|
|
|
|
|
@@ -783,20 +782,18 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
|
|
|
|
|
|
/* TTBRs */
|
|
|
if (stage1) {
|
|
|
- u16 asid = ARM_SMMU_CB_ASID(smmu, cfg);
|
|
|
-
|
|
|
if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
|
|
|
reg = pgtbl_cfg->arm_v7s_cfg.ttbr[0];
|
|
|
writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0);
|
|
|
reg = pgtbl_cfg->arm_v7s_cfg.ttbr[1];
|
|
|
writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1);
|
|
|
- writel_relaxed(asid, cb_base + ARM_SMMU_CB_CONTEXTIDR);
|
|
|
+ writel_relaxed(cfg->asid, cb_base + ARM_SMMU_CB_CONTEXTIDR);
|
|
|
} else {
|
|
|
reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
|
|
|
- reg64 |= (u64)asid << TTBRn_ASID_SHIFT;
|
|
|
+ reg64 |= (u64)cfg->asid << TTBRn_ASID_SHIFT;
|
|
|
writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR0);
|
|
|
reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
|
|
|
- reg64 |= (u64)asid << TTBRn_ASID_SHIFT;
|
|
|
+ reg64 |= (u64)cfg->asid << TTBRn_ASID_SHIFT;
|
|
|
writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR1);
|
|
|
}
|
|
|
} else {
|
|
@@ -945,6 +942,11 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
|
|
|
cfg->irptndx = cfg->cbndx;
|
|
|
}
|
|
|
|
|
|
+ if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2)
|
|
|
+ cfg->vmid = cfg->cbndx + 1 + smmu->cavium_id_base;
|
|
|
+ else
|
|
|
+ cfg->asid = cfg->cbndx + smmu->cavium_id_base;
|
|
|
+
|
|
|
pgtbl_cfg = (struct io_pgtable_cfg) {
|
|
|
.pgsize_bitmap = smmu->pgsize_bitmap,
|
|
|
.ias = ias,
|