Skip to content

Commit 4d5b50e

Browse files
marcanjannau
authored andcommitted
iommu: apple-dart: Add 4-level page table support
The T8110 variant DART implementation on T602x SoCs indicates an IAS of 42, which requires an extra page table level. The extra level is optional, but let's implement it. Later it might be useful to restrict this based on the actual attached devices, since most won't need that much address space anyway. Signed-off-by: Hector Martin <marcan@marcan.st>
1 parent d8353d9 commit 4d5b50e

1 file changed

Lines changed: 15 additions & 6 deletions

File tree

drivers/iommu/apple-dart.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
#define DART_T8110_TCR 0x1000
137137
#define DART_T8110_TCR_REMAP GENMASK(11, 8)
138138
#define DART_T8110_TCR_REMAP_EN BIT(7)
139+
#define DART_T8110_TCR_FOUR_LEVEL BIT(3)
139140
#define DART_T8110_TCR_BYPASS_DAPF BIT(2)
140141
#define DART_T8110_TCR_BYPASS_DART BIT(1)
141142
#define DART_T8110_TCR_TRANSLATE_ENABLE BIT(0)
@@ -180,6 +181,7 @@ struct apple_dart_hw {
180181
u32 tcr_enabled;
181182
u32 tcr_disabled;
182183
u32 tcr_bypass;
184+
u32 tcr_4level;
183185

184186
u32 ttbr;
185187
u32 ttbr_valid;
@@ -220,6 +222,7 @@ struct apple_dart {
220222
u32 pgsize;
221223
u32 num_streams;
222224
u32 supports_bypass : 1;
225+
u32 four_level : 1;
223226

224227
struct iommu_group *sid2group[DART_MAX_STREAMS];
225228
struct iommu_device iommu;
@@ -308,13 +311,16 @@ static struct apple_dart_domain *to_dart_domain(struct iommu_domain *dom)
308311
}
309312

310313
static void
311-
apple_dart_hw_enable_translation(struct apple_dart_stream_map *stream_map)
314+
apple_dart_hw_enable_translation(struct apple_dart_stream_map *stream_map, int levels)
312315
{
313316
struct apple_dart *dart = stream_map->dart;
314317
int sid;
315318

319+
WARN_ON(levels != 3 && levels != 4);
320+
WARN_ON(levels == 4 && !dart->four_level);
316321
for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
317-
writel(dart->hw->tcr_enabled, dart->regs + DART_TCR(dart, sid));
322+
writel(dart->hw->tcr_enabled | (levels == 4 ? dart->hw->tcr_4level : 0),
323+
dart->regs + DART_TCR(dart, sid));
318324
}
319325

320326
static void apple_dart_hw_disable_dma(struct apple_dart_stream_map *stream_map)
@@ -574,7 +580,8 @@ apple_dart_setup_translation(struct apple_dart_domain *domain,
574580
for (; i < stream_map->dart->hw->ttbr_count; ++i)
575581
apple_dart_hw_clear_ttbr(stream_map, i);
576582

577-
apple_dart_hw_enable_translation(stream_map);
583+
apple_dart_hw_enable_translation(stream_map,
584+
pgtbl_cfg->apple_dart_cfg.n_levels);
578585
stream_map->dart->hw->invalidate_tlb(stream_map);
579586
}
580587

@@ -619,7 +626,7 @@ static int apple_dart_finalize_domain(struct apple_dart_domain *dart_domain,
619626
dart_domain->domain.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
620627
dart_domain->domain.geometry.aperture_start = 0;
621628
dart_domain->domain.geometry.aperture_end =
622-
(dma_addr_t)DMA_BIT_MASK(dart->ias);
629+
(dma_addr_t)DMA_BIT_MASK(pgtbl_cfg.ias);
623630
dart_domain->domain.geometry.force_aperture = true;
624631

625632
dart_domain->finalized = true;
@@ -1183,6 +1190,7 @@ static int apple_dart_probe(struct platform_device *pdev)
11831190
dart->ias = FIELD_GET(DART_T8110_PARAMS3_VA_WIDTH, dart_params[2]);
11841191
dart->oas = FIELD_GET(DART_T8110_PARAMS3_PA_WIDTH, dart_params[2]);
11851192
dart->num_streams = FIELD_GET(DART_T8110_PARAMS4_NUM_SIDS, dart_params[3]);
1193+
dart->four_level = dart->ias > 36;
11861194
break;
11871195
}
11881196

@@ -1217,9 +1225,9 @@ static int apple_dart_probe(struct platform_device *pdev)
12171225

12181226
dev_info(
12191227
&pdev->dev,
1220-
"DART [pagesize %x, %d streams, bypass support: %d, bypass forced: %d] initialized\n",
1228+
"DART [pagesize %x, %d streams, bypass support: %d, bypass forced: %d, AS %d -> %d] initialized\n",
12211229
dart->pgsize, dart->num_streams, dart->supports_bypass,
1222-
dart->pgsize > PAGE_SIZE);
1230+
dart->pgsize > PAGE_SIZE, dart->ias, dart->oas);
12231231
return 0;
12241232

12251233
err_sysfs_remove:
@@ -1341,6 +1349,7 @@ static const struct apple_dart_hw apple_dart_hw_t8110 = {
13411349
.tcr_enabled = DART_T8110_TCR_TRANSLATE_ENABLE,
13421350
.tcr_disabled = 0,
13431351
.tcr_bypass = DART_T8110_TCR_BYPASS_DAPF | DART_T8110_TCR_BYPASS_DART,
1352+
.tcr_4level = DART_T8110_TCR_FOUR_LEVEL,
13441353

13451354
.ttbr = DART_T8110_TTBR,
13461355
.ttbr_valid = DART_T8110_TTBR_VALID,

0 commit comments

Comments
 (0)