7777
7878#define DART_T8020_STREAMS_ENABLE 0xfc
7979
80+ #define DART_T8020_REMAP 0x80
81+
82+ #define DART_REMAP_MASK (sid ) GENMASK(7 + (8 * (sid % 4)), 8 * (sid % 4))
83+ #define DART_REMAP (dart , sid ) ((dart)->regs + DART_T8020_REMAP + ((sid) & ~0x3))
84+
8085#define DART_T8020_TCR 0x100
8186#define DART_T8020_TCR_TRANSLATE_ENABLE BIT(7)
8287#define DART_T8020_TCR_BYPASS_DART BIT(8)
8388#define DART_T8020_TCR_BYPASS_DAPF BIT(12)
89+ #define DART_T8020_TCR_REMAP_ENABLE BIT(24)
8490
8591#define DART_T8020_TTBR 0x200
8692#define DART_T8020_USB4_TTBR 0x400
136142
137143#define DART_T8110_TCR 0x1000
138144#define DART_T8110_TCR_REMAP GENMASK(11, 8)
139- #define DART_T8110_TCR_REMAP_EN BIT(7)
145+ #define DART_T8110_TCR_REMAP_ENABLE BIT(7)
140146#define DART_T8110_TCR_FOUR_LEVEL BIT(3)
141147#define DART_T8110_TCR_BYPASS_DAPF BIT(2)
142148#define DART_T8110_TCR_BYPASS_DART BIT(1)
@@ -161,10 +167,13 @@ enum dart_type {
161167 DART_T8110 ,
162168};
163169
170+ struct apple_dart ;
171+
164172struct apple_dart_hw {
165173 enum dart_type type ;
166174 irqreturn_t (* irq_handler )(int irq , void * dev );
167175 int (* invalidate_tlb )(struct apple_dart_stream_map * stream_map );
176+ void (* enable_remap )(struct apple_dart * dart , int sid , int remap_to );
168177
169178 u32 oas ;
170179 enum io_pgtable_fmt fmt ;
@@ -332,22 +341,32 @@ apple_dart_hw_enable_translation(struct apple_dart_stream_map *stream_map, int l
332341{
333342 struct apple_dart * dart = stream_map -> dart ;
334343 u32 tcr = dart -> hw -> tcr_enabled ;
335- int sid ;
344+ int sid , remap_to ;
336345
337346 if (levels == 4 )
338347 tcr |= dart -> hw -> tcr_4level ;
339348
340349 WARN_ON (levels != 3 && levels != 4 );
341350 WARN_ON (levels == 4 && !dart -> four_level );
342- for_each_set_bit (sid , stream_map -> sidmap , dart -> num_streams )
343- writel (tcr , dart -> regs + DART_TCR (dart , sid ));
351+
352+ /* Search for first enabled sid and enable translation. */
353+ sid = find_first_bit (stream_map -> sidmap , dart -> num_streams );
354+ if (sid >= dart -> num_streams )
355+ return ;
356+ writel (tcr , dart -> regs + DART_TCR (dart , sid ));
357+
358+ /* Enable remapping for the remaining used sids. */
359+ remap_to = sid ++ ;
360+ for_each_set_bit_from (sid , stream_map -> sidmap , dart -> num_streams )
361+ dart -> hw -> enable_remap (dart , sid , remap_to );
344362}
345363
346364static void apple_dart_hw_disable_dma (struct apple_dart_stream_map * stream_map )
347365{
348366 struct apple_dart * dart = stream_map -> dart ;
349367 int sid ;
350368
369+ /* This will also disable remap enabled in apple_dart_hw_enable_translation(). */
351370 for_each_set_bit (sid , stream_map -> sidmap , dart -> num_streams )
352371 writel (dart -> hw -> tcr_disabled , dart -> regs + DART_TCR (dart , sid ));
353372}
@@ -371,10 +390,17 @@ static void apple_dart_hw_set_ttbr(struct apple_dart_stream_map *stream_map,
371390 int sid ;
372391
373392 WARN_ON (paddr & ((1 << dart -> hw -> ttbr_shift ) - 1 ));
374- for_each_set_bit (sid , stream_map -> sidmap , dart -> num_streams )
375- writel (dart -> hw -> ttbr_valid |
376- (paddr >> dart -> hw -> ttbr_shift ) << dart -> hw -> ttbr_addr_field_shift ,
377- dart -> regs + DART_TTBR (dart , sid , idx ));
393+ /* Search for the first used stream and set its TTBR. All other sids
394+ * of this DART are handled via the remap feature and must not set a
395+ * valid TTBR.
396+ */
397+ sid = find_first_bit (stream_map -> sidmap , dart -> num_streams );
398+ if (sid >= dart -> num_streams )
399+ return ;
400+
401+ writel (dart -> hw -> ttbr_valid |
402+ (paddr >> dart -> hw -> ttbr_shift ) << dart -> hw -> ttbr_addr_field_shift ,
403+ dart -> regs + DART_TTBR (dart , sid , idx ));
378404}
379405
380406static void apple_dart_hw_clear_ttbr (struct apple_dart_stream_map * stream_map ,
@@ -527,7 +553,8 @@ apple_dart_t8110_hw_tlb_command(struct apple_dart_stream_map *stream_map,
527553
528554 if (ret )
529555 break ;
530-
556+ /* Since remap is used only the first sid needs to be invalidated. */
557+ break ;
531558 }
532559
533560 spin_unlock_irqrestore (& dart -> lock , flags );
@@ -556,6 +583,27 @@ apple_dart_t8110_hw_invalidate_tlb(struct apple_dart_stream_map *stream_map)
556583 stream_map , DART_T8110_TLB_CMD_OP_FLUSH_SID );
557584}
558585
586+ static void
587+ apple_dart_t8020_hw_enable_remap (struct apple_dart * dart , int sid , int remap_to )
588+ {
589+ u32 remap = readl (DART_REMAP (dart , sid ));
590+ remap = (remap & ~DART_REMAP_MASK (sid )) |
591+ field_prep (DART_REMAP_MASK (sid ), remap_to );
592+ writel (remap , DART_REMAP (dart , sid ));
593+
594+ u32 tcr = FIELD_PREP (DART_T8020_TCR_REMAP_ENABLE , 1 ) |
595+ FIELD_PREP (DART_T8020_TCR_TRANSLATE_ENABLE , 1 );
596+ writel (tcr , dart -> regs + DART_TCR (dart , sid ));
597+ }
598+
599+ static void
600+ apple_dart_t8110_hw_enable_remap (struct apple_dart * dart , int sid , int remap_to )
601+ {
602+ u32 tcr = FIELD_PREP (DART_T8110_TCR_REMAP , remap_to ) |
603+ FIELD_PREP (DART_T8110_TCR_REMAP_ENABLE , 1 );
604+ writel (tcr , dart -> regs + DART_TCR (dart , sid ));
605+ }
606+
559607static int apple_dart_hw_reset (struct apple_dart * dart )
560608{
561609 struct apple_dart_stream_map stream_map ;
@@ -1537,6 +1585,7 @@ static const struct apple_dart_hw apple_dart_hw_t8103 = {
15371585 .type = DART_T8020 ,
15381586 .irq_handler = apple_dart_t8020_irq ,
15391587 .invalidate_tlb = apple_dart_t8020_hw_invalidate_tlb ,
1588+ .enable_remap = apple_dart_t8020_hw_enable_remap ,
15401589 .oas = 36 ,
15411590 .fmt = APPLE_DART ,
15421591 .max_sid_count = 16 ,
@@ -1563,6 +1612,7 @@ static const struct apple_dart_hw apple_dart_hw_t8103_usb4 = {
15631612 .type = DART_T8020 ,
15641613 .irq_handler = apple_dart_t8020_irq ,
15651614 .invalidate_tlb = apple_dart_t8020_hw_invalidate_tlb ,
1615+ .enable_remap = apple_dart_t8020_hw_enable_remap ,
15661616 .oas = 36 ,
15671617 .fmt = APPLE_DART ,
15681618 .max_sid_count = 64 ,
@@ -1589,6 +1639,7 @@ static const struct apple_dart_hw apple_dart_hw_t6000 = {
15891639 .type = DART_T6000 ,
15901640 .irq_handler = apple_dart_t8020_irq ,
15911641 .invalidate_tlb = apple_dart_t8020_hw_invalidate_tlb ,
1642+ .enable_remap = apple_dart_t8020_hw_enable_remap ,
15921643 .oas = 42 ,
15931644 .fmt = APPLE_DART2 ,
15941645 .max_sid_count = 16 ,
@@ -1615,6 +1666,7 @@ static const struct apple_dart_hw apple_dart_hw_t8110 = {
16151666 .type = DART_T8110 ,
16161667 .irq_handler = apple_dart_t8110_irq ,
16171668 .invalidate_tlb = apple_dart_t8110_hw_invalidate_tlb ,
1669+ .enable_remap = apple_dart_t8110_hw_enable_remap ,
16181670 .fmt = APPLE_DART2 ,
16191671 .max_sid_count = 256 ,
16201672
0 commit comments