OSDN Git Service

drm/amdkfd: Fix bugs regarding CP queue doorbell mask on SOC15
authorYong Zhao <Yong.Zhao@amd.com>
Wed, 13 Feb 2019 18:15:05 +0000 (13:15 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 18 Feb 2019 23:00:41 +0000 (18:00 -0500)
Reserved doorbells for SDMA IH and VCN were not properly masked out
when allocating doorbells for CP user queues. This patch fixed that.

Signed-off-by: Yong Zhao <Yong.Zhao@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
drivers/gpu/drm/amd/amdkfd/kfd_process.c
drivers/gpu/drm/amd/include/kgd_kfd_interface.h

index e957e42..30e2b37 100644 (file)
@@ -196,11 +196,19 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
                        gpu_resources.sdma_doorbell[1][i+1] =
                                adev->doorbell_index.sdma_engine[1] + 0x200 + (i >> 1);
                }
-               /* Doorbells 0x0e0-0ff and 0x2e0-2ff are reserved for
-                * SDMA, IH and VCN. So don't use them for the CP.
+
+               /* Since SOC15, BIF starts to statically use the
+                * lower 12 bits of doorbell addresses for routing
+                * based on settings in registers like
+                * SDMA0_DOORBELL_RANGE etc..
+                * In order to route a doorbell to CP engine, the lower
+                * 12 bits of its address has to be outside the range
+                * set for SDMA, VCN, and IH blocks.
                 */
-               gpu_resources.reserved_doorbell_mask = 0x1e0;
-               gpu_resources.reserved_doorbell_val  = 0x0e0;
+               gpu_resources.non_cp_doorbells_start =
+                               adev->doorbell_index.first_non_cp;
+               gpu_resources.non_cp_doorbells_end =
+                               adev->doorbell_index.last_non_cp;
 
                kgd2kfd_device_init(adev->kfd.dev, &gpu_resources);
        }
index e5ebcca..0eeee3c 100644 (file)
 #define KFD_KERNEL_QUEUE_SIZE 2048
 
 /*
+ * 512 = 0x200
+ * The doorbell index distance between SDMA RLC (2*i) and (2*i+1) in the
+ * same SDMA engine on SOC15, which has 8-byte doorbells for SDMA.
+ * 512 8-byte doorbell distance (i.e. one page away) ensures that SDMA RLC
+ * (2*i+1) doorbells (in terms of the lower 12 bit address) lie exactly in
+ * the OFFSET and SIZE set in registers like BIF_SDMA0_DOORBELL_RANGE.
+ */
+#define KFD_QUEUE_DOORBELL_MIRROR_OFFSET 512
+
+
+/*
  * Kernel module parameter to specify maximum number of supported queues per
  * device
  */
index 80b36e8..4bdae78 100644 (file)
@@ -607,13 +607,17 @@ static int init_doorbell_bitmap(struct qcm_process_device *qpd,
        if (!qpd->doorbell_bitmap)
                return -ENOMEM;
 
-       /* Mask out any reserved doorbells */
-       for (i = 0; i < KFD_MAX_NUM_OF_QUEUES_PER_PROCESS; i++)
-               if ((dev->shared_resources.reserved_doorbell_mask & i) ==
-                   dev->shared_resources.reserved_doorbell_val) {
+       /* Mask out doorbells reserved for SDMA, IH, and VCN on SOC15. */
+       for (i = 0; i < KFD_MAX_NUM_OF_QUEUES_PER_PROCESS / 2; i++) {
+               if (i >= dev->shared_resources.non_cp_doorbells_start
+                       && i <= dev->shared_resources.non_cp_doorbells_end) {
                        set_bit(i, qpd->doorbell_bitmap);
-                       pr_debug("reserved doorbell 0x%03x\n", i);
+                       set_bit(i + KFD_QUEUE_DOORBELL_MIRROR_OFFSET,
+                               qpd->doorbell_bitmap);
+                       pr_debug("reserved doorbell 0x%03x and 0x%03x\n", i,
+                               i + KFD_QUEUE_DOORBELL_MIRROR_OFFSET);
                }
+       }
 
        return 0;
 }
index 83d9601..0b6b34f 100644 (file)
@@ -140,17 +140,14 @@ struct kgd2kfd_shared_resources {
        /* Doorbell assignments (SOC15 and later chips only). Only
         * specific doorbells are routed to each SDMA engine. Others
         * are routed to IH and VCN. They are not usable by the CP.
-        *
-        * Any doorbell number D that satisfies the following condition
-        * is reserved: (D & reserved_doorbell_mask) == reserved_doorbell_val
-        *
-        * KFD currently uses 1024 (= 0x3ff) doorbells per process. If
-        * doorbells 0x0e0-0x0ff and 0x2e0-0x2ff are reserved, that means
-        * mask would be set to 0x1e0 and val set to 0x0e0.
         */
        unsigned int sdma_doorbell[2][8];
-       unsigned int reserved_doorbell_mask;
-       unsigned int reserved_doorbell_val;
+
+       /* From SOC15 onward, the doorbell index range not usable for CP
+        * queues.
+        */
+       uint32_t non_cp_doorbells_start;
+       uint32_t non_cp_doorbells_end;
 
        /* Base address of doorbell aperture. */
        phys_addr_t doorbell_physical_address;