aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/1207-drm-amdgpu-Load-write-pointer-manually-during-KFD-MQ.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/1207-drm-amdgpu-Load-write-pointer-manually-during-KFD-MQ.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/1207-drm-amdgpu-Load-write-pointer-manually-during-KFD-MQ.patch181
1 files changed, 181 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/1207-drm-amdgpu-Load-write-pointer-manually-during-KFD-MQ.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/1207-drm-amdgpu-Load-write-pointer-manually-during-KFD-MQ.patch
new file mode 100644
index 00000000..4c7b5132
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/1207-drm-amdgpu-Load-write-pointer-manually-during-KFD-MQ.patch
@@ -0,0 +1,181 @@
+From 746ab3ab0a3b5119e3bc68196619326b75f9fc7a Mon Sep 17 00:00:00 2001
+From: Jay Cornwall <Jay.Cornwall@amd.com>
+Date: Mon, 24 Oct 2016 17:12:50 -0500
+Subject: [PATCH 1207/4131] drm/amdgpu: Load write pointer manually during KFD
+ MQD setup
+
+CP_HQD_PQ_WPTR_POLL* fails intermittently on Tonga due to an RTL bug
+in CP clock gating logic.
+
+Load the write pointer inside the driver after the doorbell logic
+has been enabled. Apply the same shift/mask used by CP microcode to
+populate CP_HQD_PQ_WPTR manually. Unify this code path with MQD setup
+for SDMA queues.
+
+Change-Id: I3f4b8a3b778d00310c85c17f5af740cb3aa2844b
+Signed-off-by: Jay Cornwall <Jay.Cornwall@amd.com>
+---
+ .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 21 ++++++++-------------
+ drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c | 3 ++-
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h | 3 ++-
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c | 19 +++++++++++++------
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c | 17 ++++++++++++-----
+ 5 files changed, 37 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+index 0cf4a62..ffeea82 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+@@ -328,9 +328,8 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
+ if (!q->properties.is_active)
+ return 0;
+
+- retval = mqd->load_mqd(mqd, q->mqd, q->pipe,
+- q->queue, (uint32_t __user *) q->properties.write_ptr,
+- q->process->mm);
++ retval = mqd->load_mqd(mqd, q->mqd, q->pipe, q->queue, &q->properties,
++ q->process->mm);
+ if (retval != 0) {
+ deallocate_hqd(dqm, q);
+ mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
+@@ -447,10 +446,8 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
+ (q->properties.type == KFD_QUEUE_TYPE_COMPUTE ||
+ q->properties.type == KFD_QUEUE_TYPE_SDMA)) {
+ if (q->properties.is_active)
+- retval = mqd->load_mqd(mqd, q->mqd, q->pipe,
+- q->queue,
+- (uint32_t __user *)q->properties.write_ptr,
+- q->process->mm);
++ retval = mqd->load_mqd(mqd, q->mqd, q->pipe, q->queue,
++ &q->properties, q->process->mm);
+ else if (prev_active)
+ retval = mqd->destroy_mqd(mqd, q->mqd,
+ KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN,
+@@ -590,11 +587,9 @@ int process_restore_queues(struct device_queue_manager *dqm,
+ if (dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS &&
+ (q->properties.type == KFD_QUEUE_TYPE_COMPUTE ||
+ q->properties.type == KFD_QUEUE_TYPE_SDMA))
+- retval = mqd->load_mqd(
+- mqd, q->mqd, q->pipe, q->queue,
+- (uint32_t __user *)
+- q->properties.write_ptr,
+- q->process->mm);
++ retval = mqd->load_mqd(mqd, q->mqd, q->pipe,
++ q->queue, &q->properties,
++ q->process->mm);
+ dqm->queue_count++;
+ }
+ }
+@@ -826,7 +821,7 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
+ return retval;
+ }
+
+- retval = mqd->load_mqd(mqd, q->mqd, 0, 0, NULL, NULL);
++ retval = mqd->load_mqd(mqd, q->mqd, 0, 0, &q->properties, NULL);
+ if (retval != 0) {
+ deallocate_sdma_queue(dqm, q->sdma_id);
+ mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
+index f19f2b3..126d848 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
+@@ -144,7 +144,8 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
+ kq->queue->pipe = KFD_CIK_HIQ_PIPE;
+ kq->queue->queue = KFD_CIK_HIQ_QUEUE;
+ kq->mqd->load_mqd(kq->mqd, kq->queue->mqd, kq->queue->pipe,
+- kq->queue->queue, NULL, NULL);
++ kq->queue->queue, &kq->queue->properties,
++ NULL);
+ } else {
+ /* allocate fence for DIQ */
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
+index 4be3267..8972bcf 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
+@@ -67,7 +67,8 @@ struct mqd_manager {
+
+ int (*load_mqd)(struct mqd_manager *mm, void *mqd,
+ uint32_t pipe_id, uint32_t queue_id,
+- uint32_t __user *wptr, struct mm_struct *mms);
++ struct queue_properties *p,
++ struct mm_struct *mms);
+
+ int (*update_mqd)(struct mqd_manager *mm, void *mqd,
+ struct queue_properties *q);
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
+index 7528265..11e85d3 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
+@@ -207,18 +207,25 @@ static void uninit_mqd_sdma(struct mqd_manager *mm, void *mqd,
+ }
+
+ static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id,
+- uint32_t queue_id, uint32_t __user *wptr,
++ uint32_t queue_id, struct queue_properties *p,
+ struct mm_struct *mms)
+ {
+- return mm->dev->kfd2kgd->hqd_load
+- (mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
++ /* AQL write pointer counts in 64B packets, PM4/CP counts in dwords. */
++ uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0);
++ uint32_t wptr_mask = (uint32_t)((p->queue_size / sizeof(uint32_t)) - 1);
++
++ return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id,
++ (uint32_t __user *)p->write_ptr,
++ wptr_shift, wptr_mask, mms);
+ }
+
+ static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
+- uint32_t pipe_id, uint32_t queue_id,
+- uint32_t __user *wptr, struct mm_struct *mms)
++ uint32_t pipe_id, uint32_t queue_id,
++ struct queue_properties *p, struct mm_struct *mms)
+ {
+- return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd, wptr, mms);
++ return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd,
++ (uint32_t __user *)p->write_ptr,
++ mms);
+ }
+
+ static int __update_mqd(struct mqd_manager *mm, void *mqd,
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
+index b0ea0d2..0050821 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
+@@ -173,10 +173,15 @@ static int init_mqd(struct mqd_manager *mm, void **mqd,
+
+ static int load_mqd(struct mqd_manager *mm, void *mqd,
+ uint32_t pipe_id, uint32_t queue_id,
+- uint32_t __user *wptr, struct mm_struct *mms)
++ struct queue_properties *p, struct mm_struct *mms)
+ {
+- return mm->dev->kfd2kgd->hqd_load
+- (mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
++ /* AQL write pointer counts in 64B packets, PM4/CP counts in dwords. */
++ uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0);
++ uint32_t wptr_mask = (uint32_t)((p->queue_size / sizeof(uint32_t)) - 1);
++
++ return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id,
++ (uint32_t __user *)p->write_ptr,
++ wptr_shift, wptr_mask, mms);
+ }
+
+ static int __update_mqd(struct mqd_manager *mm, void *mqd,
+@@ -371,9 +376,11 @@ static void uninit_mqd_sdma(struct mqd_manager *mm, void *mqd,
+
+ static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
+ uint32_t pipe_id, uint32_t queue_id,
+- uint32_t __user *wptr, struct mm_struct *mms)
++ struct queue_properties *p, struct mm_struct *mms)
+ {
+- return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd, wptr, mms);
++ return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd,
++ (uint32_t __user *)p->write_ptr,
++ mms);
+ }
+
+ static int update_mqd_sdma(struct mqd_manager *mm, void *mqd,
+--
+2.7.4
+