drm/amdgpu: Add support for SRBM selection v3
authorAndrey Grodzovsky <andrey.grodzovsky@amd.com>
Thu, 29 Mar 2018 13:09:39 +0000 (09:09 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 3 Apr 2018 18:08:44 +0000 (13:08 -0500)
Also remove code duplication in write and read regs functions.
This also fixes potential missing unlock in amdgpu_debugfs_regs_write
in case get_user would fail.

v2: Add SRBM mutex locking.
v3: Fix TO counter and fix comment location.

Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c

index f44a83ab2bf49ab948f3e54059b7331cf08489e1..0193f6ced00be025372e5a5e27c9b8ec1425b42f 100644 (file)
@@ -890,6 +890,7 @@ struct amdgpu_gfx_funcs {
        void (*read_wave_data)(struct amdgpu_device *adev, uint32_t simd, uint32_t wave, uint32_t *dst, int *no_fields);
        void (*read_wave_vgprs)(struct amdgpu_device *adev, uint32_t simd, uint32_t wave, uint32_t thread, uint32_t start, uint32_t size, uint32_t *dst);
        void (*read_wave_sgprs)(struct amdgpu_device *adev, uint32_t simd, uint32_t wave, uint32_t start, uint32_t size, uint32_t *dst);
+       void (*select_me_pipe_q)(struct amdgpu_device *adev, u32 me, u32 pipe, u32 queue);
 };
 
 struct amdgpu_ngg_buf {
@@ -1812,6 +1813,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
 #define amdgpu_gfx_select_se_sh(adev, se, sh, instance) (adev)->gfx.funcs->select_se_sh((adev), (se), (sh), (instance))
 #define amdgpu_gds_switch(adev, r, v, d, w, a) (adev)->gds.funcs->patch_gds_switch((r), (v), (d), (w), (a))
 #define amdgpu_psp_check_fw_loading_status(adev, i) (adev)->firmware.funcs->check_fw_loading_status((adev), (i))
+#define amdgpu_gfx_select_me_pipe_q(adev, me, pipe, q) (adev)->gfx.funcs->select_me_pipe_q((adev), (me), (pipe), (q))
 
 /* Common functions */
 int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
index 369beb5041a2fc0450b2344b2c576f721783f9a1..448d69fe375612547c249a923344472b1e0cd114 100644 (file)
@@ -64,16 +64,21 @@ int amdgpu_debugfs_add_files(struct amdgpu_device *adev,
 
 #if defined(CONFIG_DEBUG_FS)
 
-static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
-                                       size_t size, loff_t *pos)
+
+static int  amdgpu_debugfs_process_reg_op(bool read, struct file *f,
+               char __user *buf, size_t size, loff_t *pos)
 {
        struct amdgpu_device *adev = file_inode(f)->i_private;
        ssize_t result = 0;
        int r;
-       bool pm_pg_lock, use_bank;
-       unsigned instance_bank, sh_bank, se_bank;
+       bool pm_pg_lock, use_bank, use_ring;
+       unsigned instance_bank, sh_bank, se_bank, me, pipe, queue;
 
-       if (size & 0x3 || *pos & 0x3)
+       pm_pg_lock = use_bank = use_ring = false;
+       instance_bank = sh_bank = se_bank = me = pipe = queue = 0;
+
+       if (size & 0x3 || *pos & 0x3 ||
+                       ((*pos & (1ULL << 62)) && (*pos & (1ULL << 61))))
                return -EINVAL;
 
        /* are we reading registers for which a PG lock is necessary? */
@@ -91,8 +96,15 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
                if (instance_bank == 0x3FF)
                        instance_bank = 0xFFFFFFFF;
                use_bank = 1;
+       } else if (*pos & (1ULL << 61)) {
+
+               me = (*pos & GENMASK_ULL(33, 24)) >> 24;
+               pipe = (*pos & GENMASK_ULL(43, 34)) >> 34;
+               queue = (*pos & GENMASK_ULL(53, 44)) >> 44;
+
+               use_ring = 1;
        } else {
-               use_bank = 0;
+               use_bank = use_ring = 0;
        }
 
        *pos &= (1UL << 22) - 1;
@@ -104,6 +116,9 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
                mutex_lock(&adev->grbm_idx_mutex);
                amdgpu_gfx_select_se_sh(adev, se_bank,
                                        sh_bank, instance_bank);
+       } else if (use_ring) {
+               mutex_lock(&adev->srbm_mutex);
+               amdgpu_gfx_select_me_pipe_q(adev, me, pipe, queue);
        }
 
        if (pm_pg_lock)
@@ -115,8 +130,14 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
                if (*pos > adev->rmmio_size)
                        goto end;
 
-               value = RREG32(*pos >> 2);
-               r = put_user(value, (uint32_t *)buf);
+               if (read) {
+                       value = RREG32(*pos >> 2);
+                       r = put_user(value, (uint32_t *)buf);
+               } else {
+                       r = get_user(value, (uint32_t *)buf);
+                       if (!r)
+                               WREG32(*pos >> 2, value);
+               }
                if (r) {
                        result = r;
                        goto end;
@@ -132,6 +153,9 @@ end:
        if (use_bank) {
                amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
                mutex_unlock(&adev->grbm_idx_mutex);
+       } else if (use_ring) {
+               amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0);
+               mutex_unlock(&adev->srbm_mutex);
        }
 
        if (pm_pg_lock)
@@ -140,78 +164,17 @@ end:
        return result;
 }
 
+
+static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
+                                       size_t size, loff_t *pos)
+{
+       return amdgpu_debugfs_process_reg_op(true, f, buf, size, pos);
+}
+
 static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
                                         size_t size, loff_t *pos)
 {
-       struct amdgpu_device *adev = file_inode(f)->i_private;
-       ssize_t result = 0;
-       int r;
-       bool pm_pg_lock, use_bank;
-       unsigned instance_bank, sh_bank, se_bank;
-
-       if (size & 0x3 || *pos & 0x3)
-               return -EINVAL;
-
-       /* are we reading registers for which a PG lock is necessary? */
-       pm_pg_lock = (*pos >> 23) & 1;
-
-       if (*pos & (1ULL << 62)) {
-               se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24;
-               sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34;
-               instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44;
-
-               if (se_bank == 0x3FF)
-                       se_bank = 0xFFFFFFFF;
-               if (sh_bank == 0x3FF)
-                       sh_bank = 0xFFFFFFFF;
-               if (instance_bank == 0x3FF)
-                       instance_bank = 0xFFFFFFFF;
-               use_bank = 1;
-       } else {
-               use_bank = 0;
-       }
-
-       *pos &= (1UL << 22) - 1;
-
-       if (use_bank) {
-               if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
-                   (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines))
-                       return -EINVAL;
-               mutex_lock(&adev->grbm_idx_mutex);
-               amdgpu_gfx_select_se_sh(adev, se_bank,
-                                       sh_bank, instance_bank);
-       }
-
-       if (pm_pg_lock)
-               mutex_lock(&adev->pm.mutex);
-
-       while (size) {
-               uint32_t value;
-
-               if (*pos > adev->rmmio_size)
-                       return result;
-
-               r = get_user(value, (uint32_t *)buf);
-               if (r)
-                       return r;
-
-               WREG32(*pos >> 2, value);
-
-               result += 4;
-               buf += 4;
-               *pos += 4;
-               size -= 4;
-       }
-
-       if (use_bank) {
-               amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
-               mutex_unlock(&adev->grbm_idx_mutex);
-       }
-
-       if (pm_pg_lock)
-               mutex_unlock(&adev->pm.mutex);
-
-       return result;
+       return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos);
 }
 
 static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
index 0fff5b8cd318a6f46b9a59b9f07c0d38b482b8fa..cd6bf291a853d9d0226a16c05485fc684237a82f 100644 (file)
@@ -3061,11 +3061,18 @@ static void gfx_v6_0_read_wave_sgprs(struct amdgpu_device *adev, uint32_t simd,
                start + SQIND_WAVE_SGPRS_OFFSET, size, dst);
 }
 
+static void gfx_v6_0_select_me_pipe_q(struct amdgpu_device *adev,
+                                 u32 me, u32 pipe, u32 q)
+{
+       DRM_INFO("Not implemented\n");
+}
+
 static const struct amdgpu_gfx_funcs gfx_v6_0_gfx_funcs = {
        .get_gpu_clock_counter = &gfx_v6_0_get_gpu_clock_counter,
        .select_se_sh = &gfx_v6_0_select_se_sh,
        .read_wave_data = &gfx_v6_0_read_wave_data,
        .read_wave_sgprs = &gfx_v6_0_read_wave_sgprs,
+       .select_me_pipe_q = &gfx_v6_0_select_me_pipe_q
 };
 
 static int gfx_v6_0_early_init(void *handle)
index e13d9d83767b1344a2e79f12427c9957a5a94e53..42b6144c1fd59c3e10724c4806c7eff04ce8eca9 100644 (file)
@@ -4270,11 +4270,18 @@ static void gfx_v7_0_read_wave_sgprs(struct amdgpu_device *adev, uint32_t simd,
                start + SQIND_WAVE_SGPRS_OFFSET, size, dst);
 }
 
+static void gfx_v7_0_select_me_pipe_q(struct amdgpu_device *adev,
+                                 u32 me, u32 pipe, u32 q)
+{
+       cik_srbm_select(adev, me, pipe, q, 0);
+}
+
 static const struct amdgpu_gfx_funcs gfx_v7_0_gfx_funcs = {
        .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter,
        .select_se_sh = &gfx_v7_0_select_se_sh,
        .read_wave_data = &gfx_v7_0_read_wave_data,
        .read_wave_sgprs = &gfx_v7_0_read_wave_sgprs,
+       .select_me_pipe_q = &gfx_v7_0_select_me_pipe_q
 };
 
 static const struct amdgpu_rlc_funcs gfx_v7_0_rlc_funcs = {
index 27943e57681c5b8ffac85e21d86e456b2dd3c6d1..b0e591eaa71a21754e1e2246bf41df3cdd1936cf 100644 (file)
@@ -3475,6 +3475,12 @@ static void gfx_v8_0_select_se_sh(struct amdgpu_device *adev,
        WREG32(mmGRBM_GFX_INDEX, data);
 }
 
+static void gfx_v8_0_select_me_pipe_q(struct amdgpu_device *adev,
+                                 u32 me, u32 pipe, u32 q)
+{
+       vi_srbm_select(adev, me, pipe, q, 0);
+}
+
 static u32 gfx_v8_0_get_rb_active_bitmap(struct amdgpu_device *adev)
 {
        u32 data, mask;
@@ -5442,6 +5448,7 @@ static const struct amdgpu_gfx_funcs gfx_v8_0_gfx_funcs = {
        .select_se_sh = &gfx_v8_0_select_se_sh,
        .read_wave_data = &gfx_v8_0_read_wave_data,
        .read_wave_sgprs = &gfx_v8_0_read_wave_sgprs,
+       .select_me_pipe_q = &gfx_v8_0_select_me_pipe_q
 };
 
 static int gfx_v8_0_early_init(void *handle)
index ae90c95e36af08c81702d35c3ededf073bbbdb60..9d39fd5b1822da052ee199c4408e3b46292df414 100644 (file)
@@ -998,12 +998,19 @@ static void gfx_v9_0_read_wave_vgprs(struct amdgpu_device *adev, uint32_t simd,
                start + SQIND_WAVE_VGPRS_OFFSET, size, dst);
 }
 
+static void gfx_v9_0_select_me_pipe_q(struct amdgpu_device *adev,
+                                 u32 me, u32 pipe, u32 q)
+{
+       soc15_grbm_select(adev, me, pipe, q, 0);
+}
+
 static const struct amdgpu_gfx_funcs gfx_v9_0_gfx_funcs = {
        .get_gpu_clock_counter = &gfx_v9_0_get_gpu_clock_counter,
        .select_se_sh = &gfx_v9_0_select_se_sh,
        .read_wave_data = &gfx_v9_0_read_wave_data,
        .read_wave_sgprs = &gfx_v9_0_read_wave_sgprs,
        .read_wave_vgprs = &gfx_v9_0_read_wave_vgprs,
+       .select_me_pipe_q = &gfx_v9_0_select_me_pipe_q
 };
 
 static void gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
@@ -2773,13 +2780,13 @@ static int gfx_v9_0_kiq_fini_register(struct amdgpu_ring *ring)
                        udelay(1);
                }
 
-               if (adev->usec_timeout == AMDGPU_MAX_USEC_TIMEOUT) {
+               if (j == AMDGPU_MAX_USEC_TIMEOUT) {
                        DRM_DEBUG("KIQ dequeue request failed.\n");
 
+                       /* Manual disable if dequeue request times out */
                        WREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE, 0);
                }
 
-               /* Manual disable if dequeue request times out */
                WREG32_SOC15(GC, 0, mmCP_HQD_DEQUEUE_REQUEST,
                      0);
        }