[PATCH 53/83] hsa/radeon: Add device queue manager module

2014-07-10 Thread Oded Gabbay
From: Ben Goz 

The queue scheduler divides into two sections, one section is process bounded
and the other section is device bounded.
The device bounded section is handled by this module.
The DQM module handles queue setup, update and tear-down from the device side.
It also supports suspend/resume operation.

Signed-off-by: Ben Goz 
Signed-off-by: Oded Gabbay 
---
 drivers/gpu/hsa/radeon/Makefile   |2 +-
 drivers/gpu/hsa/radeon/kfd_device_queue_manager.c | 1006 +
 drivers/gpu/hsa/radeon/kfd_priv.h |2 +
 3 files changed, 1009 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/hsa/radeon/kfd_device_queue_manager.c

diff --git a/drivers/gpu/hsa/radeon/Makefile b/drivers/gpu/hsa/radeon/Makefile
index 341fa67..3409203 100644
--- a/drivers/gpu/hsa/radeon/Makefile
+++ b/drivers/gpu/hsa/radeon/Makefile
@@ -8,6 +8,6 @@ radeon_kfd-y:= kfd_module.o kfd_device.o kfd_chardev.o \
kfd_vidmem.o kfd_interrupt.o kfd_aperture.o \
kfd_queue.o kfd_hw_pointer_store.o kfd_mqd_manager.o \
kfd_kernel_queue.o kfd_packet_manager.o \
-   kfd_process_queue_manager.o
+   kfd_process_queue_manager.o kfd_device_queue_manager.o
 
 obj-$(CONFIG_HSA_RADEON)   += radeon_kfd.o
diff --git a/drivers/gpu/hsa/radeon/kfd_device_queue_manager.c 
b/drivers/gpu/hsa/radeon/kfd_device_queue_manager.c
new file mode 100644
index 000..9e21074
--- /dev/null
+++ b/drivers/gpu/hsa/radeon/kfd_device_queue_manager.c
@@ -0,0 +1,1006 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Ben Goz
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "kfd_priv.h"
+#include "kfd_device_queue_manager.h"
+#include "kfd_mqd_manager.h"
+#include "cik_regs.h"
+#include "kfd_kernel_queue.h"
+
+#define CIK_HPD_SIZE_LOG2 11
+#define CIK_HPD_SIZE (1U << CIK_HPD_SIZE_LOG2)
+
+static bool is_mem_initialized;
+
+static int init_memory(struct device_queue_manager *dqm);
+static int
+set_pasid_vmid_mapping(struct device_queue_manager *dqm, unsigned int pasid, 
unsigned int vmid);
+
+static inline unsigned int get_pipes_num(struct device_queue_manager *dqm)
+{
+   BUG_ON(!dqm || !dqm->dev);
+   return dqm->dev->shared_resources.compute_pipe_count;
+}
+
+static inline unsigned int get_first_pipe(struct device_queue_manager *dqm)
+{
+   BUG_ON(!dqm);
+   return dqm->dev->shared_resources.first_compute_pipe;
+}
+
+static inline unsigned int get_pipes_num_cpsch(void)
+{
+   return PIPE_PER_ME_CP_SCHEDULING - 1;
+}
+
+static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble);
+static void init_process_memory(struct device_queue_manager *dqm, struct 
qcm_process_device *qpd)
+{
+   BUG_ON(!dqm || !qpd);
+
+   qpd->sh_mem_config = ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED);
+   qpd->sh_mem_config |= DEFAULT_MTYPE(MTYPE_NONCACHED);
+   qpd->sh_mem_bases = compute_sh_mem_bases_64bit(6);
+   qpd->sh_mem_ape1_limit = 0;
+   qpd->sh_mem_ape1_base = 1;
+}
+
+static void program_sh_mem_settings(struct device_queue_manager *dqm, struct 
qcm_process_device *qpd)
+{
+   struct mqd_manager *mqd;
+
+   mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE);
+   if (mqd == NULL)
+   return;
+
+   mqd->acquire_hqd(mqd, 0, 0, qpd->vmid);
+
+   WRITE_REG(dqm->dev, SH_MEM_CONFIG, qpd->sh_mem_config);
+
+   WRITE_REG(dqm->dev, SH_MEM_APE1_BASE, qpd->sh_mem_ape1_base);
+   WRITE_REG(dqm->dev, SH_MEM_APE1_LIMIT, qpd->sh_mem_ape1_limit);
+
+   mqd->release_hqd(mqd);
+}
+
+static int create_queue_nocpsch(struct device_queue_manager *dqm, struct queue 
*q,
+   struct qcm_process_device *qpd, int *allocate_vmid)
+{
+   bool set, is_new_vmid;
+   int bit, retval, pipe;
+   struct mqd_manager *mqd;
+
+ 

[PATCH 53/83] hsa/radeon: Add device queue manager module

2014-07-10 Thread Oded Gabbay
From: Ben Goz ben@amd.com

The queue scheduler divides into two sections, one section is process bounded
and the other section is device bounded.
The device bounded section is handled by this module.
The DQM module handles queue setup, update and tear-down from the device side.
It also supports suspend/resume operation.

Signed-off-by: Ben Goz ben@amd.com
Signed-off-by: Oded Gabbay oded.gab...@amd.com
---
 drivers/gpu/hsa/radeon/Makefile   |2 +-
 drivers/gpu/hsa/radeon/kfd_device_queue_manager.c | 1006 +
 drivers/gpu/hsa/radeon/kfd_priv.h |2 +
 3 files changed, 1009 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/hsa/radeon/kfd_device_queue_manager.c

diff --git a/drivers/gpu/hsa/radeon/Makefile b/drivers/gpu/hsa/radeon/Makefile
index 341fa67..3409203 100644
--- a/drivers/gpu/hsa/radeon/Makefile
+++ b/drivers/gpu/hsa/radeon/Makefile
@@ -8,6 +8,6 @@ radeon_kfd-y:= kfd_module.o kfd_device.o kfd_chardev.o \
kfd_vidmem.o kfd_interrupt.o kfd_aperture.o \
kfd_queue.o kfd_hw_pointer_store.o kfd_mqd_manager.o \
kfd_kernel_queue.o kfd_packet_manager.o \
-   kfd_process_queue_manager.o
+   kfd_process_queue_manager.o kfd_device_queue_manager.o
 
 obj-$(CONFIG_HSA_RADEON)   += radeon_kfd.o
diff --git a/drivers/gpu/hsa/radeon/kfd_device_queue_manager.c 
b/drivers/gpu/hsa/radeon/kfd_device_queue_manager.c
new file mode 100644
index 000..9e21074
--- /dev/null
+++ b/drivers/gpu/hsa/radeon/kfd_device_queue_manager.c
@@ -0,0 +1,1006 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the Software),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Ben Goz
+ */
+
+#include linux/slab.h
+#include linux/list.h
+#include linux/types.h
+#include linux/printk.h
+#include linux/bitops.h
+#include kfd_priv.h
+#include kfd_device_queue_manager.h
+#include kfd_mqd_manager.h
+#include cik_regs.h
+#include kfd_kernel_queue.h
+
+#define CIK_HPD_SIZE_LOG2 11
+#define CIK_HPD_SIZE (1U  CIK_HPD_SIZE_LOG2)
+
+static bool is_mem_initialized;
+
+static int init_memory(struct device_queue_manager *dqm);
+static int
+set_pasid_vmid_mapping(struct device_queue_manager *dqm, unsigned int pasid, 
unsigned int vmid);
+
+static inline unsigned int get_pipes_num(struct device_queue_manager *dqm)
+{
+   BUG_ON(!dqm || !dqm-dev);
+   return dqm-dev-shared_resources.compute_pipe_count;
+}
+
+static inline unsigned int get_first_pipe(struct device_queue_manager *dqm)
+{
+   BUG_ON(!dqm);
+   return dqm-dev-shared_resources.first_compute_pipe;
+}
+
+static inline unsigned int get_pipes_num_cpsch(void)
+{
+   return PIPE_PER_ME_CP_SCHEDULING - 1;
+}
+
+static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble);
+static void init_process_memory(struct device_queue_manager *dqm, struct 
qcm_process_device *qpd)
+{
+   BUG_ON(!dqm || !qpd);
+
+   qpd-sh_mem_config = ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED);
+   qpd-sh_mem_config |= DEFAULT_MTYPE(MTYPE_NONCACHED);
+   qpd-sh_mem_bases = compute_sh_mem_bases_64bit(6);
+   qpd-sh_mem_ape1_limit = 0;
+   qpd-sh_mem_ape1_base = 1;
+}
+
+static void program_sh_mem_settings(struct device_queue_manager *dqm, struct 
qcm_process_device *qpd)
+{
+   struct mqd_manager *mqd;
+
+   mqd = dqm-get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE);
+   if (mqd == NULL)
+   return;
+
+   mqd-acquire_hqd(mqd, 0, 0, qpd-vmid);
+
+   WRITE_REG(dqm-dev, SH_MEM_CONFIG, qpd-sh_mem_config);
+
+   WRITE_REG(dqm-dev, SH_MEM_APE1_BASE, qpd-sh_mem_ape1_base);
+   WRITE_REG(dqm-dev, SH_MEM_APE1_LIMIT, qpd-sh_mem_ape1_limit);
+
+   mqd-release_hqd(mqd);
+}
+
+static int create_queue_nocpsch(struct device_queue_manager *dqm, struct queue 
*q,
+   struct qcm_process_device *qpd, int *allocate_vmid)
+{
+   bool set,