diff options
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.patch | 164 |
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 + |