@@ -1710,17 +1710,15 @@ static void arm_smmu_init_initial_stes(struct arm_smmu_ste *strtab,
17101710static int arm_smmu_init_l2_strtab (struct arm_smmu_device * smmu , u32 sid )
17111711{
17121712 size_t size ;
1713- void * strtab ;
17141713 dma_addr_t l2ptr_dma ;
17151714 struct arm_smmu_strtab_cfg * cfg = & smmu -> strtab_cfg ;
1716- struct arm_smmu_strtab_l1_desc * desc = & cfg -> l1_desc [ sid >> STRTAB_SPLIT ] ;
1715+ struct arm_smmu_strtab_l1_desc * desc ;
17171716
1717+ desc = & cfg -> l1_desc [arm_smmu_strtab_l1_idx (sid )];
17181718 if (desc -> l2ptr )
17191719 return 0 ;
17201720
1721- size = 1 << (STRTAB_SPLIT + ilog2 (STRTAB_STE_DWORDS ) + 3 );
1722- strtab = & cfg -> strtab [(sid >> STRTAB_SPLIT ) * STRTAB_L1_DESC_DWORDS ];
1723-
1721+ size = STRTAB_NUM_L2_STES * sizeof (struct arm_smmu_ste );
17241722 desc -> l2ptr = dmam_alloc_coherent (smmu -> dev , size , & l2ptr_dma ,
17251723 GFP_KERNEL );
17261724 if (!desc -> l2ptr ) {
@@ -1730,8 +1728,9 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
17301728 return - ENOMEM ;
17311729 }
17321730
1733- arm_smmu_init_initial_stes (desc -> l2ptr , 1 << STRTAB_SPLIT );
1734- arm_smmu_write_strtab_l1_desc (strtab , l2ptr_dma );
1731+ arm_smmu_init_initial_stes (desc -> l2ptr , STRTAB_NUM_L2_STES );
1732+ arm_smmu_write_strtab_l1_desc (& cfg -> strtab [arm_smmu_strtab_l1_idx (sid )],
1733+ l2ptr_dma );
17351734 return 0 ;
17361735}
17371736
@@ -2486,12 +2485,9 @@ arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
24862485 struct arm_smmu_strtab_cfg * cfg = & smmu -> strtab_cfg ;
24872486
24882487 if (smmu -> features & ARM_SMMU_FEAT_2_LVL_STRTAB ) {
2489- unsigned int idx1 , idx2 ;
2490-
24912488 /* Two-level walk */
2492- idx1 = (sid >> STRTAB_SPLIT ) * STRTAB_L1_DESC_DWORDS ;
2493- idx2 = sid & ((1 << STRTAB_SPLIT ) - 1 );
2494- return & cfg -> l1_desc [idx1 ].l2ptr [idx2 ];
2489+ return & cfg -> l1_desc [arm_smmu_strtab_l1_idx (sid )]
2490+ .l2ptr [arm_smmu_strtab_l2_idx (sid )];
24952491 } else {
24962492 /* Simple linear lookup */
24972493 return (struct arm_smmu_ste * )& cfg
@@ -3195,12 +3191,9 @@ struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
31953191
31963192static bool arm_smmu_sid_in_range (struct arm_smmu_device * smmu , u32 sid )
31973193{
3198- unsigned long limit = smmu -> strtab_cfg .num_l1_ents ;
3199-
32003194 if (smmu -> features & ARM_SMMU_FEAT_2_LVL_STRTAB )
3201- limit *= 1UL << STRTAB_SPLIT ;
3202-
3203- return sid < limit ;
3195+ return arm_smmu_strtab_l1_idx (sid ) < smmu -> strtab_cfg .num_l1_ents ;
3196+ return sid < smmu -> strtab_cfg .num_l1_ents ;
32043197}
32053198
32063199static int arm_smmu_init_sid_strtab (struct arm_smmu_device * smmu , u32 sid )
@@ -3637,19 +3630,18 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
36373630{
36383631 void * strtab ;
36393632 u64 reg ;
3640- u32 size , l1size ;
3633+ u32 l1size ;
36413634 struct arm_smmu_strtab_cfg * cfg = & smmu -> strtab_cfg ;
3635+ unsigned int last_sid_idx =
3636+ arm_smmu_strtab_l1_idx ((1 << smmu -> sid_bits ) - 1 );
36423637
36433638 /* Calculate the L1 size, capped to the SIDSIZE. */
3644- size = STRTAB_L1_SZ_SHIFT - (ilog2 (STRTAB_L1_DESC_DWORDS ) + 3 );
3645- size = min (size , smmu -> sid_bits - STRTAB_SPLIT );
3646- cfg -> num_l1_ents = 1 << size ;
3647-
3648- size += STRTAB_SPLIT ;
3649- if (size < smmu -> sid_bits )
3639+ cfg -> num_l1_ents = min (last_sid_idx + 1 , STRTAB_MAX_L1_ENTRIES );
3640+ if (cfg -> num_l1_ents <= last_sid_idx )
36503641 dev_warn (smmu -> dev ,
36513642 "2-level strtab only covers %u/%u bits of SID\n" ,
3652- size , smmu -> sid_bits );
3643+ ilog2 (cfg -> num_l1_ents * STRTAB_NUM_L2_STES ),
3644+ smmu -> sid_bits );
36533645
36543646 l1size = cfg -> num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3 );
36553647 strtab = dmam_alloc_coherent (smmu -> dev , l1size , & cfg -> strtab_dma ,
@@ -3664,7 +3656,8 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
36643656
36653657 /* Configure strtab_base_cfg for 2 levels */
36663658 reg = FIELD_PREP (STRTAB_BASE_CFG_FMT , STRTAB_BASE_CFG_FMT_2LVL );
3667- reg |= FIELD_PREP (STRTAB_BASE_CFG_LOG2SIZE , size );
3659+ reg |= FIELD_PREP (STRTAB_BASE_CFG_LOG2SIZE ,
3660+ ilog2 (cfg -> num_l1_ents ) + STRTAB_SPLIT );
36683661 reg |= FIELD_PREP (STRTAB_BASE_CFG_SPLIT , STRTAB_SPLIT );
36693662 cfg -> strtab_base_cfg = reg ;
36703663
0 commit comments