|
133 | 133 | #define DART_T8110_TCR 0x1000 |
134 | 134 | #define DART_T8110_TCR_REMAP GENMASK(11, 8) |
135 | 135 | #define DART_T8110_TCR_REMAP_EN BIT(7) |
| 136 | +#define DART_T8110_TCR_FOUR_LEVEL BIT(3) |
136 | 137 | #define DART_T8110_TCR_BYPASS_DAPF BIT(2) |
137 | 138 | #define DART_T8110_TCR_BYPASS_DART BIT(1) |
138 | 139 | #define DART_T8110_TCR_TRANSLATE_ENABLE BIT(0) |
@@ -177,6 +178,7 @@ struct apple_dart_hw { |
177 | 178 | u32 tcr_enabled; |
178 | 179 | u32 tcr_disabled; |
179 | 180 | u32 tcr_bypass; |
| 181 | + u32 tcr_4level; |
180 | 182 |
|
181 | 183 | u32 ttbr; |
182 | 184 | u32 ttbr_valid; |
@@ -217,6 +219,7 @@ struct apple_dart { |
217 | 219 | u32 pgsize; |
218 | 220 | u32 num_streams; |
219 | 221 | u32 supports_bypass : 1; |
| 222 | + u32 four_level : 1; |
220 | 223 |
|
221 | 224 | struct iommu_group *sid2group[DART_MAX_STREAMS]; |
222 | 225 | struct iommu_device iommu; |
@@ -305,13 +308,19 @@ static struct apple_dart_domain *to_dart_domain(struct iommu_domain *dom) |
305 | 308 | } |
306 | 309 |
|
307 | 310 | 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) |
309 | 312 | { |
310 | 313 | struct apple_dart *dart = stream_map->dart; |
| 314 | + u32 tcr = dart->hw->tcr_enabled; |
311 | 315 | int sid; |
312 | 316 |
|
| 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); |
313 | 322 | 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)); |
315 | 324 | } |
316 | 325 |
|
317 | 326 | 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, |
569 | 578 | for (; i < stream_map->dart->hw->ttbr_count; ++i) |
570 | 579 | apple_dart_hw_clear_ttbr(stream_map, i); |
571 | 580 |
|
572 | | - apple_dart_hw_enable_translation(stream_map); |
| 581 | + apple_dart_hw_enable_translation(stream_map, |
| 582 | + pgtbl_cfg->apple_dart_cfg.n_levels); |
573 | 583 | stream_map->dart->hw->invalidate_tlb(stream_map); |
574 | 584 | } |
575 | 585 |
|
@@ -614,7 +624,7 @@ static int apple_dart_finalize_domain(struct apple_dart_domain *dart_domain, |
614 | 624 | dart_domain->domain.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; |
615 | 625 | dart_domain->domain.geometry.aperture_start = 0; |
616 | 626 | 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); |
618 | 628 | dart_domain->domain.geometry.force_aperture = true; |
619 | 629 |
|
620 | 630 | dart_domain->finalized = true; |
@@ -807,6 +817,8 @@ static int apple_dart_of_xlate(struct device *dev, |
807 | 817 | if (cfg_dart) { |
808 | 818 | if (cfg_dart->pgsize != dart->pgsize) |
809 | 819 | return -EINVAL; |
| 820 | + if (cfg_dart->ias != dart->ias) |
| 821 | + return -EINVAL; |
810 | 822 | } |
811 | 823 |
|
812 | 824 | cfg->supports_bypass &= dart->supports_bypass; |
@@ -1137,6 +1149,7 @@ static int apple_dart_probe(struct platform_device *pdev) |
1137 | 1149 | dart->ias = FIELD_GET(DART_T8110_PARAMS3_VA_WIDTH, dart_params[2]); |
1138 | 1150 | dart->oas = FIELD_GET(DART_T8110_PARAMS3_PA_WIDTH, dart_params[2]); |
1139 | 1151 | dart->num_streams = FIELD_GET(DART_T8110_PARAMS4_NUM_SIDS, dart_params[3]); |
| 1152 | + dart->four_level = dart->ias > 36; |
1140 | 1153 | break; |
1141 | 1154 | } |
1142 | 1155 |
|
@@ -1169,9 +1182,9 @@ static int apple_dart_probe(struct platform_device *pdev) |
1169 | 1182 |
|
1170 | 1183 | dev_info( |
1171 | 1184 | &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", |
1173 | 1186 | dart->pgsize, dart->num_streams, dart->supports_bypass, |
1174 | | - dart->pgsize > PAGE_SIZE); |
| 1187 | + dart->pgsize > PAGE_SIZE, dart->ias, dart->oas); |
1175 | 1188 | return 0; |
1176 | 1189 |
|
1177 | 1190 | err_sysfs_remove: |
@@ -1292,6 +1305,7 @@ static const struct apple_dart_hw apple_dart_hw_t8110 = { |
1292 | 1305 | .tcr_enabled = DART_T8110_TCR_TRANSLATE_ENABLE, |
1293 | 1306 | .tcr_disabled = 0, |
1294 | 1307 | .tcr_bypass = DART_T8110_TCR_BYPASS_DAPF | DART_T8110_TCR_BYPASS_DART, |
| 1308 | + .tcr_4level = DART_T8110_TCR_FOUR_LEVEL, |
1295 | 1309 |
|
1296 | 1310 | .ttbr = DART_T8110_TTBR, |
1297 | 1311 | .ttbr_valid = DART_T8110_TTBR_VALID, |
|
0 commit comments