aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0314-drm-amdkfd-add-support-for-VI-in-MQD-manager.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0314-drm-amdkfd-add-support-for-VI-in-MQD-manager.patch')
-rw-r--r--common/recipes-kernel/linux/files/0314-drm-amdkfd-add-support-for-VI-in-MQD-manager.patch296
1 files changed, 296 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0314-drm-amdkfd-add-support-for-VI-in-MQD-manager.patch b/common/recipes-kernel/linux/files/0314-drm-amdkfd-add-support-for-VI-in-MQD-manager.patch
new file mode 100644
index 00000000..209dec27
--- /dev/null
+++ b/common/recipes-kernel/linux/files/0314-drm-amdkfd-add-support-for-VI-in-MQD-manager.patch
@@ -0,0 +1,296 @@
+From d696d536f0a97ac779d6176107ac4e96d0a2f8b9 Mon Sep 17 00:00:00 2001
+From: Ben Goz <ben.goz@amd.com>
+Date: Mon, 12 Jan 2015 14:26:10 +0200
+Subject: [PATCH 0314/1050] drm/amdkfd: add support for VI in MQD manager
+
+This patch implements all the VI MQD manager functions.
+This is done in a different file as the MQD format is different
+between CI and VI
+
+Signed-off-by: Ben Goz <ben.goz@amd.com>
+Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
+---
+ drivers/gpu/drm/amd/amdkfd/Makefile | 3 +-
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c | 249 +++++++++++++++++++++++-
+ 2 files changed, 248 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile
+index 2855115..7fc9b0f 100644
+--- a/drivers/gpu/drm/amd/amdkfd/Makefile
++++ b/drivers/gpu/drm/amd/amdkfd/Makefile
+@@ -2,7 +2,8 @@
+ # Makefile for Heterogenous System Architecture support for AMD GPU devices
+ #
+
+-ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/
++ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/ \
++ -Idrivers/gpu/drm/amd/include/asic_reg
+
+ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \
+ kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \
+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 b3a7e3b..fa32c32 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
+@@ -22,12 +22,255 @@
+ */
+
+ #include <linux/printk.h>
++#include <linux/slab.h>
+ #include "kfd_priv.h"
+ #include "kfd_mqd_manager.h"
++#include "vi_structs.h"
++#include "gca/gfx_8_0_sh_mask.h"
++#include "gca/gfx_8_0_enum.h"
++
++#define CP_MQD_CONTROL__PRIV_STATE__SHIFT 0x8
++
++static inline struct vi_mqd *get_mqd(void *mqd)
++{
++ return (struct vi_mqd *)mqd;
++}
++
++static int init_mqd(struct mqd_manager *mm, void **mqd,
++ struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
++ struct queue_properties *q)
++{
++ int retval;
++ uint64_t addr;
++ struct vi_mqd *m;
++
++ retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct vi_mqd),
++ mqd_mem_obj);
++ if (retval != 0)
++ return -ENOMEM;
++
++ m = (struct vi_mqd *) (*mqd_mem_obj)->cpu_ptr;
++ addr = (*mqd_mem_obj)->gpu_addr;
++
++ memset(m, 0, sizeof(struct vi_mqd));
++
++ m->header = 0xC0310800;
++ m->compute_pipelinestat_enable = 1;
++ m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF;
++ m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF;
++ m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF;
++ m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF;
++
++ m->cp_hqd_persistent_state = CP_HQD_PERSISTENT_STATE__PRELOAD_REQ_MASK |
++ 0x53 << CP_HQD_PERSISTENT_STATE__PRELOAD_SIZE__SHIFT;
++
++ m->cp_mqd_control = 1 << CP_MQD_CONTROL__PRIV_STATE__SHIFT |
++ MTYPE_UC << CP_MQD_CONTROL__MTYPE__SHIFT;
++
++ m->cp_mqd_base_addr_lo = lower_32_bits(addr);
++ m->cp_mqd_base_addr_hi = upper_32_bits(addr);
++
++ m->cp_hqd_quantum = 1 << CP_HQD_QUANTUM__QUANTUM_EN__SHIFT |
++ 1 << CP_HQD_QUANTUM__QUANTUM_SCALE__SHIFT |
++ 10 << CP_HQD_QUANTUM__QUANTUM_DURATION__SHIFT;
++
++ m->cp_hqd_pipe_priority = 1;
++ m->cp_hqd_queue_priority = 15;
++
++ m->cp_hqd_eop_rptr = 1 << CP_HQD_EOP_RPTR__INIT_FETCHER__SHIFT;
++
++ if (q->format == KFD_QUEUE_FORMAT_AQL)
++ m->cp_hqd_iq_rptr = 1;
++
++ *mqd = m;
++ if (gart_addr != NULL)
++ *gart_addr = addr;
++ retval = mm->update_mqd(mm, m, q);
++
++ return retval;
++}
++
++static int load_mqd(struct mqd_manager *mm, void *mqd,
++ uint32_t pipe_id, uint32_t queue_id,
++ uint32_t __user *wptr)
++{
++ return mm->dev->kfd2kgd->hqd_load
++ (mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
++}
++
++static int __update_mqd(struct mqd_manager *mm, void *mqd,
++ struct queue_properties *q, unsigned int mtype,
++ unsigned int atc_bit)
++{
++ struct vi_mqd *m;
++
++ BUG_ON(!mm || !q || !mqd);
++
++ pr_debug("kfd: In func %s\n", __func__);
++
++ m = get_mqd(mqd);
++
++ m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT |
++ atc_bit << CP_HQD_PQ_CONTROL__PQ_ATC__SHIFT |
++ mtype << CP_HQD_PQ_CONTROL__MTYPE__SHIFT;
++ m->cp_hqd_pq_control |=
++ ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1;
++ pr_debug("kfd: cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control);
++
++ m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
++ m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
++
++ m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
++ m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
++
++ m->cp_hqd_pq_doorbell_control =
++ 1 << CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN__SHIFT |
++ q->doorbell_off <<
++ CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
++ pr_debug("kfd: cp_hqd_pq_doorbell_control 0x%x\n",
++ m->cp_hqd_pq_doorbell_control);
++
++ m->cp_hqd_eop_control = atc_bit << CP_HQD_EOP_CONTROL__EOP_ATC__SHIFT |
++ mtype << CP_HQD_EOP_CONTROL__MTYPE__SHIFT;
++
++ m->cp_hqd_ib_control = atc_bit << CP_HQD_IB_CONTROL__IB_ATC__SHIFT |
++ 3 << CP_HQD_IB_CONTROL__MIN_IB_AVAIL_SIZE__SHIFT |
++ mtype << CP_HQD_IB_CONTROL__MTYPE__SHIFT;
++
++ m->cp_hqd_eop_control |=
++ ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1;
++ m->cp_hqd_eop_base_addr_lo =
++ lower_32_bits(q->eop_ring_buffer_address >> 8);
++ m->cp_hqd_eop_base_addr_hi =
++ upper_32_bits(q->eop_ring_buffer_address >> 8);
++
++ m->cp_hqd_iq_timer = atc_bit << CP_HQD_IQ_TIMER__IQ_ATC__SHIFT |
++ mtype << CP_HQD_IQ_TIMER__MTYPE__SHIFT;
++
++ m->cp_hqd_vmid = q->vmid;
++
++ if (q->format == KFD_QUEUE_FORMAT_AQL) {
++ m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__NO_UPDATE_RPTR_MASK |
++ 2 << CP_HQD_PQ_CONTROL__SLOT_BASED_WPTR__SHIFT;
++ }
++
++ m->cp_hqd_active = 0;
++ q->is_active = false;
++ if (q->queue_size > 0 &&
++ q->queue_address != 0 &&
++ q->queue_percent > 0) {
++ m->cp_hqd_active = 1;
++ q->is_active = true;
++ }
++
++ return 0;
++}
++
++
++static int update_mqd(struct mqd_manager *mm, void *mqd,
++ struct queue_properties *q)
++{
++ return __update_mqd(mm, mqd, q, MTYPE_CC, 1);
++}
++
++static int destroy_mqd(struct mqd_manager *mm, void *mqd,
++ enum kfd_preempt_type type,
++ unsigned int timeout, uint32_t pipe_id,
++ uint32_t queue_id)
++{
++ return mm->dev->kfd2kgd->hqd_destroy
++ (mm->dev->kgd, type, timeout,
++ pipe_id, queue_id);
++}
++
++static void uninit_mqd(struct mqd_manager *mm, void *mqd,
++ struct kfd_mem_obj *mqd_mem_obj)
++{
++ BUG_ON(!mm || !mqd);
++ kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
++}
++
++static bool is_occupied(struct mqd_manager *mm, void *mqd,
++ uint64_t queue_address, uint32_t pipe_id,
++ uint32_t queue_id)
++{
++ return mm->dev->kfd2kgd->hqd_is_occupied(
++ mm->dev->kgd, queue_address,
++ pipe_id, queue_id);
++}
++
++static int init_mqd_hiq(struct mqd_manager *mm, void **mqd,
++ struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
++ struct queue_properties *q)
++{
++ struct vi_mqd *m;
++ int retval = init_mqd(mm, mqd, mqd_mem_obj, gart_addr, q);
++
++ if (retval != 0)
++ return retval;
++
++ m = get_mqd(*mqd);
++
++ m->cp_hqd_pq_control |= 1 << CP_HQD_PQ_CONTROL__PRIV_STATE__SHIFT |
++ 1 << CP_HQD_PQ_CONTROL__KMD_QUEUE__SHIFT;
++
++ return retval;
++}
++
++static int update_mqd_hiq(struct mqd_manager *mm, void *mqd,
++ struct queue_properties *q)
++{
++ struct vi_mqd *m;
++ int retval = __update_mqd(mm, mqd, q, MTYPE_UC, 0);
++
++ if (retval != 0)
++ return retval;
++
++ m = get_mqd(mqd);
++ m->cp_hqd_vmid = q->vmid;
++ return retval;
++}
+
+ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
+- struct kfd_dev *dev)
++ struct kfd_dev *dev)
+ {
+- pr_warn("amdkfd: VI MQD is not currently supported\n");
+- return NULL;
++ struct mqd_manager *mqd;
++
++ BUG_ON(!dev);
++ BUG_ON(type >= KFD_MQD_TYPE_MAX);
++
++ pr_debug("kfd: In func %s\n", __func__);
++
++ mqd = kzalloc(sizeof(struct mqd_manager), GFP_KERNEL);
++ if (!mqd)
++ return NULL;
++
++ mqd->dev = dev;
++
++ switch (type) {
++ case KFD_MQD_TYPE_CP:
++ case KFD_MQD_TYPE_COMPUTE:
++ mqd->init_mqd = init_mqd;
++ mqd->uninit_mqd = uninit_mqd;
++ mqd->load_mqd = load_mqd;
++ mqd->update_mqd = update_mqd;
++ mqd->destroy_mqd = destroy_mqd;
++ mqd->is_occupied = is_occupied;
++ break;
++ case KFD_MQD_TYPE_HIQ:
++ mqd->init_mqd = init_mqd_hiq;
++ mqd->uninit_mqd = uninit_mqd;
++ mqd->load_mqd = load_mqd;
++ mqd->update_mqd = update_mqd_hiq;
++ mqd->destroy_mqd = destroy_mqd;
++ mqd->is_occupied = is_occupied;
++ break;
++ case KFD_MQD_TYPE_SDMA:
++ break;
++ default:
++ kfree(mqd);
++ return NULL;
++ }
++
++ return mqd;
+ }
+--
+1.9.1
+