diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2973-drm-amdgpu-move-debugfs-functions-to-their-own-file.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2973-drm-amdgpu-move-debugfs-functions-to-their-own-file.patch | 1799 |
1 files changed, 1799 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2973-drm-amdgpu-move-debugfs-functions-to-their-own-file.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2973-drm-amdgpu-move-debugfs-functions-to-their-own-file.patch new file mode 100644 index 00000000..6611cdad --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2973-drm-amdgpu-move-debugfs-functions-to-their-own-file.patch @@ -0,0 +1,1799 @@ +From c76c13f7412766a2d8920bb6a4692f87c02fee02 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Thu, 14 Dec 2017 15:23:14 -0500 +Subject: [PATCH 2973/4131] drm/amdgpu: move debugfs functions to their own + file +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +amdgpu_device.c was getting pretty cluttered. + +Acked-by: Christian König <christian.koenig@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> + + Conflicts: + drivers/gpu/drm/amd/amdgpu/Makefile + drivers/gpu/drm/amd/amdgpu/amdgpu.h + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c + +Change-Id: Ie041cf55dfceb787db787c21bd81817eb92bcbed +--- + drivers/gpu/drm/amd/amdgpu/Makefile | 3 +- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 21 +- + drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 813 ++++++++++++++++++++++++++++ + drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h | 42 ++ + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 793 +-------------------------- + drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 +- + 6 files changed, 860 insertions(+), 814 deletions(-) + create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c + create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h + +diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile +index cc5aef2..da46ce1 100755 +--- a/drivers/gpu/drm/amd/amdgpu/Makefile ++++ b/drivers/gpu/drm/amd/amdgpu/Makefile +@@ -32,7 +32,8 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ + amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \ + amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \ + amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \ +- amdgpu_queue_mgr.o amdgpu_vf_error.o amdgpu_sched.o amdgpu_sem.o amdgpu_amdkfd_fence.o ++ amdgpu_queue_mgr.o amdgpu_vf_error.o amdgpu_sched.o amdgpu_sem.o amdgpu_amdkfd_fence.o \ ++ amdgpu_debugfs.o + + # add asic specific block + amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index f71e6e7..f446239 100755 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -72,7 +72,7 @@ + #include "amdgpu_mn.h" + #include "amdgpu_virt.h" + #include "amdgpu_gart.h" +- ++#include "amdgpu_debugfs.h" + + /* + * Modules parameters. +@@ -441,7 +441,6 @@ struct reservation_object *amdgpu_gem_prime_res_obj(struct drm_gem_object *); + void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj); + void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); + int amdgpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); +-int amdgpu_gem_debugfs_init(struct amdgpu_device *adev); + + /* sub-allocation manager, it has to be protected by another lock. + * By conception this is an helper for other part of the driver +@@ -1266,24 +1265,6 @@ void amdgpu_benchmark(struct amdgpu_device *adev, int test_number); + void amdgpu_test_moves(struct amdgpu_device *adev); + + /* +- * Debugfs +- */ +-struct amdgpu_debugfs { +- const struct drm_info_list *files; +- unsigned num_files; +-}; +- +-int amdgpu_debugfs_add_files(struct amdgpu_device *adev, +- const struct drm_info_list *files, +- unsigned nfiles); +-int amdgpu_debugfs_fence_init(struct amdgpu_device *adev); +- +-#if defined(CONFIG_DEBUG_FS) +-#endif +- +-int amdgpu_debugfs_firmware_init(struct amdgpu_device *adev); +- +-/* + * amdgpu smumgr functions + */ + struct amdgpu_smumgr_funcs { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +new file mode 100644 +index 0000000..07ae10f +--- /dev/null ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +@@ -0,0 +1,813 @@ ++/* ++ * Copyright 2008 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * Copyright 2009 Jerome Glisse. ++ * ++ * 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. ++ * ++ */ ++ ++#include <linux/kthread.h> ++#include <drm/drmP.h> ++#include <linux/debugfs.h> ++#include "amdgpu.h" ++ ++/* ++ * Debugfs ++ */ ++int amdgpu_debugfs_add_files(struct amdgpu_device *adev, ++ const struct drm_info_list *files, ++ unsigned nfiles) ++{ ++ unsigned i; ++ ++ for (i = 0; i < adev->debugfs_count; i++) { ++ if (adev->debugfs[i].files == files) { ++ /* Already registered */ ++ return 0; ++ } ++ } ++ ++ i = adev->debugfs_count + 1; ++ if (i > AMDGPU_DEBUGFS_MAX_COMPONENTS) { ++ DRM_ERROR("Reached maximum number of debugfs components.\n"); ++ DRM_ERROR("Report so we increase " ++ "AMDGPU_DEBUGFS_MAX_COMPONENTS.\n"); ++ return -EINVAL; ++ } ++ adev->debugfs[adev->debugfs_count].files = files; ++ adev->debugfs[adev->debugfs_count].num_files = nfiles; ++ adev->debugfs_count = i; ++#if defined(CONFIG_DEBUG_FS) ++ drm_debugfs_create_files(files, nfiles, ++ adev->ddev->primary->debugfs_root, ++ adev->ddev->primary); ++#endif ++ return 0; ++} ++ ++#if defined(BUILD_AS_DKMS) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) ++void amdgpu_debugfs_cleanup(struct drm_minor *minor) ++{ ++ struct drm_info_node *node, *tmp; ++ ++ if (!&minor->debugfs_root) ++ return 0; ++ ++ mutex_lock(&minor->debugfs_lock); ++ list_for_each_entry_safe(node, tmp, ++ &minor->debugfs_list, list) { ++ debugfs_remove(node->dent); ++ list_del(&node->list); ++ kfree(node); ++ } ++ mutex_unlock(&minor->debugfs_lock); ++ ++ return 0; ++} ++#endif ++ ++#if defined(CONFIG_DEBUG_FS) ++ ++static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)kcl_file_private(f); ++ 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) ++ goto end; ++ ++ value = RREG32(*pos >> 2); ++ r = put_user(value, (uint32_t *)buf); ++ if (r) { ++ result = r; ++ goto end; ++ } ++ ++ result += 4; ++ buf += 4; ++ *pos += 4; ++ size -= 4; ++ } ++ ++end: ++ 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; ++} ++ ++static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)kcl_file_private(f); ++ 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; ++} ++ ++static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)kcl_file_private(f); ++ ssize_t result = 0; ++ int r; ++ ++ if (size & 0x3 || *pos & 0x3) ++ return -EINVAL; ++ ++ while (size) { ++ uint32_t value; ++ ++ value = RREG32_PCIE(*pos >> 2); ++ r = put_user(value, (uint32_t *)buf); ++ if (r) ++ return r; ++ ++ result += 4; ++ buf += 4; ++ *pos += 4; ++ size -= 4; ++ } ++ ++ return result; ++} ++ ++static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)kcl_file_private(f); ++ ssize_t result = 0; ++ int r; ++ ++ if (size & 0x3 || *pos & 0x3) ++ return -EINVAL; ++ ++ while (size) { ++ uint32_t value; ++ ++ r = get_user(value, (uint32_t *)buf); ++ if (r) ++ return r; ++ ++ WREG32_PCIE(*pos >> 2, value); ++ ++ result += 4; ++ buf += 4; ++ *pos += 4; ++ size -= 4; ++ } ++ ++ return result; ++} ++ ++static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)kcl_file_private(f); ++ ssize_t result = 0; ++ int r; ++ ++ if (size & 0x3 || *pos & 0x3) ++ return -EINVAL; ++ ++ while (size) { ++ uint32_t value; ++ ++ value = RREG32_DIDT(*pos >> 2); ++ r = put_user(value, (uint32_t *)buf); ++ if (r) ++ return r; ++ ++ result += 4; ++ buf += 4; ++ *pos += 4; ++ size -= 4; ++ } ++ ++ return result; ++} ++ ++static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)kcl_file_private(f); ++ ssize_t result = 0; ++ int r; ++ ++ if (size & 0x3 || *pos & 0x3) ++ return -EINVAL; ++ ++ while (size) { ++ uint32_t value; ++ ++ r = get_user(value, (uint32_t *)buf); ++ if (r) ++ return r; ++ ++ WREG32_DIDT(*pos >> 2, value); ++ ++ result += 4; ++ buf += 4; ++ *pos += 4; ++ size -= 4; ++ } ++ ++ return result; ++} ++ ++static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)kcl_file_private(f); ++ ssize_t result = 0; ++ int r; ++ ++ if (size & 0x3 || *pos & 0x3) ++ return -EINVAL; ++ ++ while (size) { ++ uint32_t value; ++ ++ value = RREG32_SMC(*pos); ++ r = put_user(value, (uint32_t *)buf); ++ if (r) ++ return r; ++ ++ result += 4; ++ buf += 4; ++ *pos += 4; ++ size -= 4; ++ } ++ ++ return result; ++} ++ ++static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)kcl_file_private(f); ++ ssize_t result = 0; ++ int r; ++ ++ if (size & 0x3 || *pos & 0x3) ++ return -EINVAL; ++ ++ while (size) { ++ uint32_t value; ++ ++ r = get_user(value, (uint32_t *)buf); ++ if (r) ++ return r; ++ ++ WREG32_SMC(*pos, value); ++ ++ result += 4; ++ buf += 4; ++ *pos += 4; ++ size -= 4; ++ } ++ ++ return result; ++} ++ ++static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)kcl_file_private(f); ++ ssize_t result = 0; ++ int r; ++ uint32_t *config, no_regs = 0; ++ ++ if (size & 0x3 || *pos & 0x3) ++ return -EINVAL; ++ ++ config = kmalloc_array(256, sizeof(*config), GFP_KERNEL); ++ if (!config) ++ return -ENOMEM; ++ ++ /* version, increment each time something is added */ ++ config[no_regs++] = 3; ++ config[no_regs++] = adev->gfx.config.max_shader_engines; ++ config[no_regs++] = adev->gfx.config.max_tile_pipes; ++ config[no_regs++] = adev->gfx.config.max_cu_per_sh; ++ config[no_regs++] = adev->gfx.config.max_sh_per_se; ++ config[no_regs++] = adev->gfx.config.max_backends_per_se; ++ config[no_regs++] = adev->gfx.config.max_texture_channel_caches; ++ config[no_regs++] = adev->gfx.config.max_gprs; ++ config[no_regs++] = adev->gfx.config.max_gs_threads; ++ config[no_regs++] = adev->gfx.config.max_hw_contexts; ++ config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_frontend; ++ config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_backend; ++ config[no_regs++] = adev->gfx.config.sc_hiz_tile_fifo_size; ++ config[no_regs++] = adev->gfx.config.sc_earlyz_tile_fifo_size; ++ config[no_regs++] = adev->gfx.config.num_tile_pipes; ++ config[no_regs++] = adev->gfx.config.backend_enable_mask; ++ config[no_regs++] = adev->gfx.config.mem_max_burst_length_bytes; ++ config[no_regs++] = adev->gfx.config.mem_row_size_in_kb; ++ config[no_regs++] = adev->gfx.config.shader_engine_tile_size; ++ config[no_regs++] = adev->gfx.config.num_gpus; ++ config[no_regs++] = adev->gfx.config.multi_gpu_tile_size; ++ config[no_regs++] = adev->gfx.config.mc_arb_ramcfg; ++ config[no_regs++] = adev->gfx.config.gb_addr_config; ++ config[no_regs++] = adev->gfx.config.num_rbs; ++ ++ /* rev==1 */ ++ config[no_regs++] = adev->rev_id; ++ config[no_regs++] = adev->pg_flags; ++ config[no_regs++] = adev->cg_flags; ++ ++ /* rev==2 */ ++ config[no_regs++] = adev->family; ++ config[no_regs++] = adev->external_rev_id; ++ ++ /* rev==3 */ ++ config[no_regs++] = adev->pdev->device; ++ config[no_regs++] = adev->pdev->revision; ++ config[no_regs++] = adev->pdev->subsystem_device; ++ config[no_regs++] = adev->pdev->subsystem_vendor; ++ ++ while (size && (*pos < no_regs * 4)) { ++ uint32_t value; ++ ++ value = config[*pos >> 2]; ++ r = put_user(value, (uint32_t *)buf); ++ if (r) { ++ kfree(config); ++ return r; ++ } ++ ++ result += 4; ++ buf += 4; ++ *pos += 4; ++ size -= 4; ++ } ++ ++ kfree(config); ++ return result; ++} ++ ++static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)kcl_file_private(f); ++ int idx, x, outsize, r, valuesize; ++ uint32_t values[16]; ++ ++ if (size & 3 || *pos & 0x3) ++ return -EINVAL; ++ ++ if (amdgpu_dpm == 0) ++ return -EINVAL; ++ ++ /* convert offset to sensor number */ ++ idx = *pos >> 2; ++ ++ valuesize = sizeof(values); ++ if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->read_sensor) ++ r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize); ++ else ++ return -EINVAL; ++ ++ if (size > valuesize) ++ return -EINVAL; ++ ++ outsize = 0; ++ x = 0; ++ if (!r) { ++ while (size) { ++ r = put_user(values[x++], (int32_t *)buf); ++ buf += 4; ++ size -= 4; ++ outsize += 4; ++ } ++ } ++ ++ return !r ? outsize : r; ++} ++ ++static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)kcl_file_private(f); ++ int r, x; ++ ssize_t result=0; ++ uint32_t offset, se, sh, cu, wave, simd, data[32]; ++ ++ if (size & 3 || *pos & 3) ++ return -EINVAL; ++ ++ /* decode offset */ ++ offset = (*pos & GENMASK_ULL(6, 0)); ++ se = (*pos & GENMASK_ULL(14, 7)) >> 7; ++ sh = (*pos & GENMASK_ULL(22, 15)) >> 15; ++ cu = (*pos & GENMASK_ULL(30, 23)) >> 23; ++ wave = (*pos & GENMASK_ULL(36, 31)) >> 31; ++ simd = (*pos & GENMASK_ULL(44, 37)) >> 37; ++ ++ /* switch to the specific se/sh/cu */ ++ mutex_lock(&adev->grbm_idx_mutex); ++ amdgpu_gfx_select_se_sh(adev, se, sh, cu); ++ ++ x = 0; ++ if (adev->gfx.funcs->read_wave_data) ++ adev->gfx.funcs->read_wave_data(adev, simd, wave, data, &x); ++ ++ amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); ++ mutex_unlock(&adev->grbm_idx_mutex); ++ ++ if (!x) ++ return -EINVAL; ++ ++ while (size && (offset < x * 4)) { ++ uint32_t value; ++ ++ value = data[offset >> 2]; ++ r = put_user(value, (uint32_t *)buf); ++ if (r) ++ return r; ++ ++ result += 4; ++ buf += 4; ++ offset += 4; ++ size -= 4; ++ } ++ ++ return result; ++} ++ ++static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct amdgpu_device *adev = (struct amdgpu_device *)kcl_file_private(f); ++ int r; ++ ssize_t result = 0; ++ uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data; ++ ++ if (size & 3 || *pos & 3) ++ return -EINVAL; ++ ++ /* decode offset */ ++ offset = *pos & GENMASK_ULL(11, 0); ++ se = (*pos & GENMASK_ULL(19, 12)) >> 12; ++ sh = (*pos & GENMASK_ULL(27, 20)) >> 20; ++ cu = (*pos & GENMASK_ULL(35, 28)) >> 28; ++ wave = (*pos & GENMASK_ULL(43, 36)) >> 36; ++ simd = (*pos & GENMASK_ULL(51, 44)) >> 44; ++ thread = (*pos & GENMASK_ULL(59, 52)) >> 52; ++ bank = (*pos & GENMASK_ULL(61, 60)) >> 60; ++ ++ data = kmalloc_array(1024, sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ ++ /* switch to the specific se/sh/cu */ ++ mutex_lock(&adev->grbm_idx_mutex); ++ amdgpu_gfx_select_se_sh(adev, se, sh, cu); ++ ++ if (bank == 0) { ++ if (adev->gfx.funcs->read_wave_vgprs) ++ adev->gfx.funcs->read_wave_vgprs(adev, simd, wave, thread, offset, size>>2, data); ++ } else { ++ if (adev->gfx.funcs->read_wave_sgprs) ++ adev->gfx.funcs->read_wave_sgprs(adev, simd, wave, offset, size>>2, data); ++ } ++ ++ amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); ++ mutex_unlock(&adev->grbm_idx_mutex); ++ ++ while (size) { ++ uint32_t value; ++ ++ value = data[offset++]; ++ r = put_user(value, (uint32_t *)buf); ++ if (r) { ++ result = r; ++ goto err; ++ } ++ ++ result += 4; ++ buf += 4; ++ size -= 4; ++ } ++ ++err: ++ kfree(data); ++ return result; ++} ++ ++static const struct file_operations amdgpu_debugfs_regs_fops = { ++ .owner = THIS_MODULE, ++ .read = amdgpu_debugfs_regs_read, ++ .write = amdgpu_debugfs_regs_write, ++ .llseek = default_llseek ++}; ++static const struct file_operations amdgpu_debugfs_regs_didt_fops = { ++ .owner = THIS_MODULE, ++ .read = amdgpu_debugfs_regs_didt_read, ++ .write = amdgpu_debugfs_regs_didt_write, ++ .llseek = default_llseek ++}; ++static const struct file_operations amdgpu_debugfs_regs_pcie_fops = { ++ .owner = THIS_MODULE, ++ .read = amdgpu_debugfs_regs_pcie_read, ++ .write = amdgpu_debugfs_regs_pcie_write, ++ .llseek = default_llseek ++}; ++static const struct file_operations amdgpu_debugfs_regs_smc_fops = { ++ .owner = THIS_MODULE, ++ .read = amdgpu_debugfs_regs_smc_read, ++ .write = amdgpu_debugfs_regs_smc_write, ++ .llseek = default_llseek ++}; ++ ++static const struct file_operations amdgpu_debugfs_gca_config_fops = { ++ .owner = THIS_MODULE, ++ .read = amdgpu_debugfs_gca_config_read, ++ .llseek = default_llseek ++}; ++ ++static const struct file_operations amdgpu_debugfs_sensors_fops = { ++ .owner = THIS_MODULE, ++ .read = amdgpu_debugfs_sensor_read, ++ .llseek = default_llseek ++}; ++ ++static const struct file_operations amdgpu_debugfs_wave_fops = { ++ .owner = THIS_MODULE, ++ .read = amdgpu_debugfs_wave_read, ++ .llseek = default_llseek ++}; ++static const struct file_operations amdgpu_debugfs_gpr_fops = { ++ .owner = THIS_MODULE, ++ .read = amdgpu_debugfs_gpr_read, ++ .llseek = default_llseek ++}; ++ ++static const struct file_operations *debugfs_regs[] = { ++ &amdgpu_debugfs_regs_fops, ++ &amdgpu_debugfs_regs_didt_fops, ++ &amdgpu_debugfs_regs_pcie_fops, ++ &amdgpu_debugfs_regs_smc_fops, ++ &amdgpu_debugfs_gca_config_fops, ++ &amdgpu_debugfs_sensors_fops, ++ &amdgpu_debugfs_wave_fops, ++ &amdgpu_debugfs_gpr_fops, ++}; ++ ++static const char *debugfs_regs_names[] = { ++ "amdgpu_regs", ++ "amdgpu_regs_didt", ++ "amdgpu_regs_pcie", ++ "amdgpu_regs_smc", ++ "amdgpu_gca_config", ++ "amdgpu_sensors", ++ "amdgpu_wave", ++ "amdgpu_gpr", ++}; ++ ++int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) ++{ ++ struct drm_minor *minor = adev->ddev->primary; ++ struct dentry *ent, *root = minor->debugfs_root; ++ unsigned i, j; ++ ++ for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) { ++ ent = debugfs_create_file(debugfs_regs_names[i], ++ S_IFREG | S_IRUGO, root, ++ adev, debugfs_regs[i]); ++ if (IS_ERR(ent)) { ++ for (j = 0; j < i; j++) { ++ debugfs_remove(adev->debugfs_regs[i]); ++ adev->debugfs_regs[i] = NULL; ++ } ++ return PTR_ERR(ent); ++ } ++ ++ if (!i) ++ i_size_write(ent->d_inode, adev->rmmio_size); ++ adev->debugfs_regs[i] = ent; ++ } ++ ++ return 0; ++} ++ ++void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) ++{ ++ unsigned i; ++ ++ for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) { ++ if (adev->debugfs_regs[i]) { ++ debugfs_remove(adev->debugfs_regs[i]); ++ adev->debugfs_regs[i] = NULL; ++ } ++ } ++} ++ ++static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct amdgpu_device *adev = dev->dev_private; ++ int r = 0, i; ++ ++ /* hold on the scheduler */ ++ for (i = 0; i < AMDGPU_MAX_RINGS; i++) { ++ struct amdgpu_ring *ring = adev->rings[i]; ++ ++ if (!ring || !ring->sched.thread) ++ continue; ++ kcl_kthread_park(ring->sched.thread); ++ } ++ ++ seq_printf(m, "run ib test:\n"); ++ r = amdgpu_ib_ring_tests(adev); ++ if (r) ++ seq_printf(m, "ib ring tests failed (%d).\n", r); ++ else ++ seq_printf(m, "ib ring tests passed.\n"); ++ ++ /* go on the scheduler */ ++ for (i = 0; i < AMDGPU_MAX_RINGS; i++) { ++ struct amdgpu_ring *ring = adev->rings[i]; ++ ++ if (!ring || !ring->sched.thread) ++ continue; ++ kcl_kthread_unpark(ring->sched.thread); ++ } ++ ++ return 0; ++} ++ ++static int amdgpu_debugfs_get_vbios_dump(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct amdgpu_device *adev = dev->dev_private; ++ ++ seq_write(m, adev->bios, adev->bios_size); ++ return 0; ++} ++ ++static int amdgpu_debugfs_evict_vram(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *)m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct amdgpu_device *adev = dev->dev_private; ++ ++ seq_printf(m, "(%d)\n", amdgpu_bo_evict_vram(adev)); ++ return 0; ++} ++ ++static const struct drm_info_list amdgpu_debugfs_list[] = { ++ {"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump}, ++ {"amdgpu_test_ib", &amdgpu_debugfs_test_ib}, ++ {"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram} ++}; ++ ++int amdgpu_debugfs_init(struct amdgpu_device *adev) ++{ ++ return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_list, ++ ARRAY_SIZE(amdgpu_debugfs_list)); ++} ++ ++#else ++int amdgpu_debugfs_init(struct amdgpu_device *adev) ++{ ++ return 0; ++} ++int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) ++{ ++ return 0; ++} ++void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) { } ++#endif +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h +new file mode 100644 +index 0000000..8260d80 +--- /dev/null ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright 2008 Advanced Micro Devices, Inc. ++ * Copyright 2008 Red Hat Inc. ++ * Copyright 2009 Jerome Glisse. ++ * ++ * 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. ++ * ++ */ ++ ++/* ++ * Debugfs ++ */ ++struct amdgpu_debugfs { ++ const struct drm_info_list *files; ++ unsigned num_files; ++}; ++ ++int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); ++void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev); ++int amdgpu_debugfs_init(struct amdgpu_device *adev); ++int amdgpu_debugfs_add_files(struct amdgpu_device *adev, ++ const struct drm_info_list *files, ++ unsigned nfiles); ++int amdgpu_debugfs_fence_init(struct amdgpu_device *adev); ++int amdgpu_debugfs_firmware_init(struct amdgpu_device *adev); ++int amdgpu_debugfs_gem_init(struct amdgpu_device *adev); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index 1eceb1c..32488c4 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -28,7 +28,6 @@ + #include <linux/kthread.h> + #include <linux/console.h> + #include <linux/slab.h> +-#include <linux/debugfs.h> + #include <drm/drmP.h> + #include <drm/drm_crtc_helper.h> + #include <drm/drm_atomic_helper.h> +@@ -60,14 +59,9 @@ + #include "amdgpu_pm.h" + + MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin"); +-MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin"); + + #define AMDGPU_RESUME_MS 2000 + +-static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); +-static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev); +-static int amdgpu_debugfs_init(struct amdgpu_device *adev); +- + static const char *amdgpu_asic_name[] = { + "TAHITI", + "PITCAIRN", +@@ -2197,7 +2191,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, + if (r) + DRM_ERROR("registering pm debugfs failed (%d).\n", r); + +- r = amdgpu_gem_debugfs_init(adev); ++ r = amdgpu_debugfs_gem_init(adev); + if (r) + DRM_ERROR("registering gem debugfs failed (%d).\n", r); + +@@ -3049,788 +3043,3 @@ void amdgpu_get_pcie_info(struct amdgpu_device *adev) + } + } + } +- +-/* +- * Debugfs +- */ +-int amdgpu_debugfs_add_files(struct amdgpu_device *adev, +- const struct drm_info_list *files, +- unsigned nfiles) +-{ +- unsigned i; +- +- for (i = 0; i < adev->debugfs_count; i++) { +- if (adev->debugfs[i].files == files) { +- /* Already registered */ +- return 0; +- } +- } +- +- i = adev->debugfs_count + 1; +- if (i > AMDGPU_DEBUGFS_MAX_COMPONENTS) { +- DRM_ERROR("Reached maximum number of debugfs components.\n"); +- DRM_ERROR("Report so we increase " +- "AMDGPU_DEBUGFS_MAX_COMPONENTS.\n"); +- return -EINVAL; +- } +- adev->debugfs[adev->debugfs_count].files = files; +- adev->debugfs[adev->debugfs_count].num_files = nfiles; +- adev->debugfs_count = i; +-#if defined(CONFIG_DEBUG_FS) +- drm_debugfs_create_files(files, nfiles, +- adev->ddev->primary->debugfs_root, +- adev->ddev->primary); +-#endif +- return 0; +-} +- +-#if defined(BUILD_AS_DKMS) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) +-void amdgpu_debugfs_cleanup(struct drm_minor *minor) +-{ +- struct drm_info_node *node, *tmp; +- +- if (!&minor->debugfs_root) +- return 0; +- +- mutex_lock(&minor->debugfs_lock); +- list_for_each_entry_safe(node, tmp, +- &minor->debugfs_list, list) { +- debugfs_remove(node->dent); +- list_del(&node->list); +- kfree(node); +- } +- mutex_unlock(&minor->debugfs_lock); +- +- return 0; +-} +-#endif +- +-#if defined(CONFIG_DEBUG_FS) +- +-static ssize_t amdgpu_debugfs_regs_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; +- +- 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) +- goto end; +- +- value = RREG32(*pos >> 2); +- r = put_user(value, (uint32_t *)buf); +- if (r) { +- result = r; +- goto end; +- } +- +- result += 4; +- buf += 4; +- *pos += 4; +- size -= 4; +- } +- +-end: +- 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; +-} +- +-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; +-} +- +-static ssize_t amdgpu_debugfs_regs_pcie_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; +- +- if (size & 0x3 || *pos & 0x3) +- return -EINVAL; +- +- while (size) { +- uint32_t value; +- +- value = RREG32_PCIE(*pos >> 2); +- r = put_user(value, (uint32_t *)buf); +- if (r) +- return r; +- +- result += 4; +- buf += 4; +- *pos += 4; +- size -= 4; +- } +- +- return result; +-} +- +-static ssize_t amdgpu_debugfs_regs_pcie_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; +- +- if (size & 0x3 || *pos & 0x3) +- return -EINVAL; +- +- while (size) { +- uint32_t value; +- +- r = get_user(value, (uint32_t *)buf); +- if (r) +- return r; +- +- WREG32_PCIE(*pos >> 2, value); +- +- result += 4; +- buf += 4; +- *pos += 4; +- size -= 4; +- } +- +- return result; +-} +- +-static ssize_t amdgpu_debugfs_regs_didt_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; +- +- if (size & 0x3 || *pos & 0x3) +- return -EINVAL; +- +- while (size) { +- uint32_t value; +- +- value = RREG32_DIDT(*pos >> 2); +- r = put_user(value, (uint32_t *)buf); +- if (r) +- return r; +- +- result += 4; +- buf += 4; +- *pos += 4; +- size -= 4; +- } +- +- return result; +-} +- +-static ssize_t amdgpu_debugfs_regs_didt_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; +- +- if (size & 0x3 || *pos & 0x3) +- return -EINVAL; +- +- while (size) { +- uint32_t value; +- +- r = get_user(value, (uint32_t *)buf); +- if (r) +- return r; +- +- WREG32_DIDT(*pos >> 2, value); +- +- result += 4; +- buf += 4; +- *pos += 4; +- size -= 4; +- } +- +- return result; +-} +- +-static ssize_t amdgpu_debugfs_regs_smc_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; +- +- if (size & 0x3 || *pos & 0x3) +- return -EINVAL; +- +- while (size) { +- uint32_t value; +- +- value = RREG32_SMC(*pos); +- r = put_user(value, (uint32_t *)buf); +- if (r) +- return r; +- +- result += 4; +- buf += 4; +- *pos += 4; +- size -= 4; +- } +- +- return result; +-} +- +-static ssize_t amdgpu_debugfs_regs_smc_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; +- +- if (size & 0x3 || *pos & 0x3) +- return -EINVAL; +- +- while (size) { +- uint32_t value; +- +- r = get_user(value, (uint32_t *)buf); +- if (r) +- return r; +- +- WREG32_SMC(*pos, value); +- +- result += 4; +- buf += 4; +- *pos += 4; +- size -= 4; +- } +- +- return result; +-} +- +-static ssize_t amdgpu_debugfs_gca_config_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; +- uint32_t *config, no_regs = 0; +- +- if (size & 0x3 || *pos & 0x3) +- return -EINVAL; +- +- config = kmalloc_array(256, sizeof(*config), GFP_KERNEL); +- if (!config) +- return -ENOMEM; +- +- /* version, increment each time something is added */ +- config[no_regs++] = 3; +- config[no_regs++] = adev->gfx.config.max_shader_engines; +- config[no_regs++] = adev->gfx.config.max_tile_pipes; +- config[no_regs++] = adev->gfx.config.max_cu_per_sh; +- config[no_regs++] = adev->gfx.config.max_sh_per_se; +- config[no_regs++] = adev->gfx.config.max_backends_per_se; +- config[no_regs++] = adev->gfx.config.max_texture_channel_caches; +- config[no_regs++] = adev->gfx.config.max_gprs; +- config[no_regs++] = adev->gfx.config.max_gs_threads; +- config[no_regs++] = adev->gfx.config.max_hw_contexts; +- config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_frontend; +- config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_backend; +- config[no_regs++] = adev->gfx.config.sc_hiz_tile_fifo_size; +- config[no_regs++] = adev->gfx.config.sc_earlyz_tile_fifo_size; +- config[no_regs++] = adev->gfx.config.num_tile_pipes; +- config[no_regs++] = adev->gfx.config.backend_enable_mask; +- config[no_regs++] = adev->gfx.config.mem_max_burst_length_bytes; +- config[no_regs++] = adev->gfx.config.mem_row_size_in_kb; +- config[no_regs++] = adev->gfx.config.shader_engine_tile_size; +- config[no_regs++] = adev->gfx.config.num_gpus; +- config[no_regs++] = adev->gfx.config.multi_gpu_tile_size; +- config[no_regs++] = adev->gfx.config.mc_arb_ramcfg; +- config[no_regs++] = adev->gfx.config.gb_addr_config; +- config[no_regs++] = adev->gfx.config.num_rbs; +- +- /* rev==1 */ +- config[no_regs++] = adev->rev_id; +- config[no_regs++] = adev->pg_flags; +- config[no_regs++] = adev->cg_flags; +- +- /* rev==2 */ +- config[no_regs++] = adev->family; +- config[no_regs++] = adev->external_rev_id; +- +- /* rev==3 */ +- config[no_regs++] = adev->pdev->device; +- config[no_regs++] = adev->pdev->revision; +- config[no_regs++] = adev->pdev->subsystem_device; +- config[no_regs++] = adev->pdev->subsystem_vendor; +- +- while (size && (*pos < no_regs * 4)) { +- uint32_t value; +- +- value = config[*pos >> 2]; +- r = put_user(value, (uint32_t *)buf); +- if (r) { +- kfree(config); +- return r; +- } +- +- result += 4; +- buf += 4; +- *pos += 4; +- size -= 4; +- } +- +- kfree(config); +- return result; +-} +- +-static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf, +- size_t size, loff_t *pos) +-{ +- struct amdgpu_device *adev = file_inode(f)->i_private; +- int idx, x, outsize, r, valuesize; +- uint32_t values[16]; +- +- if (size & 3 || *pos & 0x3) +- return -EINVAL; +- +- if (amdgpu_dpm == 0) +- return -EINVAL; +- +- /* convert offset to sensor number */ +- idx = *pos >> 2; +- +- valuesize = sizeof(values); +- if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->read_sensor) +- r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize); +- else +- return -EINVAL; +- +- if (size > valuesize) +- return -EINVAL; +- +- outsize = 0; +- x = 0; +- if (!r) { +- while (size) { +- r = put_user(values[x++], (int32_t *)buf); +- buf += 4; +- size -= 4; +- outsize += 4; +- } +- } +- +- return !r ? outsize : r; +-} +- +-static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf, +- size_t size, loff_t *pos) +-{ +- struct amdgpu_device *adev = file_inode(f)->i_private; +- int r, x; +- ssize_t result=0; +- uint32_t offset, se, sh, cu, wave, simd, data[32]; +- +- if (size & 3 || *pos & 3) +- return -EINVAL; +- +- /* decode offset */ +- offset = (*pos & GENMASK_ULL(6, 0)); +- se = (*pos & GENMASK_ULL(14, 7)) >> 7; +- sh = (*pos & GENMASK_ULL(22, 15)) >> 15; +- cu = (*pos & GENMASK_ULL(30, 23)) >> 23; +- wave = (*pos & GENMASK_ULL(36, 31)) >> 31; +- simd = (*pos & GENMASK_ULL(44, 37)) >> 37; +- +- /* switch to the specific se/sh/cu */ +- mutex_lock(&adev->grbm_idx_mutex); +- amdgpu_gfx_select_se_sh(adev, se, sh, cu); +- +- x = 0; +- if (adev->gfx.funcs->read_wave_data) +- adev->gfx.funcs->read_wave_data(adev, simd, wave, data, &x); +- +- amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); +- mutex_unlock(&adev->grbm_idx_mutex); +- +- if (!x) +- return -EINVAL; +- +- while (size && (offset < x * 4)) { +- uint32_t value; +- +- value = data[offset >> 2]; +- r = put_user(value, (uint32_t *)buf); +- if (r) +- return r; +- +- result += 4; +- buf += 4; +- offset += 4; +- size -= 4; +- } +- +- return result; +-} +- +-static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, +- size_t size, loff_t *pos) +-{ +- struct amdgpu_device *adev = file_inode(f)->i_private; +- +- int r; +- ssize_t result = 0; +- uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data; +- +- if (size & 3 || *pos & 3) +- return -EINVAL; +- +- /* decode offset */ +- offset = *pos & GENMASK_ULL(11, 0); +- se = (*pos & GENMASK_ULL(19, 12)) >> 12; +- sh = (*pos & GENMASK_ULL(27, 20)) >> 20; +- cu = (*pos & GENMASK_ULL(35, 28)) >> 28; +- wave = (*pos & GENMASK_ULL(43, 36)) >> 36; +- simd = (*pos & GENMASK_ULL(51, 44)) >> 44; +- thread = (*pos & GENMASK_ULL(59, 52)) >> 52; +- bank = (*pos & GENMASK_ULL(61, 60)) >> 60; +- +- data = kmalloc_array(1024, sizeof(*data), GFP_KERNEL); +- if (!data) +- return -ENOMEM; +- +- /* switch to the specific se/sh/cu */ +- mutex_lock(&adev->grbm_idx_mutex); +- amdgpu_gfx_select_se_sh(adev, se, sh, cu); +- +- if (bank == 0) { +- if (adev->gfx.funcs->read_wave_vgprs) +- adev->gfx.funcs->read_wave_vgprs(adev, simd, wave, thread, offset, size>>2, data); +- } else { +- if (adev->gfx.funcs->read_wave_sgprs) +- adev->gfx.funcs->read_wave_sgprs(adev, simd, wave, offset, size>>2, data); +- } +- +- amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); +- mutex_unlock(&adev->grbm_idx_mutex); +- +- while (size) { +- uint32_t value; +- +- value = data[offset++]; +- r = put_user(value, (uint32_t *)buf); +- if (r) { +- result = r; +- goto err; +- } +- +- result += 4; +- buf += 4; +- size -= 4; +- } +- +-err: +- kfree(data); +- return result; +-} +- +-static const struct file_operations amdgpu_debugfs_regs_fops = { +- .owner = THIS_MODULE, +- .read = amdgpu_debugfs_regs_read, +- .write = amdgpu_debugfs_regs_write, +- .llseek = default_llseek +-}; +-static const struct file_operations amdgpu_debugfs_regs_didt_fops = { +- .owner = THIS_MODULE, +- .read = amdgpu_debugfs_regs_didt_read, +- .write = amdgpu_debugfs_regs_didt_write, +- .llseek = default_llseek +-}; +-static const struct file_operations amdgpu_debugfs_regs_pcie_fops = { +- .owner = THIS_MODULE, +- .read = amdgpu_debugfs_regs_pcie_read, +- .write = amdgpu_debugfs_regs_pcie_write, +- .llseek = default_llseek +-}; +-static const struct file_operations amdgpu_debugfs_regs_smc_fops = { +- .owner = THIS_MODULE, +- .read = amdgpu_debugfs_regs_smc_read, +- .write = amdgpu_debugfs_regs_smc_write, +- .llseek = default_llseek +-}; +- +-static const struct file_operations amdgpu_debugfs_gca_config_fops = { +- .owner = THIS_MODULE, +- .read = amdgpu_debugfs_gca_config_read, +- .llseek = default_llseek +-}; +- +-static const struct file_operations amdgpu_debugfs_sensors_fops = { +- .owner = THIS_MODULE, +- .read = amdgpu_debugfs_sensor_read, +- .llseek = default_llseek +-}; +- +-static const struct file_operations amdgpu_debugfs_wave_fops = { +- .owner = THIS_MODULE, +- .read = amdgpu_debugfs_wave_read, +- .llseek = default_llseek +-}; +-static const struct file_operations amdgpu_debugfs_gpr_fops = { +- .owner = THIS_MODULE, +- .read = amdgpu_debugfs_gpr_read, +- .llseek = default_llseek +-}; +- +-static const struct file_operations *debugfs_regs[] = { +- &amdgpu_debugfs_regs_fops, +- &amdgpu_debugfs_regs_didt_fops, +- &amdgpu_debugfs_regs_pcie_fops, +- &amdgpu_debugfs_regs_smc_fops, +- &amdgpu_debugfs_gca_config_fops, +- &amdgpu_debugfs_sensors_fops, +- &amdgpu_debugfs_wave_fops, +- &amdgpu_debugfs_gpr_fops, +-}; +- +-static const char *debugfs_regs_names[] = { +- "amdgpu_regs", +- "amdgpu_regs_didt", +- "amdgpu_regs_pcie", +- "amdgpu_regs_smc", +- "amdgpu_gca_config", +- "amdgpu_sensors", +- "amdgpu_wave", +- "amdgpu_gpr", +-}; +- +-static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) +-{ +- struct drm_minor *minor = adev->ddev->primary; +- struct dentry *ent, *root = minor->debugfs_root; +- unsigned i, j; +- +- for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) { +- ent = debugfs_create_file(debugfs_regs_names[i], +- S_IFREG | S_IRUGO, root, +- adev, debugfs_regs[i]); +- if (IS_ERR(ent)) { +- for (j = 0; j < i; j++) { +- debugfs_remove(adev->debugfs_regs[i]); +- adev->debugfs_regs[i] = NULL; +- } +- return PTR_ERR(ent); +- } +- +- if (!i) +- i_size_write(ent->d_inode, adev->rmmio_size); +- adev->debugfs_regs[i] = ent; +- } +- +- return 0; +-} +- +-static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) +-{ +- unsigned i; +- +- for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) { +- if (adev->debugfs_regs[i]) { +- debugfs_remove(adev->debugfs_regs[i]); +- adev->debugfs_regs[i] = NULL; +- } +- } +-} +- +-static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data) +-{ +- struct drm_info_node *node = (struct drm_info_node *) m->private; +- struct drm_device *dev = node->minor->dev; +- struct amdgpu_device *adev = dev->dev_private; +- int r = 0, i; +- +- /* hold on the scheduler */ +- for (i = 0; i < AMDGPU_MAX_RINGS; i++) { +- struct amdgpu_ring *ring = adev->rings[i]; +- +- if (!ring || !ring->sched.thread) +- continue; +- kthread_park(ring->sched.thread); +- } +- +- seq_printf(m, "run ib test:\n"); +- r = amdgpu_ib_ring_tests(adev); +- if (r) +- seq_printf(m, "ib ring tests failed (%d).\n", r); +- else +- seq_printf(m, "ib ring tests passed.\n"); +- +- /* go on the scheduler */ +- for (i = 0; i < AMDGPU_MAX_RINGS; i++) { +- struct amdgpu_ring *ring = adev->rings[i]; +- +- if (!ring || !ring->sched.thread) +- continue; +- kthread_unpark(ring->sched.thread); +- } +- +- return 0; +-} +- +-static int amdgpu_debugfs_get_vbios_dump(struct seq_file *m, void *data) +-{ +- struct drm_info_node *node = (struct drm_info_node *) m->private; +- struct drm_device *dev = node->minor->dev; +- struct amdgpu_device *adev = dev->dev_private; +- +- seq_write(m, adev->bios, adev->bios_size); +- return 0; +-} +- +-static int amdgpu_debugfs_evict_vram(struct seq_file *m, void *data) +-{ +- struct drm_info_node *node = (struct drm_info_node *)m->private; +- struct drm_device *dev = node->minor->dev; +- struct amdgpu_device *adev = dev->dev_private; +- +- seq_printf(m, "(%d)\n", amdgpu_bo_evict_vram(adev)); +- return 0; +-} +- +-static const struct drm_info_list amdgpu_debugfs_list[] = { +- {"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump}, +- {"amdgpu_test_ib", &amdgpu_debugfs_test_ib}, +- {"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram} +-}; +- +-static int amdgpu_debugfs_init(struct amdgpu_device *adev) +-{ +- return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_list, +- ARRAY_SIZE(amdgpu_debugfs_list)); +-} +- +-#else +-static int amdgpu_debugfs_init(struct amdgpu_device *adev) +-{ +- return 0; +-} +-static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) +-{ +- return 0; +-} +-static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) { } +-#endif +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +index c9149a1f..96143ee 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +@@ -1028,7 +1028,7 @@ static const struct drm_info_list amdgpu_debugfs_gem_list[] = { + }; + #endif + +-int amdgpu_gem_debugfs_init(struct amdgpu_device *adev) ++int amdgpu_debugfs_gem_init(struct amdgpu_device *adev) + { + #if defined(CONFIG_DEBUG_FS) + return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_gem_list, 1); +-- +2.7.4 + |