diff options
author | Yong Zhao <Yong.Zhao@amd.com> | 2018-09-12 21:42:20 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-09-20 11:25:23 -0400 |
commit | 44d8cc6f1a905e4bb1d4221a898abb0d7e9d100a (patch) | |
tree | 1901efb81cec5087aeda5ce03766319c7f5898c2 /drivers/gpu/drm/amd | |
parent | 15426dbb65c5b37680d27e84d58a1ed3b8532518 (diff) |
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: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Yong Zhao <Yong.Zhao@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_iommu.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 21 |
3 files changed, 29 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c index 7a61f38c09e6..01494752c36a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c | |||
@@ -62,9 +62,20 @@ int kfd_iommu_device_init(struct kfd_dev *kfd) | |||
62 | struct amd_iommu_device_info iommu_info; | 62 | struct amd_iommu_device_info iommu_info; |
63 | unsigned int pasid_limit; | 63 | unsigned int pasid_limit; |
64 | int err; | 64 | int err; |
65 | struct kfd_topology_device *top_dev; | ||
65 | 66 | ||
66 | if (!kfd->device_info->needs_iommu_device) | 67 | top_dev = kfd_topology_device_by_id(kfd->id); |
68 | |||
69 | /* | ||
70 | * Overwrite ATS capability according to needs_iommu_device to fix | ||
71 | * potential missing corresponding bit in CRAT of BIOS. | ||
72 | */ | ||
73 | if (!kfd->device_info->needs_iommu_device) { | ||
74 | top_dev->node_props.capability &= ~HSA_CAP_ATS_PRESENT; | ||
67 | return 0; | 75 | return 0; |
76 | } | ||
77 | |||
78 | top_dev->node_props.capability |= HSA_CAP_ATS_PRESENT; | ||
68 | 79 | ||
69 | iommu_info.flags = 0; | 80 | iommu_info.flags = 0; |
70 | err = amd_iommu_device_info(kfd->pdev, &iommu_info); | 81 | err = amd_iommu_device_info(kfd->pdev, &iommu_info); |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index f971710f1c91..92b285ca73aa 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h | |||
@@ -806,6 +806,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu); | |||
806 | int kfd_topology_remove_device(struct kfd_dev *gpu); | 806 | int kfd_topology_remove_device(struct kfd_dev *gpu); |
807 | struct kfd_topology_device *kfd_topology_device_by_proximity_domain( | 807 | struct kfd_topology_device *kfd_topology_device_by_proximity_domain( |
808 | uint32_t proximity_domain); | 808 | uint32_t proximity_domain); |
809 | struct kfd_topology_device *kfd_topology_device_by_id(uint32_t gpu_id); | ||
809 | struct kfd_dev *kfd_device_by_id(uint32_t gpu_id); | 810 | struct kfd_dev *kfd_device_by_id(uint32_t gpu_id); |
810 | struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev); | 811 | struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev); |
811 | int kfd_topology_enum_kfd_devices(uint8_t idx, struct kfd_dev **kdev); | 812 | int kfd_topology_enum_kfd_devices(uint8_t idx, struct kfd_dev **kdev); |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index bc95d4dfee2e..80f5db4ef75f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c | |||
@@ -63,22 +63,33 @@ struct kfd_topology_device *kfd_topology_device_by_proximity_domain( | |||
63 | return device; | 63 | return device; |
64 | } | 64 | } |
65 | 65 | ||
66 | struct kfd_dev *kfd_device_by_id(uint32_t gpu_id) | 66 | struct kfd_topology_device *kfd_topology_device_by_id(uint32_t gpu_id) |
67 | { | 67 | { |
68 | struct kfd_topology_device *top_dev; | 68 | struct kfd_topology_device *top_dev = NULL; |
69 | struct kfd_dev *device = NULL; | 69 | struct kfd_topology_device *ret = NULL; |
70 | 70 | ||
71 | down_read(&topology_lock); | 71 | down_read(&topology_lock); |
72 | 72 | ||
73 | list_for_each_entry(top_dev, &topology_device_list, list) | 73 | list_for_each_entry(top_dev, &topology_device_list, list) |
74 | if (top_dev->gpu_id == gpu_id) { | 74 | if (top_dev->gpu_id == gpu_id) { |
75 | device = top_dev->gpu; | 75 | ret = top_dev; |
76 | break; | 76 | break; |
77 | } | 77 | } |
78 | 78 | ||
79 | up_read(&topology_lock); | 79 | up_read(&topology_lock); |
80 | 80 | ||
81 | return device; | 81 | return ret; |
82 | } | ||
83 | |||
84 | struct kfd_dev *kfd_device_by_id(uint32_t gpu_id) | ||
85 | { | ||
86 | struct kfd_topology_device *top_dev; | ||
87 | |||
88 | top_dev = kfd_topology_device_by_id(gpu_id); | ||
89 | if (!top_dev) | ||
90 | return NULL; | ||
91 | |||
92 | return top_dev->gpu; | ||
82 | } | 93 | } |
83 | 94 | ||
84 | struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev) | 95 | struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev) |