Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44d8cc6f authored by Yong Zhao's avatar Yong Zhao Committed by Alex Deucher
Browse files

drm/amdkfd: Fix ATS capablity was not reported correctly on some APUs



Because CRAT_CU_FLAGS_IOMMU_PRESENT was not set in some BIOS crat, we
need to workaround this.

For future compatibility, we also overwrite the bit in capability according
to the value of needs_iommu_device.

Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarYong Zhao <Yong.Zhao@amd.com>
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 15426dbb
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -62,9 +62,20 @@ int kfd_iommu_device_init(struct kfd_dev *kfd)
	struct amd_iommu_device_info iommu_info;
	unsigned int pasid_limit;
	int err;
	struct kfd_topology_device *top_dev;

	if (!kfd->device_info->needs_iommu_device)
	top_dev = kfd_topology_device_by_id(kfd->id);

	/*
	 * Overwrite ATS capability according to needs_iommu_device to fix
	 * potential missing corresponding bit in CRAT of BIOS.
	 */
	if (!kfd->device_info->needs_iommu_device) {
		top_dev->node_props.capability &= ~HSA_CAP_ATS_PRESENT;
		return 0;
	}

	top_dev->node_props.capability |= HSA_CAP_ATS_PRESENT;

	iommu_info.flags = 0;
	err = amd_iommu_device_info(kfd->pdev, &iommu_info);
+1 −0
Original line number Diff line number Diff line
@@ -806,6 +806,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu);
int kfd_topology_remove_device(struct kfd_dev *gpu);
struct kfd_topology_device *kfd_topology_device_by_proximity_domain(
						uint32_t proximity_domain);
struct kfd_topology_device *kfd_topology_device_by_id(uint32_t gpu_id);
struct kfd_dev *kfd_device_by_id(uint32_t gpu_id);
struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev);
int kfd_topology_enum_kfd_devices(uint8_t idx, struct kfd_dev **kdev);
+16 −5
Original line number Diff line number Diff line
@@ -63,22 +63,33 @@ struct kfd_topology_device *kfd_topology_device_by_proximity_domain(
	return device;
}

struct kfd_dev *kfd_device_by_id(uint32_t gpu_id)
struct kfd_topology_device *kfd_topology_device_by_id(uint32_t gpu_id)
{
	struct kfd_topology_device *top_dev;
	struct kfd_dev *device = NULL;
	struct kfd_topology_device *top_dev = NULL;
	struct kfd_topology_device *ret = NULL;

	down_read(&topology_lock);

	list_for_each_entry(top_dev, &topology_device_list, list)
		if (top_dev->gpu_id == gpu_id) {
			device = top_dev->gpu;
			ret = top_dev;
			break;
		}

	up_read(&topology_lock);

	return device;
	return ret;
}

struct kfd_dev *kfd_device_by_id(uint32_t gpu_id)
{
	struct kfd_topology_device *top_dev;

	top_dev = kfd_topology_device_by_id(gpu_id);
	if (!top_dev)
		return NULL;

	return top_dev->gpu;
}

struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev)