Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions drivers/iommu/apple-dart.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ struct apple_dart {
u32 pgsize;
u32 num_streams;
u32 supports_bypass : 1;
/* J613 MTP keeps issuing DMA in the boot loader identity domain. */
bool live_mtp;
u32 four_level : 1;
u32 locked : 1;
u32 tunneled : 1;
Expand Down Expand Up @@ -2654,6 +2656,10 @@ static int apple_dart_attach_dev_paging(struct iommu_domain *domain,
struct apple_dart_domain *dart_domain = to_dart_domain(domain);
bool streams_added = false;

for_each_stream_map(i, cfg, stream_map)
if (stream_map->dart->live_mtp)
return -EBUSY;

for_each_stream_map(i, cfg, stream_map)
WARN_ON(pm_runtime_get_sync(stream_map->dart->dev) < 0);

Expand Down Expand Up @@ -2747,6 +2753,10 @@ static int apple_dart_attach_dev_blocked(struct iommu_domain *domain,
struct apple_dart_stream_map *stream_map;
int i;

for_each_stream_map(i, cfg, stream_map)
if (stream_map->dart->live_mtp)
return -EBUSY;

if (cfg->locked)
return -EINVAL;

Expand Down Expand Up @@ -3483,7 +3493,8 @@ static int apple_dart_def_domain_type(struct device *dev)
if (cfg->stream_maps[0].dart->managed_sids ||
apple_dart_has_borrowed(cfg->stream_maps[0].dart))
return IOMMU_DOMAIN_DMA;
if (cfg->stream_maps[0].dart->retained_mtp)
if (cfg->stream_maps[0].dart->retained_mtp ||
cfg->stream_maps[0].dart->live_mtp)
return IOMMU_DOMAIN_IDENTITY;
if (cfg->stream_maps[0].dart->pgsize > PAGE_SIZE)
return IOMMU_DOMAIN_IDENTITY;
Expand Down Expand Up @@ -4483,6 +4494,25 @@ static int apple_dart_probe(struct platform_device *pdev)
goto err_clk_disable;
}

/* A live MTP epoch must never lose its firmware DMA addresses. */
if (of_property_present(dev->of_node, "apple,bypass-handoff-streams")) {
u32 stream;

if (!of_machine_is_compatible("apple,j613") ||
!of_device_is_compatible(dev->of_node, "apple,t8122-dart") ||
res->start != 0x2fa808000ULL || !dart->supports_bypass ||
of_property_count_u32_elems(dev->of_node,
"apple,bypass-handoff-streams") != 1 ||
of_property_read_u32(dev->of_node, "apple,bypass-handoff-streams",
&stream) ||
stream != 1 || stream >= dart->num_streams ||
apple_dart_readl(dart, DART_TCR(dart, stream)) != dart->hw->tcr_bypass) {
ret = -EINVAL;
goto err_clk_disable;
}
dart->live_mtp = true;
}

ret = apple_dart_read_remaps(dart);
if (ret)
goto err_clk_disable;
Expand Down Expand Up @@ -4594,7 +4624,7 @@ static int apple_dart_probe(struct platform_device *pdev)
}
/* ENABLE is write-one-to-set; no foreign stream changes state. */
apple_dart_writel(dart, dart->managed_sids, dart->hw->enable_streams);
} else if (!dart->locked && !dart->retained_mtp && !dart->preserve_display) {
} else if (!dart->locked && !dart->retained_mtp && !dart->live_mtp && !dart->preserve_display) {
ret = apple_dart_hw_reset(dart);
if (ret)
goto err_clk_disable;
Expand Down Expand Up @@ -4830,7 +4860,7 @@ static void apple_dart_remove(struct platform_device *pdev)
* A command issued then never completes. The next probe resets the
* block after that clock is running again.
*/
if (!dart->locked && !dart->retained_mtp &&
if (!dart->locked && !dart->retained_mtp && !dart->live_mtp &&
!READ_ONCE(dart->commands_gated))
apple_dart_hw_reset(dart);

Expand All @@ -4840,7 +4870,8 @@ static void apple_dart_remove(struct platform_device *pdev)
iommu_device_unregister(&dart->iommu);
iommu_device_sysfs_remove(&dart->iommu);

clk_bulk_disable_unprepare(dart->num_clks, dart->clks);
if (!dart->live_mtp)
clk_bulk_disable_unprepare(dart->num_clks, dart->clks);
}

static void apple_dart_shutdown(struct platform_device *pdev)
Expand Down Expand Up @@ -4984,6 +5015,9 @@ static __maybe_unused int apple_dart_suspend(struct device *dev)
{
struct apple_dart *dart = dev_get_drvdata(dev);

if (dart->live_mtp)
return -EBUSY;

dart->tunnel_state_restored = false;
if (READ_ONCE(dart->commands_gated))
return 0;
Expand Down
2 changes: 2 additions & 0 deletions drivers/soc/apple/rtkit-helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,8 @@ static const struct dev_pm_ops apple_rtkit_helper_pm_ops = {

static const struct of_device_id apple_rtkit_helper_of_match[] = {
{ .compatible = "apple,rtk-helper-asc4" },
/* J613/J615 25G83 DTs omit the generic fallback (see t8122-j613-25g83.dts). */
{ .compatible = "apple,t8122-rtk-helper-asc4" },
{},
};
MODULE_DEVICE_TABLE(of, apple_rtkit_helper_of_match);
Expand Down