Commit 7bc4f3fa authored by Jean-Philippe Brucker's avatar Jean-Philippe Brucker Committed by Will Deacon

iommu/arm-smmu-v3: Prepare arm_smmu_s1_cfg for SSID support

When adding SSID support to the SMMUv3 driver, we'll need to manipulate
leaf pasid tables and context descriptors. Extract the context
descriptor structure and align with the way stream tables are handled.
Signed-off-by: default avatarJean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent da22565d
...@@ -542,16 +542,21 @@ struct arm_smmu_strtab_l1_desc { ...@@ -542,16 +542,21 @@ struct arm_smmu_strtab_l1_desc {
dma_addr_t l2ptr_dma; dma_addr_t l2ptr_dma;
}; };
struct arm_smmu_ctx_desc {
u16 asid;
u64 ttbr;
u64 tcr;
u64 mair;
};
struct arm_smmu_ctx_desc_cfg {
__le64 *cdtab;
dma_addr_t cdtab_dma;
};
struct arm_smmu_s1_cfg { struct arm_smmu_s1_cfg {
__le64 *cdptr; struct arm_smmu_ctx_desc_cfg cdcfg;
dma_addr_t cdptr_dma; struct arm_smmu_ctx_desc cd;
struct arm_smmu_ctx_desc {
u16 asid;
u64 ttbr;
u64 tcr;
u64 mair;
} cd;
}; };
struct arm_smmu_s2_cfg { struct arm_smmu_s2_cfg {
...@@ -1444,6 +1449,7 @@ static void arm_smmu_write_ctx_desc(struct arm_smmu_device *smmu, ...@@ -1444,6 +1449,7 @@ static void arm_smmu_write_ctx_desc(struct arm_smmu_device *smmu,
struct arm_smmu_s1_cfg *cfg) struct arm_smmu_s1_cfg *cfg)
{ {
u64 val; u64 val;
__le64 *cdptr = cfg->cdcfg.cdtab;
/* /*
* We don't need to issue any invalidation here, as we'll invalidate * We don't need to issue any invalidation here, as we'll invalidate
...@@ -1461,12 +1467,12 @@ static void arm_smmu_write_ctx_desc(struct arm_smmu_device *smmu, ...@@ -1461,12 +1467,12 @@ static void arm_smmu_write_ctx_desc(struct arm_smmu_device *smmu,
if (smmu->features & ARM_SMMU_FEAT_STALL_FORCE) if (smmu->features & ARM_SMMU_FEAT_STALL_FORCE)
val |= CTXDESC_CD_0_S; val |= CTXDESC_CD_0_S;
cfg->cdptr[0] = cpu_to_le64(val); cdptr[0] = cpu_to_le64(val);
val = cfg->cd.ttbr & CTXDESC_CD_1_TTB0_MASK; val = cfg->cd.ttbr & CTXDESC_CD_1_TTB0_MASK;
cfg->cdptr[1] = cpu_to_le64(val); cdptr[1] = cpu_to_le64(val);
cfg->cdptr[3] = cpu_to_le64(cfg->cd.mair); cdptr[3] = cpu_to_le64(cfg->cd.mair);
} }
/* Stream table manipulation functions */ /* Stream table manipulation functions */
...@@ -1597,7 +1603,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid, ...@@ -1597,7 +1603,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
!(smmu->features & ARM_SMMU_FEAT_STALL_FORCE)) !(smmu->features & ARM_SMMU_FEAT_STALL_FORCE))
dst[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD); dst[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
val |= (s1_cfg->cdptr_dma & STRTAB_STE_0_S1CTXPTR_MASK) | val |= (s1_cfg->cdcfg.cdtab_dma & STRTAB_STE_0_S1CTXPTR_MASK) |
FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS); FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS);
} }
...@@ -2111,11 +2117,11 @@ static void arm_smmu_domain_free(struct iommu_domain *domain) ...@@ -2111,11 +2117,11 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) { if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg; struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
if (cfg->cdptr) { if (cfg->cdcfg.cdtab) {
dmam_free_coherent(smmu_domain->smmu->dev, dmam_free_coherent(smmu_domain->smmu->dev,
CTXDESC_CD_DWORDS << 3, CTXDESC_CD_DWORDS << 3,
cfg->cdptr, cfg->cdcfg.cdtab,
cfg->cdptr_dma); cfg->cdcfg.cdtab_dma);
arm_smmu_bitmap_free(smmu->asid_map, cfg->cd.asid); arm_smmu_bitmap_free(smmu->asid_map, cfg->cd.asid);
} }
...@@ -2141,9 +2147,11 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain, ...@@ -2141,9 +2147,11 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
if (asid < 0) if (asid < 0)
return asid; return asid;
cfg->cdptr = dmam_alloc_coherent(smmu->dev, CTXDESC_CD_DWORDS << 3, cfg->cdcfg.cdtab = dmam_alloc_coherent(smmu->dev,
&cfg->cdptr_dma, GFP_KERNEL); CTXDESC_CD_DWORDS << 3,
if (!cfg->cdptr) { &cfg->cdcfg.cdtab_dma,
GFP_KERNEL);
if (!cfg->cdcfg.cdtab) {
dev_warn(smmu->dev, "failed to allocate context descriptor\n"); dev_warn(smmu->dev, "failed to allocate context descriptor\n");
ret = -ENOMEM; ret = -ENOMEM;
goto out_free_asid; goto out_free_asid;
......
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