85
85
#define DART_T8020_TTBR_ADDR_FIELD_SHIFT 0
86
86
#define DART_T8020_TTBR_SHIFT 12
87
87
88
+ /* T8110 registers */
89
+
90
+ #define DART_T8110_PARAMS3 0x08
91
+ #define DART_T8110_PARAMS3_PA_WIDTH GENMASK(29, 24)
92
+ #define DART_T8110_PARAMS3_VA_WIDTH GENMASK(21, 16)
93
+ #define DART_T8110_PARAMS3_VER_MAJ GENMASK(15, 8)
94
+ #define DART_T8110_PARAMS3_VER_MIN GENMASK(7, 0)
95
+
96
+ #define DART_T8110_PARAMS4 0x0c
97
+ #define DART_T8110_PARAMS4_NUM_CLIENTS GENMASK(24, 16)
98
+ #define DART_T8110_PARAMS4_NUM_SIDS GENMASK(8, 0)
99
+
100
+ #define DART_T8110_TLB_CMD 0x80
101
+ #define DART_T8110_TLB_CMD_BUSY BIT(31)
102
+ #define DART_T8110_TLB_CMD_OP GENMASK(10, 8)
103
+ #define DART_T8110_TLB_CMD_OP_FLUSH_ALL 0
104
+ #define DART_T8110_TLB_CMD_OP_FLUSH_SID 1
105
+ #define DART_T8110_TLB_CMD_STREAM GENMASK(7, 0)
106
+
107
+ #define DART_T8110_ERROR 0x100
108
+ #define DART_T8110_ERROR_STREAM GENMASK(27, 20)
109
+ #define DART_T8110_ERROR_CODE GENMASK(14, 0)
110
+ #define DART_T8110_ERROR_FLAG BIT(31)
111
+
112
+ #define DART_T8110_ERROR_MASK 0x104
113
+
114
+ #define DART_T8110_ERROR_READ_FAULT BIT(4)
115
+ #define DART_T8110_ERROR_WRITE_FAULT BIT(3)
116
+ #define DART_T8110_ERROR_NO_PTE BIT(3)
117
+ #define DART_T8110_ERROR_NO_PMD BIT(2)
118
+ #define DART_T8110_ERROR_NO_PGD BIT(1)
119
+ #define DART_T8110_ERROR_NO_TTBR BIT(0)
120
+
121
+ #define DART_T8110_ERROR_ADDR_LO 0x170
122
+ #define DART_T8110_ERROR_ADDR_HI 0x174
123
+
124
+ #define DART_T8110_PROTECT 0x200
125
+ #define DART_T8110_UNPROTECT 0x204
126
+ #define DART_T8110_PROTECT_LOCK 0x208
127
+ #define DART_T8110_PROTECT_TTBR_TCR BIT(0)
128
+
129
+ #define DART_T8110_ENABLE_STREAMS 0xc00
130
+ #define DART_T8110_DISABLE_STREAMS 0xc20
131
+
132
+ #define DART_T8110_TCR 0x1000
133
+ #define DART_T8110_TCR_REMAP GENMASK(11, 8)
134
+ #define DART_T8110_TCR_REMAP_EN BIT(7)
135
+ #define DART_T8110_TCR_BYPASS_DAPF BIT(2)
136
+ #define DART_T8110_TCR_BYPASS_DART BIT(1)
137
+ #define DART_T8110_TCR_TRANSLATE_ENABLE BIT(0)
138
+
139
+ #define DART_T8110_TTBR 0x1400
140
+ #define DART_T8110_TTBR_VALID BIT(0)
141
+ #define DART_T8110_TTBR_ADDR_FIELD_SHIFT 2
142
+ #define DART_T8110_TTBR_SHIFT 14
143
+
88
144
#define DART_TCR (dart , sid ) ((dart)->hw->tcr + ((sid) << 2))
89
145
90
146
#define DART_TTBR (dart , sid , idx ) ((dart)->hw->ttbr + \
93
149
94
150
struct apple_dart_stream_map ;
95
151
152
+ enum dart_type {
153
+ DART_T8020 ,
154
+ DART_T6000 ,
155
+ DART_T8110 ,
156
+ };
157
+
96
158
struct apple_dart_hw {
159
+ enum dart_type type ;
97
160
irqreturn_t (* irq_handler )(int irq , void * dev );
98
161
int (* invalidate_tlb )(struct apple_dart_stream_map * stream_map );
99
162
@@ -149,6 +212,8 @@ struct apple_dart {
149
212
150
213
spinlock_t lock ;
151
214
215
+ u32 ias ;
216
+ u32 oas ;
152
217
u32 pgsize ;
153
218
u32 num_streams ;
154
219
u32 supports_bypass : 1 ;
@@ -330,13 +395,58 @@ apple_dart_t8020_hw_stream_command(struct apple_dart_stream_map *stream_map,
330
395
return 0 ;
331
396
}
332
397
398
+ static int
399
+ apple_dart_t8110_hw_tlb_command (struct apple_dart_stream_map * stream_map ,
400
+ u32 command )
401
+ {
402
+ struct apple_dart * dart = stream_map -> dart ;
403
+ unsigned long flags ;
404
+ int ret = 0 ;
405
+ int sid ;
406
+
407
+ spin_lock_irqsave (& dart -> lock , flags );
408
+
409
+ for_each_set_bit (sid , stream_map -> sidmap , dart -> num_streams ) {
410
+ u32 val = FIELD_PREP (DART_T8110_TLB_CMD_OP , command ) |
411
+ FIELD_PREP (DART_T8110_TLB_CMD_STREAM , sid );
412
+ writel (val , dart -> regs + DART_T8110_TLB_CMD );
413
+
414
+ ret = readl_poll_timeout_atomic (
415
+ dart -> regs + DART_T8110_TLB_CMD , val ,
416
+ !(val & DART_T8110_TLB_CMD_BUSY ), 1 ,
417
+ DART_STREAM_COMMAND_BUSY_TIMEOUT );
418
+
419
+ if (ret )
420
+ break ;
421
+
422
+ }
423
+
424
+ spin_unlock_irqrestore (& dart -> lock , flags );
425
+
426
+ if (ret ) {
427
+ dev_err (stream_map -> dart -> dev ,
428
+ "busy bit did not clear after command %x for stream %d\n" ,
429
+ command , sid );
430
+ return ret ;
431
+ }
432
+
433
+ return 0 ;
434
+ }
435
+
333
436
static int
334
437
apple_dart_t8020_hw_invalidate_tlb (struct apple_dart_stream_map * stream_map )
335
438
{
336
439
return apple_dart_t8020_hw_stream_command (
337
440
stream_map , DART_T8020_STREAM_COMMAND_INVALIDATE );
338
441
}
339
442
443
+ static int
444
+ apple_dart_t8110_hw_invalidate_tlb (struct apple_dart_stream_map * stream_map )
445
+ {
446
+ return apple_dart_t8110_hw_tlb_command (
447
+ stream_map , DART_T8110_TLB_CMD_OP_FLUSH_SID );
448
+ }
449
+
340
450
static int apple_dart_hw_reset (struct apple_dart * dart )
341
451
{
342
452
u32 config ;
@@ -363,6 +473,9 @@ static int apple_dart_hw_reset(struct apple_dart *dart)
363
473
/* clear any pending errors before the interrupt is unmasked */
364
474
writel (readl (dart -> regs + dart -> hw -> error ), dart -> regs + dart -> hw -> error );
365
475
476
+ if (dart -> hw -> type == DART_T8110 )
477
+ writel (0 , dart -> regs + DART_T8110_ERROR_MASK );
478
+
366
479
return dart -> hw -> invalidate_tlb (& stream_map );
367
480
}
368
481
@@ -478,8 +591,8 @@ static int apple_dart_finalize_domain(struct iommu_domain *domain,
478
591
479
592
pgtbl_cfg = (struct io_pgtable_cfg ){
480
593
.pgsize_bitmap = dart -> pgsize ,
481
- .ias = 32 ,
482
- .oas = dart -> hw -> oas ,
594
+ .ias = dart -> ias ,
595
+ .oas = dart -> oas ,
483
596
.coherent_walk = 1 ,
484
597
.iommu_dev = dart -> dev ,
485
598
};
@@ -493,7 +606,7 @@ static int apple_dart_finalize_domain(struct iommu_domain *domain,
493
606
494
607
domain -> pgsize_bitmap = pgtbl_cfg .pgsize_bitmap ;
495
608
domain -> geometry .aperture_start = 0 ;
496
- domain -> geometry .aperture_end = DMA_BIT_MASK (32 );
609
+ domain -> geometry .aperture_end = ( dma_addr_t ) DMA_BIT_MASK (dart -> ias );
497
610
domain -> geometry .force_aperture = true;
498
611
499
612
dart_domain -> finalized = true;
@@ -880,10 +993,49 @@ static irqreturn_t apple_dart_t8020_irq(int irq, void *dev)
880
993
return IRQ_HANDLED ;
881
994
}
882
995
996
+ static irqreturn_t apple_dart_t8110_irq (int irq , void * dev )
997
+ {
998
+ struct apple_dart * dart = dev ;
999
+ const char * fault_name = NULL ;
1000
+ u32 error = readl (dart -> regs + DART_T8110_ERROR );
1001
+ u32 error_code = FIELD_GET (DART_T8110_ERROR_CODE , error );
1002
+ u32 addr_lo = readl (dart -> regs + DART_T8110_ERROR_ADDR_LO );
1003
+ u32 addr_hi = readl (dart -> regs + DART_T8110_ERROR_ADDR_HI );
1004
+ u64 addr = addr_lo | (((u64 )addr_hi ) << 32 );
1005
+ u8 stream_idx = FIELD_GET (DART_T8110_ERROR_STREAM , error );
1006
+
1007
+ if (!(error & DART_T8110_ERROR_FLAG ))
1008
+ return IRQ_NONE ;
1009
+
1010
+ /* there should only be a single bit set but let's use == to be sure */
1011
+ if (error_code == DART_T8110_ERROR_READ_FAULT )
1012
+ fault_name = "READ FAULT" ;
1013
+ else if (error_code == DART_T8110_ERROR_WRITE_FAULT )
1014
+ fault_name = "WRITE FAULT" ;
1015
+ else if (error_code == DART_T8110_ERROR_NO_PTE )
1016
+ fault_name = "NO PTE FOR IOVA" ;
1017
+ else if (error_code == DART_T8110_ERROR_NO_PMD )
1018
+ fault_name = "NO PMD FOR IOVA" ;
1019
+ else if (error_code == DART_T8110_ERROR_NO_PGD )
1020
+ fault_name = "NO PGD FOR IOVA" ;
1021
+ else if (error_code == DART_T8110_ERROR_NO_TTBR )
1022
+ fault_name = "NO TTBR FOR IOVA" ;
1023
+ else
1024
+ fault_name = "unknown" ;
1025
+
1026
+ dev_err_ratelimited (
1027
+ dart -> dev ,
1028
+ "translation fault: status:0x%x stream:%d code:0x%x (%s) at 0x%llx" ,
1029
+ error , stream_idx , error_code , fault_name , addr );
1030
+
1031
+ writel (error , dart -> regs + DART_T8110_ERROR );
1032
+ return IRQ_HANDLED ;
1033
+ }
1034
+
883
1035
static int apple_dart_probe (struct platform_device * pdev )
884
1036
{
885
1037
int ret ;
886
- u32 dart_params [2 ];
1038
+ u32 dart_params [4 ];
887
1039
struct resource * res ;
888
1040
struct apple_dart * dart ;
889
1041
struct device * dev = & pdev -> dev ;
@@ -923,7 +1075,22 @@ static int apple_dart_probe(struct platform_device *pdev)
923
1075
dart -> pgsize = 1 << FIELD_GET (DART_PARAMS1_PAGE_SHIFT , dart_params [0 ]);
924
1076
dart -> supports_bypass = dart_params [1 ] & DART_PARAMS2_BYPASS_SUPPORT ;
925
1077
926
- dart -> num_streams = dart -> hw -> max_sid_count ;
1078
+ switch (dart -> hw -> type ) {
1079
+ case DART_T8020 :
1080
+ case DART_T6000 :
1081
+ dart -> ias = 32 ;
1082
+ dart -> oas = dart -> hw -> oas ;
1083
+ dart -> num_streams = dart -> hw -> max_sid_count ;
1084
+ break ;
1085
+
1086
+ case DART_T8110 :
1087
+ dart_params [2 ] = readl (dart -> regs + DART_T8110_PARAMS3 );
1088
+ dart_params [3 ] = readl (dart -> regs + DART_T8110_PARAMS4 );
1089
+ dart -> ias = FIELD_GET (DART_T8110_PARAMS3_VA_WIDTH , dart_params [2 ]);
1090
+ dart -> oas = FIELD_GET (DART_T8110_PARAMS3_PA_WIDTH , dart_params [2 ]);
1091
+ dart -> num_streams = FIELD_GET (DART_T8110_PARAMS4_NUM_SIDS , dart_params [3 ]);
1092
+ break ;
1093
+ }
927
1094
928
1095
if (dart -> num_streams > DART_MAX_STREAMS ) {
929
1096
dev_err (& pdev -> dev , "Too many streams (%d > %d)\n" ,
@@ -986,6 +1153,7 @@ static int apple_dart_remove(struct platform_device *pdev)
986
1153
}
987
1154
988
1155
static const struct apple_dart_hw apple_dart_hw_t8103 = {
1156
+ .type = DART_T8020 ,
989
1157
.irq_handler = apple_dart_t8020_irq ,
990
1158
.invalidate_tlb = apple_dart_t8020_hw_invalidate_tlb ,
991
1159
.oas = 36 ,
@@ -1010,6 +1178,7 @@ static const struct apple_dart_hw apple_dart_hw_t8103 = {
1010
1178
.ttbr_count = 4 ,
1011
1179
};
1012
1180
static const struct apple_dart_hw apple_dart_hw_t6000 = {
1181
+ .type = DART_T6000 ,
1013
1182
.irq_handler = apple_dart_t8020_irq ,
1014
1183
.invalidate_tlb = apple_dart_t8020_hw_invalidate_tlb ,
1015
1184
.oas = 42 ,
@@ -1034,6 +1203,31 @@ static const struct apple_dart_hw apple_dart_hw_t6000 = {
1034
1203
.ttbr_count = 4 ,
1035
1204
};
1036
1205
1206
+ static const struct apple_dart_hw apple_dart_hw_t8110 = {
1207
+ .type = DART_T8110 ,
1208
+ .irq_handler = apple_dart_t8110_irq ,
1209
+ .invalidate_tlb = apple_dart_t8110_hw_invalidate_tlb ,
1210
+ .fmt = APPLE_DART2 ,
1211
+ .max_sid_count = 256 ,
1212
+
1213
+ .enable_streams = DART_T8110_ENABLE_STREAMS ,
1214
+ .lock = DART_T8110_PROTECT ,
1215
+ .lock_bit = DART_T8110_PROTECT_TTBR_TCR ,
1216
+
1217
+ .error = DART_T8110_ERROR ,
1218
+
1219
+ .tcr = DART_T8110_TCR ,
1220
+ .tcr_enabled = DART_T8110_TCR_TRANSLATE_ENABLE ,
1221
+ .tcr_disabled = 0 ,
1222
+ .tcr_bypass = DART_T8110_TCR_BYPASS_DAPF | DART_T8110_TCR_BYPASS_DART ,
1223
+
1224
+ .ttbr = DART_T8110_TTBR ,
1225
+ .ttbr_valid = DART_T8110_TTBR_VALID ,
1226
+ .ttbr_addr_field_shift = DART_T8110_TTBR_ADDR_FIELD_SHIFT ,
1227
+ .ttbr_shift = DART_T8110_TTBR_SHIFT ,
1228
+ .ttbr_count = 1 ,
1229
+ };
1230
+
1037
1231
static __maybe_unused int apple_dart_suspend (struct device * dev )
1038
1232
{
1039
1233
struct apple_dart * dart = dev_get_drvdata (dev );
@@ -1075,6 +1269,7 @@ DEFINE_SIMPLE_DEV_PM_OPS(apple_dart_pm_ops, apple_dart_suspend, apple_dart_resum
1075
1269
1076
1270
static const struct of_device_id apple_dart_of_match [] = {
1077
1271
{ .compatible = "apple,t8103-dart" , .data = & apple_dart_hw_t8103 },
1272
+ { .compatible = "apple,t8110-dart" , .data = & apple_dart_hw_t8110 },
1078
1273
{ .compatible = "apple,t6000-dart" , .data = & apple_dart_hw_t6000 },
1079
1274
{},
1080
1275
};
0 commit comments