Commit 3bc01028 authored by Hector Martin's avatar Hector Martin Committed by Joerg Roedel
Browse files

iommu: apple-dart: Allow mismatched bypass support



This is needed by ISP, which has DART0 with bypass and DART1/2 without.

Signed-off-by: default avatarHector Martin <marcan@marcan.st>
Reviewed-by: default avatarAlyssa Rosenzweig <alyssa@rosenzweig.io>
Signed-off-by: default avatarSasha Finkelstein <fnkl.kernel@gmail.com>
Reviewed-by: default avatarSven Peter <sven@svenpeter.dev>
Link: https://lore.kernel.org/r/20250307-isp-dart-v3-2-684fe4489591@gmail.com


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 9d7b779e
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -277,6 +277,9 @@ struct apple_dart_domain {
 * @streams: streams for this device
 */
struct apple_dart_master_cfg {
	/* Intersection of DART capabilitles */
	u32 supports_bypass : 1;

	struct apple_dart_stream_map stream_maps[MAX_DARTS_PER_DEVICE];
};

@@ -684,7 +687,7 @@ static int apple_dart_attach_dev_identity(struct iommu_domain *domain,
	struct apple_dart_stream_map *stream_map;
	int i;

	if (!cfg->stream_maps[0].dart->supports_bypass)
	if (!cfg->supports_bypass)
		return -EINVAL;

	for_each_stream_map(i, cfg, stream_map)
@@ -792,20 +795,24 @@ static int apple_dart_of_xlate(struct device *dev,
		return -EINVAL;
	sid = args->args[0];

	if (!cfg)
	if (!cfg) {
		cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);

		/* Will be ANDed with DART capabilities */
		cfg->supports_bypass = true;
	}
	if (!cfg)
		return -ENOMEM;
	dev_iommu_priv_set(dev, cfg);

	cfg_dart = cfg->stream_maps[0].dart;
	if (cfg_dart) {
		if (cfg_dart->supports_bypass != dart->supports_bypass)
			return -EINVAL;
		if (cfg_dart->pgsize != dart->pgsize)
			return -EINVAL;
	}

	cfg->supports_bypass &= dart->supports_bypass;

	for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) {
		if (cfg->stream_maps[i].dart == dart) {
			set_bit(sid, cfg->stream_maps[i].sidmap);
@@ -945,7 +952,7 @@ static int apple_dart_def_domain_type(struct device *dev)

	if (cfg->stream_maps[0].dart->pgsize > PAGE_SIZE)
		return IOMMU_DOMAIN_IDENTITY;
	if (!cfg->stream_maps[0].dart->supports_bypass)
	if (!cfg->supports_bypass)
		return IOMMU_DOMAIN_DMA;

	return 0;