Add new fields to the amdgpu_mqd_prop structure to track CU (Compute Unit)
mask information, including the mask itself, count, flags, and a flag to
indicate if user-specified CU masking is active.

v2: Create a generic function amdgpu_gfx_mqd_symmetrically_map_cu_mask()

Suggested-by: Alex Deucher <[email protected]>
Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h     | 10 +++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 49 +++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h |  2 +
 3 files changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 11a36c132905..a8f4f73fa0ce 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -789,6 +789,12 @@ struct amd_powerplay {
                                          (rid == 0x01) || \
                                          (rid == 0x10))))
 
+enum amdgpu_mqd_update_flag {
+       AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE = 1,
+       AMDGPU_UPDATE_FLAG_DBG_WA_DISABLE = 2,
+       AMDGPU_UPDATE_FLAG_IS_GWS = 4, /* quirk for gfx9 IP */
+};
+
 struct amdgpu_mqd_prop {
        uint64_t mqd_gpu_addr;
        uint64_t hqd_base_gpu_addr;
@@ -809,6 +815,10 @@ struct amdgpu_mqd_prop {
        uint64_t fence_address;
        bool tmz_queue;
        bool kernel_queue;
+       uint32_t *cu_mask;
+       uint32_t cu_mask_count;
+       uint32_t cu_flags;
+       bool is_user_cu_masked;
 };
 
 struct amdgpu_mqd {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index 6abe5103a78d..73e6988cb703 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -501,6 +501,55 @@ void amdgpu_gfx_mqd_sw_fini(struct amdgpu_device *adev, 
int xcc_id)
                              &ring->mqd_ptr);
 }
 
+void amdgpu_gfx_mqd_symmetrically_map_cu_mask(struct amdgpu_device *adev, 
const uint32_t *cu_mask,
+                                             uint32_t cu_mask_count, uint32_t 
*se_mask)
+{
+       struct amdgpu_cu_info *cu_info = &adev->gfx.cu_info;
+       struct amdgpu_gfx_config *gfx_info = &adev->gfx.config;
+       uint32_t cu_per_sh[8][4] = {0};
+       int i, se, sh, cu, cu_bitmap_sh_mul;
+       int xcc_inst = ffs(adev->gfx.xcc_mask) - 1;
+       bool wgp_mode_req = amdgpu_ip_version(adev, GC_HWIP, 0) >= 
IP_VERSION(10, 0, 0);
+       int cu_inc = wgp_mode_req ? 2 : 1;
+       uint32_t en_mask = wgp_mode_req ? 0x3 : 0x1;
+       int num_xcc, inc, inst = 0;
+
+       if (xcc_inst < 0)
+               xcc_inst = 0;
+
+       num_xcc = hweight16(adev->gfx.xcc_mask);
+       if (!num_xcc)
+               num_xcc = 1;
+
+       inc = cu_inc * num_xcc;
+
+       cu_bitmap_sh_mul = 2;
+
+       for (se = 0; se < gfx_info->max_shader_engines; se++)
+               for (sh = 0; sh < gfx_info->max_sh_per_se; sh++)
+                       cu_per_sh[se][sh] = hweight32(
+                               cu_info->bitmap[xcc_inst][se % 4][sh + (se / 4) 
*
+                               cu_bitmap_sh_mul]);
+
+       for (i = 0; i < gfx_info->max_shader_engines; i++)
+               se_mask[i] = 0;
+
+       i = inst;
+       for (cu = 0; cu < 16; cu += cu_inc) {
+               for (sh = 0; sh < gfx_info->max_sh_per_se; sh++) {
+                       for (se = 0; se < gfx_info->max_shader_engines; se++) {
+                               if (cu_per_sh[se][sh] > cu) {
+                                       if ((i / 32) < cu_mask_count && 
(cu_mask[i / 32] & (1 << (i % 32))))
+                                               se_mask[se] |= en_mask << (cu + 
sh * 16);
+                                       i += inc;
+                                       if (i >= cu_mask_count * 32)
+                                               return;
+                               }
+                       }
+               }
+       }
+}
+
 int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev, int xcc_id)
 {
        struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
index 585cc8e81bb2..720ed3a2c78c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
@@ -583,6 +583,8 @@ int amdgpu_gfx_kiq_init(struct amdgpu_device *adev,
 int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev,
                           unsigned mqd_size, int xcc_id);
 void amdgpu_gfx_mqd_sw_fini(struct amdgpu_device *adev, int xcc_id);
+void amdgpu_gfx_mqd_symmetrically_map_cu_mask(struct amdgpu_device *adev, 
const uint32_t *cu_mask,
+                                             uint32_t cu_mask_count, uint32_t 
*se_mask);
 int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev, int xcc_id);
 int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev, int xcc_id);
 int amdgpu_gfx_disable_kgq(struct amdgpu_device *adev, int xcc_id);
-- 
2.49.0

Reply via email to