|
@@ -2020,21 +2020,23 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
|
|
{
|
|
{
|
|
void *strtab;
|
|
void *strtab;
|
|
u64 reg;
|
|
u64 reg;
|
|
- u32 size;
|
|
|
|
|
|
+ u32 size, l1size;
|
|
int ret;
|
|
int ret;
|
|
struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
|
|
struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
|
|
|
|
|
|
/* Calculate the L1 size, capped to the SIDSIZE */
|
|
/* Calculate the L1 size, capped to the SIDSIZE */
|
|
size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3);
|
|
size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3);
|
|
size = min(size, smmu->sid_bits - STRTAB_SPLIT);
|
|
size = min(size, smmu->sid_bits - STRTAB_SPLIT);
|
|
- if (size + STRTAB_SPLIT < smmu->sid_bits)
|
|
|
|
|
|
+ cfg->num_l1_ents = 1 << size;
|
|
|
|
+
|
|
|
|
+ size += STRTAB_SPLIT;
|
|
|
|
+ if (size < smmu->sid_bits)
|
|
dev_warn(smmu->dev,
|
|
dev_warn(smmu->dev,
|
|
"2-level strtab only covers %u/%u bits of SID\n",
|
|
"2-level strtab only covers %u/%u bits of SID\n",
|
|
- size + STRTAB_SPLIT, smmu->sid_bits);
|
|
|
|
|
|
+ size, smmu->sid_bits);
|
|
|
|
|
|
- cfg->num_l1_ents = 1 << size;
|
|
|
|
- size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3);
|
|
|
|
- strtab = dma_zalloc_coherent(smmu->dev, size, &cfg->strtab_dma,
|
|
|
|
|
|
+ l1size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3);
|
|
|
|
+ strtab = dma_zalloc_coherent(smmu->dev, l1size, &cfg->strtab_dma,
|
|
GFP_KERNEL);
|
|
GFP_KERNEL);
|
|
if (!strtab) {
|
|
if (!strtab) {
|
|
dev_err(smmu->dev,
|
|
dev_err(smmu->dev,
|
|
@@ -2055,8 +2057,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
|
|
ret = arm_smmu_init_l1_strtab(smmu);
|
|
ret = arm_smmu_init_l1_strtab(smmu);
|
|
if (ret)
|
|
if (ret)
|
|
dma_free_coherent(smmu->dev,
|
|
dma_free_coherent(smmu->dev,
|
|
- cfg->num_l1_ents *
|
|
|
|
- (STRTAB_L1_DESC_DWORDS << 3),
|
|
|
|
|
|
+ l1size,
|
|
strtab,
|
|
strtab,
|
|
cfg->strtab_dma);
|
|
cfg->strtab_dma);
|
|
return ret;
|
|
return ret;
|