|
136 | 136 | #define DART_T8110_TCR 0x1000 |
137 | 137 | #define DART_T8110_TCR_REMAP GENMASK(11, 8) |
138 | 138 | #define DART_T8110_TCR_REMAP_EN BIT(7) |
| 139 | +#define DART_T8110_TCR_FOUR_LEVEL BIT(3) |
139 | 140 | #define DART_T8110_TCR_BYPASS_DAPF BIT(2) |
140 | 141 | #define DART_T8110_TCR_BYPASS_DART BIT(1) |
141 | 142 | #define DART_T8110_TCR_TRANSLATE_ENABLE BIT(0) |
@@ -180,6 +181,7 @@ struct apple_dart_hw { |
180 | 181 | u32 tcr_enabled; |
181 | 182 | u32 tcr_disabled; |
182 | 183 | u32 tcr_bypass; |
| 184 | + u32 tcr_4level; |
183 | 185 |
|
184 | 186 | u32 ttbr; |
185 | 187 | u32 ttbr_valid; |
@@ -220,6 +222,7 @@ struct apple_dart { |
220 | 222 | u32 pgsize; |
221 | 223 | u32 num_streams; |
222 | 224 | u32 supports_bypass : 1; |
| 225 | + u32 four_level : 1; |
223 | 226 |
|
224 | 227 | struct iommu_group *sid2group[DART_MAX_STREAMS]; |
225 | 228 | struct iommu_device iommu; |
@@ -308,13 +311,16 @@ static struct apple_dart_domain *to_dart_domain(struct iommu_domain *dom) |
308 | 311 | } |
309 | 312 |
|
310 | 313 | 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) |
312 | 315 | { |
313 | 316 | struct apple_dart *dart = stream_map->dart; |
314 | 317 | int sid; |
315 | 318 |
|
| 319 | + WARN_ON(levels != 3 && levels != 4); |
| 320 | + WARN_ON(levels == 4 && !dart->four_level); |
316 | 321 | 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)); |
318 | 324 | } |
319 | 325 |
|
320 | 326 | 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, |
574 | 580 | for (; i < stream_map->dart->hw->ttbr_count; ++i) |
575 | 581 | apple_dart_hw_clear_ttbr(stream_map, i); |
576 | 582 |
|
577 | | - apple_dart_hw_enable_translation(stream_map); |
| 583 | + apple_dart_hw_enable_translation(stream_map, |
| 584 | + pgtbl_cfg->apple_dart_cfg.n_levels); |
578 | 585 | stream_map->dart->hw->invalidate_tlb(stream_map); |
579 | 586 | } |
580 | 587 |
|
@@ -619,7 +626,7 @@ static int apple_dart_finalize_domain(struct apple_dart_domain *dart_domain, |
619 | 626 | dart_domain->domain.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; |
620 | 627 | dart_domain->domain.geometry.aperture_start = 0; |
621 | 628 | 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); |
623 | 630 | dart_domain->domain.geometry.force_aperture = true; |
624 | 631 |
|
625 | 632 | dart_domain->finalized = true; |
@@ -1183,6 +1190,7 @@ static int apple_dart_probe(struct platform_device *pdev) |
1183 | 1190 | dart->ias = FIELD_GET(DART_T8110_PARAMS3_VA_WIDTH, dart_params[2]); |
1184 | 1191 | dart->oas = FIELD_GET(DART_T8110_PARAMS3_PA_WIDTH, dart_params[2]); |
1185 | 1192 | dart->num_streams = FIELD_GET(DART_T8110_PARAMS4_NUM_SIDS, dart_params[3]); |
| 1193 | + dart->four_level = dart->ias > 36; |
1186 | 1194 | break; |
1187 | 1195 | } |
1188 | 1196 |
|
@@ -1217,9 +1225,9 @@ static int apple_dart_probe(struct platform_device *pdev) |
1217 | 1225 |
|
1218 | 1226 | dev_info( |
1219 | 1227 | &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", |
1221 | 1229 | dart->pgsize, dart->num_streams, dart->supports_bypass, |
1222 | | - dart->pgsize > PAGE_SIZE); |
| 1230 | + dart->pgsize > PAGE_SIZE, dart->ias, dart->oas); |
1223 | 1231 | return 0; |
1224 | 1232 |
|
1225 | 1233 | err_sysfs_remove: |
@@ -1341,6 +1349,7 @@ static const struct apple_dart_hw apple_dart_hw_t8110 = { |
1341 | 1349 | .tcr_enabled = DART_T8110_TCR_TRANSLATE_ENABLE, |
1342 | 1350 | .tcr_disabled = 0, |
1343 | 1351 | .tcr_bypass = DART_T8110_TCR_BYPASS_DAPF | DART_T8110_TCR_BYPASS_DART, |
| 1352 | + .tcr_4level = DART_T8110_TCR_FOUR_LEVEL, |
1344 | 1353 |
|
1345 | 1354 | .ttbr = DART_T8110_TTBR, |
1346 | 1355 | .ttbr_valid = DART_T8110_TTBR_VALID, |
|
0 commit comments