@@ -1458,7 +1458,8 @@ static void arm_smmu_free_cd_tables(struct arm_smmu_master *master)
}
/* Stream table manipulation functions */
-static void arm_smmu_write_strtab_l1_desc(__le64 *dst, dma_addr_t l2ptr_dma)
+static void arm_smmu_write_strtab_l1_desc(struct arm_smmu_strtab_l1 *dst,
+ dma_addr_t l2ptr_dma)
{
u64 val = 0;
@@ -1466,7 +1467,7 @@ static void arm_smmu_write_strtab_l1_desc(__le64 *dst, dma_addr_t l2ptr_dma)
val |= l2ptr_dma & STRTAB_L1_DESC_L2PTR_MASK;
/* The HW has 64 bit atomicity with stores to the L2 STE table */
- WRITE_ONCE(*dst, cpu_to_le64(val));
+ WRITE_ONCE(dst->l2ptr, cpu_to_le64(val));
}
struct arm_smmu_ste_writer {
@@ -1678,9 +1679,8 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
if (desc->l2ptr)
return 0;
- desc->l2ptr = dmam_alloc_coherent(
- smmu->dev, STRTAB_NUM_L2_STES * sizeof(struct arm_smmu_ste),
- &l2ptr_dma, GFP_KERNEL);
+ desc->l2ptr = dmam_alloc_coherent(smmu->dev, sizeof(*desc->l2ptr),
+ &l2ptr_dma, GFP_KERNEL);
if (!desc->l2ptr) {
dev_err(smmu->dev,
"failed to allocate l2 stream table for SID %u\n",
@@ -1688,9 +1688,11 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
return -ENOMEM;
}
- arm_smmu_init_initial_stes(desc->l2ptr, STRTAB_NUM_L2_STES);
- arm_smmu_write_strtab_l1_desc(&cfg->strtab[arm_smmu_strtab_l1_idx(sid)],
- l2ptr_dma);
+ arm_smmu_init_initial_stes(desc->l2ptr->stes, STRTAB_NUM_L2_STES);
+ arm_smmu_write_strtab_l1_desc(
+ (struct arm_smmu_strtab_l1 *)&cfg
+ ->strtab[arm_smmu_strtab_l1_idx(sid)],
+ l2ptr_dma);
return 0;
}
@@ -2449,7 +2451,7 @@ arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
/* Two-level walk */
return &cfg->l1_desc[arm_smmu_strtab_l1_idx(sid)]
- .l2ptr[arm_smmu_strtab_l2_idx(sid)];
+ .l2ptr->stes[arm_smmu_strtab_l2_idx(sid)];
} else {
/* Simple linear lookup */
return (struct arm_smmu_ste *)&cfg
@@ -3608,7 +3610,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
ilog2(cfg->num_l1_ents * STRTAB_NUM_L2_STES),
smmu->sid_bits);
- l1size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3);
+ l1size = cfg->num_l1_ents * sizeof(struct arm_smmu_strtab_l1);
strtab = dmam_alloc_coherent(smmu->dev, l1size, &cfg->strtab_dma,
GFP_KERNEL);
if (!strtab) {
@@ -204,7 +204,6 @@
*/
#define STRTAB_SPLIT 8
-#define STRTAB_L1_DESC_DWORDS 1
#define STRTAB_L1_DESC_SPAN GENMASK_ULL(4, 0)
#define STRTAB_L1_DESC_L2PTR_MASK GENMASK_ULL(51, 6)
@@ -215,6 +214,13 @@ struct arm_smmu_ste {
};
#define STRTAB_NUM_L2_STES (1 << STRTAB_SPLIT)
+struct arm_smmu_strtab_l2 {
+ struct arm_smmu_ste stes[STRTAB_NUM_L2_STES];
+};
+
+struct arm_smmu_strtab_l1 {
+ __le64 l2ptr;
+};
#define STRTAB_MAX_L1_ENTRIES (1 << 17)
static inline u32 arm_smmu_strtab_l1_idx(u32 sid)
@@ -597,7 +603,7 @@ struct arm_smmu_priq {
/* High-level stream table and context descriptor structures */
struct arm_smmu_strtab_l1_desc {
- struct arm_smmu_ste *l2ptr;
+ struct arm_smmu_strtab_l2 *l2ptr;
};
struct arm_smmu_ctx_desc {