Skip to content

Commit 5229bd5

Browse files
marcanjoergroedel
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 <[email protected]> Signed-off-by: Janne Grunau <[email protected]> Reviewed-by: Sven Peter <[email protected]> Reviewed-by: Neal Gompa <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 74a0e72 commit 5229bd5

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

drivers/iommu/apple-dart.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
#define DART_T8110_TCR 0x1000
134134
#define DART_T8110_TCR_REMAP GENMASK(11, 8)
135135
#define DART_T8110_TCR_REMAP_EN BIT(7)
136+
#define DART_T8110_TCR_FOUR_LEVEL BIT(3)
136137
#define DART_T8110_TCR_BYPASS_DAPF BIT(2)
137138
#define DART_T8110_TCR_BYPASS_DART BIT(1)
138139
#define DART_T8110_TCR_TRANSLATE_ENABLE BIT(0)
@@ -177,6 +178,7 @@ struct apple_dart_hw {
177178
u32 tcr_enabled;
178179
u32 tcr_disabled;
179180
u32 tcr_bypass;
181+
u32 tcr_4level;
180182

181183
u32 ttbr;
182184
u32 ttbr_valid;
@@ -217,6 +219,7 @@ struct apple_dart {
217219
u32 pgsize;
218220
u32 num_streams;
219221
u32 supports_bypass : 1;
222+
u32 four_level : 1;
220223

221224
struct iommu_group *sid2group[DART_MAX_STREAMS];
222225
struct iommu_device iommu;
@@ -305,13 +308,19 @@ static struct apple_dart_domain *to_dart_domain(struct iommu_domain *dom)
305308
}
306309

307310
static void
308-
apple_dart_hw_enable_translation(struct apple_dart_stream_map *stream_map)
311+
apple_dart_hw_enable_translation(struct apple_dart_stream_map *stream_map, int levels)
309312
{
310313
struct apple_dart *dart = stream_map->dart;
314+
u32 tcr = dart->hw->tcr_enabled;
311315
int sid;
312316

317+
if (levels == 4)
318+
tcr |= dart->hw->tcr_4level;
319+
320+
WARN_ON(levels != 3 && levels != 4);
321+
WARN_ON(levels == 4 && !dart->four_level);
313322
for_each_set_bit(sid, stream_map->sidmap, dart->num_streams)
314-
writel(dart->hw->tcr_enabled, dart->regs + DART_TCR(dart, sid));
323+
writel(tcr, dart->regs + DART_TCR(dart, sid));
315324
}
316325

317326
static void apple_dart_hw_disable_dma(struct apple_dart_stream_map *stream_map)
@@ -569,7 +578,8 @@ apple_dart_setup_translation(struct apple_dart_domain *domain,
569578
for (; i < stream_map->dart->hw->ttbr_count; ++i)
570579
apple_dart_hw_clear_ttbr(stream_map, i);
571580

572-
apple_dart_hw_enable_translation(stream_map);
581+
apple_dart_hw_enable_translation(stream_map,
582+
pgtbl_cfg->apple_dart_cfg.n_levels);
573583
stream_map->dart->hw->invalidate_tlb(stream_map);
574584
}
575585

@@ -614,7 +624,7 @@ static int apple_dart_finalize_domain(struct apple_dart_domain *dart_domain,
614624
dart_domain->domain.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
615625
dart_domain->domain.geometry.aperture_start = 0;
616626
dart_domain->domain.geometry.aperture_end =
617-
(dma_addr_t)DMA_BIT_MASK(dart->ias);
627+
(dma_addr_t)DMA_BIT_MASK(pgtbl_cfg.ias);
618628
dart_domain->domain.geometry.force_aperture = true;
619629

620630
dart_domain->finalized = true;
@@ -807,6 +817,8 @@ static int apple_dart_of_xlate(struct device *dev,
807817
if (cfg_dart) {
808818
if (cfg_dart->pgsize != dart->pgsize)
809819
return -EINVAL;
820+
if (cfg_dart->ias != dart->ias)
821+
return -EINVAL;
810822
}
811823

812824
cfg->supports_bypass &= dart->supports_bypass;
@@ -1137,6 +1149,7 @@ static int apple_dart_probe(struct platform_device *pdev)
11371149
dart->ias = FIELD_GET(DART_T8110_PARAMS3_VA_WIDTH, dart_params[2]);
11381150
dart->oas = FIELD_GET(DART_T8110_PARAMS3_PA_WIDTH, dart_params[2]);
11391151
dart->num_streams = FIELD_GET(DART_T8110_PARAMS4_NUM_SIDS, dart_params[3]);
1152+
dart->four_level = dart->ias > 36;
11401153
break;
11411154
}
11421155

@@ -1169,9 +1182,9 @@ static int apple_dart_probe(struct platform_device *pdev)
11691182

11701183
dev_info(
11711184
&pdev->dev,
1172-
"DART [pagesize %x, %d streams, bypass support: %d, bypass forced: %d] initialized\n",
1185+
"DART [pagesize %x, %d streams, bypass support: %d, bypass forced: %d, AS %d -> %d] initialized\n",
11731186
dart->pgsize, dart->num_streams, dart->supports_bypass,
1174-
dart->pgsize > PAGE_SIZE);
1187+
dart->pgsize > PAGE_SIZE, dart->ias, dart->oas);
11751188
return 0;
11761189

11771190
err_sysfs_remove:
@@ -1292,6 +1305,7 @@ static const struct apple_dart_hw apple_dart_hw_t8110 = {
12921305
.tcr_enabled = DART_T8110_TCR_TRANSLATE_ENABLE,
12931306
.tcr_disabled = 0,
12941307
.tcr_bypass = DART_T8110_TCR_BYPASS_DAPF | DART_T8110_TCR_BYPASS_DART,
1308+
.tcr_4level = DART_T8110_TCR_FOUR_LEVEL,
12951309

12961310
.ttbr = DART_T8110_TTBR,
12971311
.ttbr_valid = DART_T8110_TTBR_VALID,

0 commit comments

Comments
 (0)