aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3342-drm-amdkfd-Reorganize-kfd-resume-code.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3342-drm-amdkfd-Reorganize-kfd-resume-code.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3342-drm-amdkfd-Reorganize-kfd-resume-code.patch164
1 files changed, 164 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3342-drm-amdkfd-Reorganize-kfd-resume-code.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3342-drm-amdkfd-Reorganize-kfd-resume-code.patch
new file mode 100644
index 00000000..4da17423
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3342-drm-amdkfd-Reorganize-kfd-resume-code.patch
@@ -0,0 +1,164 @@
+From df9baa67a2a9384bdcbbe37f7c562f8a640551d9 Mon Sep 17 00:00:00 2001
+From: Yong Zhao <yong.zhao@amd.com>
+Date: Wed, 20 Sep 2017 18:10:13 -0400
+Subject: [PATCH 3342/4131] drm/amdkfd: Reorganize kfd resume code
+
+The idea is to let kfd init and resume function share the same code path
+as much as possible, rather than to have two copies of almost identical
+code. That way improves the code readability and maintainability.
+
+Signed-off-by: Yong Zhao <yong.zhao@amd.com>
+Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
+Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com>
+Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_device.c | 78 +++++++++++++++++----------------
+ 1 file changed, 40 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+index 5df12b2..e5d1387 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+@@ -92,6 +92,8 @@ static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size,
+ unsigned int chunk_size);
+ static void kfd_gtt_sa_fini(struct kfd_dev *kfd);
+
++static int kfd_resume(struct kfd_dev *kfd);
++
+ static const struct kfd_device_info *lookup_device_info(unsigned short did)
+ {
+ size_t i;
+@@ -169,15 +171,8 @@ static bool device_iommu_pasid_init(struct kfd_dev *kfd)
+ (unsigned int)(1 << kfd->device_info->max_pasid_bits),
+ iommu_info.max_pasids);
+
+- err = amd_iommu_init_device(kfd->pdev, pasid_limit);
+- if (err < 0) {
+- dev_err(kfd_device, "error initializing iommu device\n");
+- return false;
+- }
+-
+ if (!kfd_set_pasid_limit(pasid_limit)) {
+ dev_err(kfd_device, "error setting pasid limit\n");
+- amd_iommu_free_device(kfd->pdev);
+ return false;
+ }
+
+@@ -273,29 +268,22 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
+ goto kfd_interrupt_error;
+ }
+
+- if (!device_iommu_pasid_init(kfd)) {
+- dev_err(kfd_device,
+- "Error initializing iommuv2 for device %x:%x\n",
+- kfd->pdev->vendor, kfd->pdev->device);
+- goto device_iommu_pasid_error;
+- }
+- amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
+- iommu_pasid_shutdown_callback);
+- amd_iommu_set_invalid_ppr_cb(kfd->pdev, iommu_invalid_ppr_cb);
+-
+ kfd->dqm = device_queue_manager_init(kfd);
+ if (!kfd->dqm) {
+ dev_err(kfd_device, "Error initializing queue manager\n");
+ goto device_queue_manager_error;
+ }
+
+- if (kfd->dqm->ops.start(kfd->dqm)) {
++ if (!device_iommu_pasid_init(kfd)) {
+ dev_err(kfd_device,
+- "Error starting queue manager for device %x:%x\n",
++ "Error initializing iommuv2 for device %x:%x\n",
+ kfd->pdev->vendor, kfd->pdev->device);
+- goto dqm_start_error;
++ goto device_iommu_pasid_error;
+ }
+
++ if (kfd_resume(kfd))
++ goto kfd_resume_error;
++
+ kfd->dbgmgr = NULL;
+
+ kfd->init_complete = true;
+@@ -307,11 +295,10 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
+
+ goto out;
+
+-dqm_start_error:
++kfd_resume_error:
++device_iommu_pasid_error:
+ device_queue_manager_uninit(kfd->dqm);
+ device_queue_manager_error:
+- amd_iommu_free_device(kfd->pdev);
+-device_iommu_pasid_error:
+ kfd_interrupt_exit(kfd);
+ kfd_interrupt_error:
+ kfd_topology_remove_device(kfd);
+@@ -331,8 +318,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
+ void kgd2kfd_device_exit(struct kfd_dev *kfd)
+ {
+ if (kfd->init_complete) {
++ kgd2kfd_suspend(kfd);
+ device_queue_manager_uninit(kfd->dqm);
+- amd_iommu_free_device(kfd->pdev);
+ kfd_interrupt_exit(kfd);
+ kfd_topology_remove_device(kfd);
+ kfd_doorbell_fini(kfd);
+@@ -355,25 +342,40 @@ void kgd2kfd_suspend(struct kfd_dev *kfd)
+
+ int kgd2kfd_resume(struct kfd_dev *kfd)
+ {
+- unsigned int pasid_limit;
+- int err;
++ if (!kfd->init_complete)
++ return 0;
+
+- pasid_limit = kfd_get_pasid_limit();
++ return kfd_resume(kfd);
+
+- if (kfd->init_complete) {
+- err = amd_iommu_init_device(kfd->pdev, pasid_limit);
+- if (err < 0) {
+- dev_err(kfd_device, "failed to initialize iommu\n");
+- return -ENXIO;
+- }
++}
+
+- amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
+- iommu_pasid_shutdown_callback);
+- amd_iommu_set_invalid_ppr_cb(kfd->pdev, iommu_invalid_ppr_cb);
+- kfd->dqm->ops.start(kfd->dqm);
++static int kfd_resume(struct kfd_dev *kfd)
++{
++ int err = 0;
++ unsigned int pasid_limit = kfd_get_pasid_limit();
++
++ err = amd_iommu_init_device(kfd->pdev, pasid_limit);
++ if (err)
++ return -ENXIO;
++ amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
++ iommu_pasid_shutdown_callback);
++ amd_iommu_set_invalid_ppr_cb(kfd->pdev,
++ iommu_invalid_ppr_cb);
++
++ err = kfd->dqm->ops.start(kfd->dqm);
++ if (err) {
++ dev_err(kfd_device,
++ "Error starting queue manager for device %x:%x\n",
++ kfd->pdev->vendor, kfd->pdev->device);
++ goto dqm_start_error;
+ }
+
+- return 0;
++ return err;
++
++dqm_start_error:
++ amd_iommu_free_device(kfd->pdev);
++
++ return err;
+ }
+
+ /* This is called directly from KGD at ISR. */
+--
+2.7.4
+