69
69
#define IDR1_SSIDSIZE GENMASK(10, 6)
70
70
#define IDR1_SIDSIZE GENMASK(5, 0)
71
71
72
+ #define ARM_SMMU_IDR3 0xc
73
+ #define IDR3_RIL (1 << 10)
74
+
72
75
#define ARM_SMMU_IDR5 0x14
73
76
#define IDR5_STALL_MAX GENMASK(31, 16)
74
77
#define IDR5_GRAN64K (1 << 6)
346
349
#define CMDQ_CFGI_1_LEAF (1UL << 0)
347
350
#define CMDQ_CFGI_1_RANGE GENMASK_ULL(4, 0)
348
351
352
+ #define CMDQ_TLBI_0_NUM GENMASK_ULL(16, 12)
353
+ #define CMDQ_TLBI_RANGE_NUM_MAX 31
354
+ #define CMDQ_TLBI_0_SCALE GENMASK_ULL(24, 20)
349
355
#define CMDQ_TLBI_0_VMID GENMASK_ULL(47, 32)
350
356
#define CMDQ_TLBI_0_ASID GENMASK_ULL(63, 48)
351
357
#define CMDQ_TLBI_1_LEAF (1UL << 0)
358
+ #define CMDQ_TLBI_1_TTL GENMASK_ULL(9, 8)
359
+ #define CMDQ_TLBI_1_TG GENMASK_ULL(11, 10)
352
360
#define CMDQ_TLBI_1_VA_MASK GENMASK_ULL(63, 12)
353
361
#define CMDQ_TLBI_1_IPA_MASK GENMASK_ULL(51, 12)
354
362
@@ -473,9 +481,13 @@ struct arm_smmu_cmdq_ent {
473
481
#define CMDQ_OP_TLBI_S2_IPA 0x2a
474
482
#define CMDQ_OP_TLBI_NSNH_ALL 0x30
475
483
struct {
484
+ u8 num ;
485
+ u8 scale ;
476
486
u16 asid ;
477
487
u16 vmid ;
478
488
bool leaf ;
489
+ u8 ttl ;
490
+ u8 tg ;
479
491
u64 addr ;
480
492
} tlbi ;
481
493
@@ -632,6 +644,7 @@ struct arm_smmu_device {
632
644
#define ARM_SMMU_FEAT_HYP (1 << 12)
633
645
#define ARM_SMMU_FEAT_STALL_FORCE (1 << 13)
634
646
#define ARM_SMMU_FEAT_VAX (1 << 14)
647
+ #define ARM_SMMU_FEAT_RANGE_INV (1 << 15)
635
648
u32 features ;
636
649
637
650
#define ARM_SMMU_OPT_SKIP_PREFETCH (1 << 0)
@@ -900,14 +913,22 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
900
913
cmd [1 ] |= FIELD_PREP (CMDQ_CFGI_1_RANGE , 31 );
901
914
break ;
902
915
case CMDQ_OP_TLBI_NH_VA :
916
+ cmd [0 ] |= FIELD_PREP (CMDQ_TLBI_0_NUM , ent -> tlbi .num );
917
+ cmd [0 ] |= FIELD_PREP (CMDQ_TLBI_0_SCALE , ent -> tlbi .scale );
903
918
cmd [0 ] |= FIELD_PREP (CMDQ_TLBI_0_VMID , ent -> tlbi .vmid );
904
919
cmd [0 ] |= FIELD_PREP (CMDQ_TLBI_0_ASID , ent -> tlbi .asid );
905
920
cmd [1 ] |= FIELD_PREP (CMDQ_TLBI_1_LEAF , ent -> tlbi .leaf );
921
+ cmd [1 ] |= FIELD_PREP (CMDQ_TLBI_1_TTL , ent -> tlbi .ttl );
922
+ cmd [1 ] |= FIELD_PREP (CMDQ_TLBI_1_TG , ent -> tlbi .tg );
906
923
cmd [1 ] |= ent -> tlbi .addr & CMDQ_TLBI_1_VA_MASK ;
907
924
break ;
908
925
case CMDQ_OP_TLBI_S2_IPA :
926
+ cmd [0 ] |= FIELD_PREP (CMDQ_TLBI_0_NUM , ent -> tlbi .num );
927
+ cmd [0 ] |= FIELD_PREP (CMDQ_TLBI_0_SCALE , ent -> tlbi .scale );
909
928
cmd [0 ] |= FIELD_PREP (CMDQ_TLBI_0_VMID , ent -> tlbi .vmid );
910
929
cmd [1 ] |= FIELD_PREP (CMDQ_TLBI_1_LEAF , ent -> tlbi .leaf );
930
+ cmd [1 ] |= FIELD_PREP (CMDQ_TLBI_1_TTL , ent -> tlbi .ttl );
931
+ cmd [1 ] |= FIELD_PREP (CMDQ_TLBI_1_TG , ent -> tlbi .tg );
911
932
cmd [1 ] |= ent -> tlbi .addr & CMDQ_TLBI_1_IPA_MASK ;
912
933
break ;
913
934
case CMDQ_OP_TLBI_NH_ASID :
@@ -2252,7 +2273,8 @@ static void arm_smmu_tlb_inv_range(unsigned long iova, size_t size,
2252
2273
struct arm_smmu_domain * smmu_domain )
2253
2274
{
2254
2275
struct arm_smmu_device * smmu = smmu_domain -> smmu ;
2255
- unsigned long start = iova , end = iova + size ;
2276
+ unsigned long start = iova , end = iova + size , num_pages = 0 , tg = 0 ;
2277
+ size_t inv_range = granule ;
2256
2278
struct arm_smmu_cmdq_batch cmds = {};
2257
2279
struct arm_smmu_cmdq_ent cmd = {
2258
2280
.tlbi = {
@@ -2271,10 +2293,48 @@ static void arm_smmu_tlb_inv_range(unsigned long iova, size_t size,
2271
2293
cmd .tlbi .vmid = smmu_domain -> s2_cfg .vmid ;
2272
2294
}
2273
2295
2296
+ if (smmu -> features & ARM_SMMU_FEAT_RANGE_INV ) {
2297
+ /* Get the leaf page size */
2298
+ tg = __ffs (smmu_domain -> domain .pgsize_bitmap );
2299
+
2300
+ /* Convert page size of 12,14,16 (log2) to 1,2,3 */
2301
+ cmd .tlbi .tg = (tg - 10 ) / 2 ;
2302
+
2303
+ /* Determine what level the granule is at */
2304
+ cmd .tlbi .ttl = 4 - ((ilog2 (granule ) - 3 ) / (tg - 3 ));
2305
+
2306
+ num_pages = size >> tg ;
2307
+ }
2308
+
2274
2309
while (iova < end ) {
2310
+ if (smmu -> features & ARM_SMMU_FEAT_RANGE_INV ) {
2311
+ /*
2312
+ * On each iteration of the loop, the range is 5 bits
2313
+ * worth of the aligned size remaining.
2314
+ * The range in pages is:
2315
+ *
2316
+ * range = (num_pages & (0x1f << __ffs(num_pages)))
2317
+ */
2318
+ unsigned long scale , num ;
2319
+
2320
+ /* Determine the power of 2 multiple number of pages */
2321
+ scale = __ffs (num_pages );
2322
+ cmd .tlbi .scale = scale ;
2323
+
2324
+ /* Determine how many chunks of 2^scale size we have */
2325
+ num = (num_pages >> scale ) & CMDQ_TLBI_RANGE_NUM_MAX ;
2326
+ cmd .tlbi .num = num - 1 ;
2327
+
2328
+ /* range is num * 2^scale * pgsize */
2329
+ inv_range = num << (scale + tg );
2330
+
2331
+ /* Clear out the lower order bits for the next iteration */
2332
+ num_pages -= num << scale ;
2333
+ }
2334
+
2275
2335
cmd .tlbi .addr = iova ;
2276
2336
arm_smmu_cmdq_batch_add (smmu , & cmds , & cmd );
2277
- iova += granule ;
2337
+ iova += inv_range ;
2278
2338
}
2279
2339
arm_smmu_cmdq_batch_submit (smmu , & cmds );
2280
2340
@@ -3783,6 +3843,11 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
3783
3843
if (smmu -> sid_bits <= STRTAB_SPLIT )
3784
3844
smmu -> features &= ~ARM_SMMU_FEAT_2_LVL_STRTAB ;
3785
3845
3846
+ /* IDR3 */
3847
+ reg = readl_relaxed (smmu -> base + ARM_SMMU_IDR3 );
3848
+ if (FIELD_GET (IDR3_RIL , reg ))
3849
+ smmu -> features |= ARM_SMMU_FEAT_RANGE_INV ;
3850
+
3786
3851
/* IDR5 */
3787
3852
reg = readl_relaxed (smmu -> base + ARM_SMMU_IDR5 );
3788
3853
0 commit comments