1*41ec0267Sriastradh /* $NetBSD: amdgpu_debugfs.c,v 1.2 2021/12/18 23:44:58 riastradh Exp $ */
24e390cabSriastradh
34e390cabSriastradh /*
44e390cabSriastradh * Copyright 2008 Advanced Micro Devices, Inc.
54e390cabSriastradh * Copyright 2008 Red Hat Inc.
64e390cabSriastradh * Copyright 2009 Jerome Glisse.
74e390cabSriastradh *
84e390cabSriastradh * Permission is hereby granted, free of charge, to any person obtaining a
94e390cabSriastradh * copy of this software and associated documentation files (the "Software"),
104e390cabSriastradh * to deal in the Software without restriction, including without limitation
114e390cabSriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense,
124e390cabSriastradh * and/or sell copies of the Software, and to permit persons to whom the
134e390cabSriastradh * Software is furnished to do so, subject to the following conditions:
144e390cabSriastradh *
154e390cabSriastradh * The above copyright notice and this permission notice shall be included in
164e390cabSriastradh * all copies or substantial portions of the Software.
174e390cabSriastradh *
184e390cabSriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
194e390cabSriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
204e390cabSriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
214e390cabSriastradh * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
224e390cabSriastradh * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
234e390cabSriastradh * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
244e390cabSriastradh * OTHER DEALINGS IN THE SOFTWARE.
254e390cabSriastradh *
264e390cabSriastradh */
274e390cabSriastradh
284e390cabSriastradh #include <sys/cdefs.h>
29*41ec0267Sriastradh __KERNEL_RCSID(0, "$NetBSD: amdgpu_debugfs.c,v 1.2 2021/12/18 23:44:58 riastradh Exp $");
304e390cabSriastradh
314e390cabSriastradh #include <linux/kthread.h>
324e390cabSriastradh #include <linux/pci.h>
334e390cabSriastradh #include <linux/uaccess.h>
344e390cabSriastradh #include <linux/pm_runtime.h>
354e390cabSriastradh
364e390cabSriastradh #include <drm/drm_debugfs.h>
374e390cabSriastradh
384e390cabSriastradh #include "amdgpu.h"
394e390cabSriastradh
404e390cabSriastradh /**
414e390cabSriastradh * amdgpu_debugfs_add_files - Add simple debugfs entries
424e390cabSriastradh *
434e390cabSriastradh * @adev: Device to attach debugfs entries to
444e390cabSriastradh * @files: Array of function callbacks that respond to reads
454e390cabSriastradh * @nfiles: Number of callbacks to register
464e390cabSriastradh *
474e390cabSriastradh */
amdgpu_debugfs_add_files(struct amdgpu_device * adev,const struct drm_info_list * files,unsigned nfiles)484e390cabSriastradh int amdgpu_debugfs_add_files(struct amdgpu_device *adev,
494e390cabSriastradh const struct drm_info_list *files,
504e390cabSriastradh unsigned nfiles)
514e390cabSriastradh {
524e390cabSriastradh unsigned i;
534e390cabSriastradh
544e390cabSriastradh for (i = 0; i < adev->debugfs_count; i++) {
554e390cabSriastradh if (adev->debugfs[i].files == files) {
564e390cabSriastradh /* Already registered */
574e390cabSriastradh return 0;
584e390cabSriastradh }
594e390cabSriastradh }
604e390cabSriastradh
614e390cabSriastradh i = adev->debugfs_count + 1;
624e390cabSriastradh if (i > AMDGPU_DEBUGFS_MAX_COMPONENTS) {
634e390cabSriastradh DRM_ERROR("Reached maximum number of debugfs components.\n");
644e390cabSriastradh DRM_ERROR("Report so we increase "
654e390cabSriastradh "AMDGPU_DEBUGFS_MAX_COMPONENTS.\n");
664e390cabSriastradh return -EINVAL;
674e390cabSriastradh }
684e390cabSriastradh adev->debugfs[adev->debugfs_count].files = files;
694e390cabSriastradh adev->debugfs[adev->debugfs_count].num_files = nfiles;
704e390cabSriastradh adev->debugfs_count = i;
714e390cabSriastradh #if defined(CONFIG_DEBUG_FS)
724e390cabSriastradh drm_debugfs_create_files(files, nfiles,
734e390cabSriastradh adev->ddev->primary->debugfs_root,
744e390cabSriastradh adev->ddev->primary);
754e390cabSriastradh #endif
764e390cabSriastradh return 0;
774e390cabSriastradh }
784e390cabSriastradh
794e390cabSriastradh #if defined(CONFIG_DEBUG_FS)
804e390cabSriastradh
814e390cabSriastradh /**
824e390cabSriastradh * amdgpu_debugfs_process_reg_op - Handle MMIO register reads/writes
834e390cabSriastradh *
844e390cabSriastradh * @read: True if reading
854e390cabSriastradh * @f: open file handle
864e390cabSriastradh * @buf: User buffer to write/read to
874e390cabSriastradh * @size: Number of bytes to write/read
884e390cabSriastradh * @pos: Offset to seek to
894e390cabSriastradh *
904e390cabSriastradh * This debugfs entry has special meaning on the offset being sought.
914e390cabSriastradh * Various bits have different meanings:
924e390cabSriastradh *
934e390cabSriastradh * Bit 62: Indicates a GRBM bank switch is needed
944e390cabSriastradh * Bit 61: Indicates a SRBM bank switch is needed (implies bit 62 is
954e390cabSriastradh * zero)
964e390cabSriastradh * Bits 24..33: The SE or ME selector if needed
974e390cabSriastradh * Bits 34..43: The SH (or SA) or PIPE selector if needed
984e390cabSriastradh * Bits 44..53: The INSTANCE (or CU/WGP) or QUEUE selector if needed
994e390cabSriastradh *
1004e390cabSriastradh * Bit 23: Indicates that the PM power gating lock should be held
1014e390cabSriastradh * This is necessary to read registers that might be
1024e390cabSriastradh * unreliable during a power gating transistion.
1034e390cabSriastradh *
1044e390cabSriastradh * The lower bits are the BYTE offset of the register to read. This
1054e390cabSriastradh * allows reading multiple registers in a single call and having
1064e390cabSriastradh * the returned size reflect that.
1074e390cabSriastradh */
amdgpu_debugfs_process_reg_op(bool read,struct file * f,char __user * buf,size_t size,loff_t * pos)1084e390cabSriastradh static int amdgpu_debugfs_process_reg_op(bool read, struct file *f,
1094e390cabSriastradh char __user *buf, size_t size, loff_t *pos)
1104e390cabSriastradh {
1114e390cabSriastradh struct amdgpu_device *adev = file_inode(f)->i_private;
1124e390cabSriastradh ssize_t result = 0;
1134e390cabSriastradh int r;
1144e390cabSriastradh bool pm_pg_lock, use_bank, use_ring;
1154e390cabSriastradh unsigned instance_bank, sh_bank, se_bank, me, pipe, queue, vmid;
1164e390cabSriastradh
1174e390cabSriastradh pm_pg_lock = use_bank = use_ring = false;
1184e390cabSriastradh instance_bank = sh_bank = se_bank = me = pipe = queue = vmid = 0;
1194e390cabSriastradh
1204e390cabSriastradh if (size & 0x3 || *pos & 0x3 ||
1214e390cabSriastradh ((*pos & (1ULL << 62)) && (*pos & (1ULL << 61))))
1224e390cabSriastradh return -EINVAL;
1234e390cabSriastradh
1244e390cabSriastradh /* are we reading registers for which a PG lock is necessary? */
1254e390cabSriastradh pm_pg_lock = (*pos >> 23) & 1;
1264e390cabSriastradh
1274e390cabSriastradh if (*pos & (1ULL << 62)) {
1284e390cabSriastradh se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24;
1294e390cabSriastradh sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34;
1304e390cabSriastradh instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44;
1314e390cabSriastradh
1324e390cabSriastradh if (se_bank == 0x3FF)
1334e390cabSriastradh se_bank = 0xFFFFFFFF;
1344e390cabSriastradh if (sh_bank == 0x3FF)
1354e390cabSriastradh sh_bank = 0xFFFFFFFF;
1364e390cabSriastradh if (instance_bank == 0x3FF)
1374e390cabSriastradh instance_bank = 0xFFFFFFFF;
1384e390cabSriastradh use_bank = true;
1394e390cabSriastradh } else if (*pos & (1ULL << 61)) {
1404e390cabSriastradh
1414e390cabSriastradh me = (*pos & GENMASK_ULL(33, 24)) >> 24;
1424e390cabSriastradh pipe = (*pos & GENMASK_ULL(43, 34)) >> 34;
1434e390cabSriastradh queue = (*pos & GENMASK_ULL(53, 44)) >> 44;
1444e390cabSriastradh vmid = (*pos & GENMASK_ULL(58, 54)) >> 54;
1454e390cabSriastradh
1464e390cabSriastradh use_ring = true;
1474e390cabSriastradh } else {
1484e390cabSriastradh use_bank = use_ring = false;
1494e390cabSriastradh }
1504e390cabSriastradh
1514e390cabSriastradh *pos &= (1UL << 22) - 1;
1524e390cabSriastradh
1534e390cabSriastradh r = pm_runtime_get_sync(adev->ddev->dev);
1544e390cabSriastradh if (r < 0)
1554e390cabSriastradh return r;
1564e390cabSriastradh
1574e390cabSriastradh if (use_bank) {
1584e390cabSriastradh if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
1594e390cabSriastradh (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines)) {
1604e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
1614e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
1624e390cabSriastradh return -EINVAL;
1634e390cabSriastradh }
1644e390cabSriastradh mutex_lock(&adev->grbm_idx_mutex);
1654e390cabSriastradh amdgpu_gfx_select_se_sh(adev, se_bank,
1664e390cabSriastradh sh_bank, instance_bank);
1674e390cabSriastradh } else if (use_ring) {
1684e390cabSriastradh mutex_lock(&adev->srbm_mutex);
1694e390cabSriastradh amdgpu_gfx_select_me_pipe_q(adev, me, pipe, queue, vmid);
1704e390cabSriastradh }
1714e390cabSriastradh
1724e390cabSriastradh if (pm_pg_lock)
1734e390cabSriastradh mutex_lock(&adev->pm.mutex);
1744e390cabSriastradh
1754e390cabSriastradh while (size) {
1764e390cabSriastradh uint32_t value;
1774e390cabSriastradh
1784e390cabSriastradh if (read) {
1794e390cabSriastradh value = RREG32(*pos >> 2);
1804e390cabSriastradh r = put_user(value, (uint32_t *)buf);
1814e390cabSriastradh } else {
1824e390cabSriastradh r = get_user(value, (uint32_t *)buf);
1834e390cabSriastradh if (!r)
1844e390cabSriastradh WREG32(*pos >> 2, value);
1854e390cabSriastradh }
1864e390cabSriastradh if (r) {
1874e390cabSriastradh result = r;
1884e390cabSriastradh goto end;
1894e390cabSriastradh }
1904e390cabSriastradh
1914e390cabSriastradh result += 4;
1924e390cabSriastradh buf += 4;
1934e390cabSriastradh *pos += 4;
1944e390cabSriastradh size -= 4;
1954e390cabSriastradh }
1964e390cabSriastradh
1974e390cabSriastradh end:
1984e390cabSriastradh if (use_bank) {
1994e390cabSriastradh amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
2004e390cabSriastradh mutex_unlock(&adev->grbm_idx_mutex);
2014e390cabSriastradh } else if (use_ring) {
2024e390cabSriastradh amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0);
2034e390cabSriastradh mutex_unlock(&adev->srbm_mutex);
2044e390cabSriastradh }
2054e390cabSriastradh
2064e390cabSriastradh if (pm_pg_lock)
2074e390cabSriastradh mutex_unlock(&adev->pm.mutex);
2084e390cabSriastradh
2094e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
2104e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
2114e390cabSriastradh
2124e390cabSriastradh return result;
2134e390cabSriastradh }
2144e390cabSriastradh
2154e390cabSriastradh /**
2164e390cabSriastradh * amdgpu_debugfs_regs_read - Callback for reading MMIO registers
2174e390cabSriastradh */
amdgpu_debugfs_regs_read(struct file * f,char __user * buf,size_t size,loff_t * pos)2184e390cabSriastradh static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
2194e390cabSriastradh size_t size, loff_t *pos)
2204e390cabSriastradh {
2214e390cabSriastradh return amdgpu_debugfs_process_reg_op(true, f, buf, size, pos);
2224e390cabSriastradh }
2234e390cabSriastradh
2244e390cabSriastradh /**
2254e390cabSriastradh * amdgpu_debugfs_regs_write - Callback for writing MMIO registers
2264e390cabSriastradh */
amdgpu_debugfs_regs_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)2274e390cabSriastradh static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
2284e390cabSriastradh size_t size, loff_t *pos)
2294e390cabSriastradh {
2304e390cabSriastradh return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos);
2314e390cabSriastradh }
2324e390cabSriastradh
2334e390cabSriastradh
2344e390cabSriastradh /**
2354e390cabSriastradh * amdgpu_debugfs_regs_pcie_read - Read from a PCIE register
2364e390cabSriastradh *
2374e390cabSriastradh * @f: open file handle
2384e390cabSriastradh * @buf: User buffer to store read data in
2394e390cabSriastradh * @size: Number of bytes to read
2404e390cabSriastradh * @pos: Offset to seek to
2414e390cabSriastradh *
2424e390cabSriastradh * The lower bits are the BYTE offset of the register to read. This
2434e390cabSriastradh * allows reading multiple registers in a single call and having
2444e390cabSriastradh * the returned size reflect that.
2454e390cabSriastradh */
amdgpu_debugfs_regs_pcie_read(struct file * f,char __user * buf,size_t size,loff_t * pos)2464e390cabSriastradh static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
2474e390cabSriastradh size_t size, loff_t *pos)
2484e390cabSriastradh {
2494e390cabSriastradh struct amdgpu_device *adev = file_inode(f)->i_private;
2504e390cabSriastradh ssize_t result = 0;
2514e390cabSriastradh int r;
2524e390cabSriastradh
2534e390cabSriastradh if (size & 0x3 || *pos & 0x3)
2544e390cabSriastradh return -EINVAL;
2554e390cabSriastradh
2564e390cabSriastradh r = pm_runtime_get_sync(adev->ddev->dev);
2574e390cabSriastradh if (r < 0)
2584e390cabSriastradh return r;
2594e390cabSriastradh
2604e390cabSriastradh while (size) {
2614e390cabSriastradh uint32_t value;
2624e390cabSriastradh
2634e390cabSriastradh value = RREG32_PCIE(*pos >> 2);
2644e390cabSriastradh r = put_user(value, (uint32_t *)buf);
2654e390cabSriastradh if (r) {
2664e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
2674e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
2684e390cabSriastradh return r;
2694e390cabSriastradh }
2704e390cabSriastradh
2714e390cabSriastradh result += 4;
2724e390cabSriastradh buf += 4;
2734e390cabSriastradh *pos += 4;
2744e390cabSriastradh size -= 4;
2754e390cabSriastradh }
2764e390cabSriastradh
2774e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
2784e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
2794e390cabSriastradh
2804e390cabSriastradh return result;
2814e390cabSriastradh }
2824e390cabSriastradh
2834e390cabSriastradh /**
2844e390cabSriastradh * amdgpu_debugfs_regs_pcie_write - Write to a PCIE register
2854e390cabSriastradh *
2864e390cabSriastradh * @f: open file handle
2874e390cabSriastradh * @buf: User buffer to write data from
2884e390cabSriastradh * @size: Number of bytes to write
2894e390cabSriastradh * @pos: Offset to seek to
2904e390cabSriastradh *
2914e390cabSriastradh * The lower bits are the BYTE offset of the register to write. This
2924e390cabSriastradh * allows writing multiple registers in a single call and having
2934e390cabSriastradh * the returned size reflect that.
2944e390cabSriastradh */
amdgpu_debugfs_regs_pcie_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)2954e390cabSriastradh static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user *buf,
2964e390cabSriastradh size_t size, loff_t *pos)
2974e390cabSriastradh {
2984e390cabSriastradh struct amdgpu_device *adev = file_inode(f)->i_private;
2994e390cabSriastradh ssize_t result = 0;
3004e390cabSriastradh int r;
3014e390cabSriastradh
3024e390cabSriastradh if (size & 0x3 || *pos & 0x3)
3034e390cabSriastradh return -EINVAL;
3044e390cabSriastradh
3054e390cabSriastradh r = pm_runtime_get_sync(adev->ddev->dev);
3064e390cabSriastradh if (r < 0)
3074e390cabSriastradh return r;
3084e390cabSriastradh
3094e390cabSriastradh while (size) {
3104e390cabSriastradh uint32_t value;
3114e390cabSriastradh
3124e390cabSriastradh r = get_user(value, (uint32_t *)buf);
3134e390cabSriastradh if (r) {
3144e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
3154e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
3164e390cabSriastradh return r;
3174e390cabSriastradh }
3184e390cabSriastradh
3194e390cabSriastradh WREG32_PCIE(*pos >> 2, value);
3204e390cabSriastradh
3214e390cabSriastradh result += 4;
3224e390cabSriastradh buf += 4;
3234e390cabSriastradh *pos += 4;
3244e390cabSriastradh size -= 4;
3254e390cabSriastradh }
3264e390cabSriastradh
3274e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
3284e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
3294e390cabSriastradh
3304e390cabSriastradh return result;
3314e390cabSriastradh }
3324e390cabSriastradh
3334e390cabSriastradh /**
3344e390cabSriastradh * amdgpu_debugfs_regs_didt_read - Read from a DIDT register
3354e390cabSriastradh *
3364e390cabSriastradh * @f: open file handle
3374e390cabSriastradh * @buf: User buffer to store read data in
3384e390cabSriastradh * @size: Number of bytes to read
3394e390cabSriastradh * @pos: Offset to seek to
3404e390cabSriastradh *
3414e390cabSriastradh * The lower bits are the BYTE offset of the register to read. This
3424e390cabSriastradh * allows reading multiple registers in a single call and having
3434e390cabSriastradh * the returned size reflect that.
3444e390cabSriastradh */
amdgpu_debugfs_regs_didt_read(struct file * f,char __user * buf,size_t size,loff_t * pos)3454e390cabSriastradh static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
3464e390cabSriastradh size_t size, loff_t *pos)
3474e390cabSriastradh {
3484e390cabSriastradh struct amdgpu_device *adev = file_inode(f)->i_private;
3494e390cabSriastradh ssize_t result = 0;
3504e390cabSriastradh int r;
3514e390cabSriastradh
3524e390cabSriastradh if (size & 0x3 || *pos & 0x3)
3534e390cabSriastradh return -EINVAL;
3544e390cabSriastradh
3554e390cabSriastradh r = pm_runtime_get_sync(adev->ddev->dev);
3564e390cabSriastradh if (r < 0)
3574e390cabSriastradh return r;
3584e390cabSriastradh
3594e390cabSriastradh while (size) {
3604e390cabSriastradh uint32_t value;
3614e390cabSriastradh
3624e390cabSriastradh value = RREG32_DIDT(*pos >> 2);
3634e390cabSriastradh r = put_user(value, (uint32_t *)buf);
3644e390cabSriastradh if (r) {
3654e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
3664e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
3674e390cabSriastradh return r;
3684e390cabSriastradh }
3694e390cabSriastradh
3704e390cabSriastradh result += 4;
3714e390cabSriastradh buf += 4;
3724e390cabSriastradh *pos += 4;
3734e390cabSriastradh size -= 4;
3744e390cabSriastradh }
3754e390cabSriastradh
3764e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
3774e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
3784e390cabSriastradh
3794e390cabSriastradh return result;
3804e390cabSriastradh }
3814e390cabSriastradh
3824e390cabSriastradh /**
3834e390cabSriastradh * amdgpu_debugfs_regs_didt_write - Write to a DIDT register
3844e390cabSriastradh *
3854e390cabSriastradh * @f: open file handle
3864e390cabSriastradh * @buf: User buffer to write data from
3874e390cabSriastradh * @size: Number of bytes to write
3884e390cabSriastradh * @pos: Offset to seek to
3894e390cabSriastradh *
3904e390cabSriastradh * The lower bits are the BYTE offset of the register to write. This
3914e390cabSriastradh * allows writing multiple registers in a single call and having
3924e390cabSriastradh * the returned size reflect that.
3934e390cabSriastradh */
amdgpu_debugfs_regs_didt_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)3944e390cabSriastradh static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user *buf,
3954e390cabSriastradh size_t size, loff_t *pos)
3964e390cabSriastradh {
3974e390cabSriastradh struct amdgpu_device *adev = file_inode(f)->i_private;
3984e390cabSriastradh ssize_t result = 0;
3994e390cabSriastradh int r;
4004e390cabSriastradh
4014e390cabSriastradh if (size & 0x3 || *pos & 0x3)
4024e390cabSriastradh return -EINVAL;
4034e390cabSriastradh
4044e390cabSriastradh r = pm_runtime_get_sync(adev->ddev->dev);
4054e390cabSriastradh if (r < 0)
4064e390cabSriastradh return r;
4074e390cabSriastradh
4084e390cabSriastradh while (size) {
4094e390cabSriastradh uint32_t value;
4104e390cabSriastradh
4114e390cabSriastradh r = get_user(value, (uint32_t *)buf);
4124e390cabSriastradh if (r) {
4134e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
4144e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
4154e390cabSriastradh return r;
4164e390cabSriastradh }
4174e390cabSriastradh
4184e390cabSriastradh WREG32_DIDT(*pos >> 2, value);
4194e390cabSriastradh
4204e390cabSriastradh result += 4;
4214e390cabSriastradh buf += 4;
4224e390cabSriastradh *pos += 4;
4234e390cabSriastradh size -= 4;
4244e390cabSriastradh }
4254e390cabSriastradh
4264e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
4274e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
4284e390cabSriastradh
4294e390cabSriastradh return result;
4304e390cabSriastradh }
4314e390cabSriastradh
4324e390cabSriastradh /**
4334e390cabSriastradh * amdgpu_debugfs_regs_smc_read - Read from a SMC register
4344e390cabSriastradh *
4354e390cabSriastradh * @f: open file handle
4364e390cabSriastradh * @buf: User buffer to store read data in
4374e390cabSriastradh * @size: Number of bytes to read
4384e390cabSriastradh * @pos: Offset to seek to
4394e390cabSriastradh *
4404e390cabSriastradh * The lower bits are the BYTE offset of the register to read. This
4414e390cabSriastradh * allows reading multiple registers in a single call and having
4424e390cabSriastradh * the returned size reflect that.
4434e390cabSriastradh */
amdgpu_debugfs_regs_smc_read(struct file * f,char __user * buf,size_t size,loff_t * pos)4444e390cabSriastradh static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
4454e390cabSriastradh size_t size, loff_t *pos)
4464e390cabSriastradh {
4474e390cabSriastradh struct amdgpu_device *adev = file_inode(f)->i_private;
4484e390cabSriastradh ssize_t result = 0;
4494e390cabSriastradh int r;
4504e390cabSriastradh
4514e390cabSriastradh if (size & 0x3 || *pos & 0x3)
4524e390cabSriastradh return -EINVAL;
4534e390cabSriastradh
4544e390cabSriastradh r = pm_runtime_get_sync(adev->ddev->dev);
4554e390cabSriastradh if (r < 0)
4564e390cabSriastradh return r;
4574e390cabSriastradh
4584e390cabSriastradh while (size) {
4594e390cabSriastradh uint32_t value;
4604e390cabSriastradh
4614e390cabSriastradh value = RREG32_SMC(*pos);
4624e390cabSriastradh r = put_user(value, (uint32_t *)buf);
4634e390cabSriastradh if (r) {
4644e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
4654e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
4664e390cabSriastradh return r;
4674e390cabSriastradh }
4684e390cabSriastradh
4694e390cabSriastradh result += 4;
4704e390cabSriastradh buf += 4;
4714e390cabSriastradh *pos += 4;
4724e390cabSriastradh size -= 4;
4734e390cabSriastradh }
4744e390cabSriastradh
4754e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
4764e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
4774e390cabSriastradh
4784e390cabSriastradh return result;
4794e390cabSriastradh }
4804e390cabSriastradh
4814e390cabSriastradh /**
4824e390cabSriastradh * amdgpu_debugfs_regs_smc_write - Write to a SMC register
4834e390cabSriastradh *
4844e390cabSriastradh * @f: open file handle
4854e390cabSriastradh * @buf: User buffer to write data from
4864e390cabSriastradh * @size: Number of bytes to write
4874e390cabSriastradh * @pos: Offset to seek to
4884e390cabSriastradh *
4894e390cabSriastradh * The lower bits are the BYTE offset of the register to write. This
4904e390cabSriastradh * allows writing multiple registers in a single call and having
4914e390cabSriastradh * the returned size reflect that.
4924e390cabSriastradh */
amdgpu_debugfs_regs_smc_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)4934e390cabSriastradh static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *buf,
4944e390cabSriastradh size_t size, loff_t *pos)
4954e390cabSriastradh {
4964e390cabSriastradh struct amdgpu_device *adev = file_inode(f)->i_private;
4974e390cabSriastradh ssize_t result = 0;
4984e390cabSriastradh int r;
4994e390cabSriastradh
5004e390cabSriastradh if (size & 0x3 || *pos & 0x3)
5014e390cabSriastradh return -EINVAL;
5024e390cabSriastradh
5034e390cabSriastradh r = pm_runtime_get_sync(adev->ddev->dev);
5044e390cabSriastradh if (r < 0)
5054e390cabSriastradh return r;
5064e390cabSriastradh
5074e390cabSriastradh while (size) {
5084e390cabSriastradh uint32_t value;
5094e390cabSriastradh
5104e390cabSriastradh r = get_user(value, (uint32_t *)buf);
5114e390cabSriastradh if (r) {
5124e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
5134e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
5144e390cabSriastradh return r;
5154e390cabSriastradh }
5164e390cabSriastradh
5174e390cabSriastradh WREG32_SMC(*pos, value);
5184e390cabSriastradh
5194e390cabSriastradh result += 4;
5204e390cabSriastradh buf += 4;
5214e390cabSriastradh *pos += 4;
5224e390cabSriastradh size -= 4;
5234e390cabSriastradh }
5244e390cabSriastradh
5254e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
5264e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
5274e390cabSriastradh
5284e390cabSriastradh return result;
5294e390cabSriastradh }
5304e390cabSriastradh
5314e390cabSriastradh /**
5324e390cabSriastradh * amdgpu_debugfs_gca_config_read - Read from gfx config data
5334e390cabSriastradh *
5344e390cabSriastradh * @f: open file handle
5354e390cabSriastradh * @buf: User buffer to store read data in
5364e390cabSriastradh * @size: Number of bytes to read
5374e390cabSriastradh * @pos: Offset to seek to
5384e390cabSriastradh *
5394e390cabSriastradh * This file is used to access configuration data in a somewhat
5404e390cabSriastradh * stable fashion. The format is a series of DWORDs with the first
5414e390cabSriastradh * indicating which revision it is. New content is appended to the
5424e390cabSriastradh * end so that older software can still read the data.
5434e390cabSriastradh */
5444e390cabSriastradh
amdgpu_debugfs_gca_config_read(struct file * f,char __user * buf,size_t size,loff_t * pos)5454e390cabSriastradh static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,
5464e390cabSriastradh size_t size, loff_t *pos)
5474e390cabSriastradh {
5484e390cabSriastradh struct amdgpu_device *adev = file_inode(f)->i_private;
5494e390cabSriastradh ssize_t result = 0;
5504e390cabSriastradh int r;
5514e390cabSriastradh uint32_t *config, no_regs = 0;
5524e390cabSriastradh
5534e390cabSriastradh if (size & 0x3 || *pos & 0x3)
5544e390cabSriastradh return -EINVAL;
5554e390cabSriastradh
5564e390cabSriastradh config = kmalloc_array(256, sizeof(*config), GFP_KERNEL);
5574e390cabSriastradh if (!config)
5584e390cabSriastradh return -ENOMEM;
5594e390cabSriastradh
5604e390cabSriastradh /* version, increment each time something is added */
5614e390cabSriastradh config[no_regs++] = 3;
5624e390cabSriastradh config[no_regs++] = adev->gfx.config.max_shader_engines;
5634e390cabSriastradh config[no_regs++] = adev->gfx.config.max_tile_pipes;
5644e390cabSriastradh config[no_regs++] = adev->gfx.config.max_cu_per_sh;
5654e390cabSriastradh config[no_regs++] = adev->gfx.config.max_sh_per_se;
5664e390cabSriastradh config[no_regs++] = adev->gfx.config.max_backends_per_se;
5674e390cabSriastradh config[no_regs++] = adev->gfx.config.max_texture_channel_caches;
5684e390cabSriastradh config[no_regs++] = adev->gfx.config.max_gprs;
5694e390cabSriastradh config[no_regs++] = adev->gfx.config.max_gs_threads;
5704e390cabSriastradh config[no_regs++] = adev->gfx.config.max_hw_contexts;
5714e390cabSriastradh config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_frontend;
5724e390cabSriastradh config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_backend;
5734e390cabSriastradh config[no_regs++] = adev->gfx.config.sc_hiz_tile_fifo_size;
5744e390cabSriastradh config[no_regs++] = adev->gfx.config.sc_earlyz_tile_fifo_size;
5754e390cabSriastradh config[no_regs++] = adev->gfx.config.num_tile_pipes;
5764e390cabSriastradh config[no_regs++] = adev->gfx.config.backend_enable_mask;
5774e390cabSriastradh config[no_regs++] = adev->gfx.config.mem_max_burst_length_bytes;
5784e390cabSriastradh config[no_regs++] = adev->gfx.config.mem_row_size_in_kb;
5794e390cabSriastradh config[no_regs++] = adev->gfx.config.shader_engine_tile_size;
5804e390cabSriastradh config[no_regs++] = adev->gfx.config.num_gpus;
5814e390cabSriastradh config[no_regs++] = adev->gfx.config.multi_gpu_tile_size;
5824e390cabSriastradh config[no_regs++] = adev->gfx.config.mc_arb_ramcfg;
5834e390cabSriastradh config[no_regs++] = adev->gfx.config.gb_addr_config;
5844e390cabSriastradh config[no_regs++] = adev->gfx.config.num_rbs;
5854e390cabSriastradh
5864e390cabSriastradh /* rev==1 */
5874e390cabSriastradh config[no_regs++] = adev->rev_id;
5884e390cabSriastradh config[no_regs++] = adev->pg_flags;
5894e390cabSriastradh config[no_regs++] = adev->cg_flags;
5904e390cabSriastradh
5914e390cabSriastradh /* rev==2 */
5924e390cabSriastradh config[no_regs++] = adev->family;
5934e390cabSriastradh config[no_regs++] = adev->external_rev_id;
5944e390cabSriastradh
5954e390cabSriastradh /* rev==3 */
5964e390cabSriastradh config[no_regs++] = adev->pdev->device;
5974e390cabSriastradh config[no_regs++] = adev->pdev->revision;
5984e390cabSriastradh config[no_regs++] = adev->pdev->subsystem_device;
5994e390cabSriastradh config[no_regs++] = adev->pdev->subsystem_vendor;
6004e390cabSriastradh
6014e390cabSriastradh while (size && (*pos < no_regs * 4)) {
6024e390cabSriastradh uint32_t value;
6034e390cabSriastradh
6044e390cabSriastradh value = config[*pos >> 2];
6054e390cabSriastradh r = put_user(value, (uint32_t *)buf);
6064e390cabSriastradh if (r) {
6074e390cabSriastradh kfree(config);
6084e390cabSriastradh return r;
6094e390cabSriastradh }
6104e390cabSriastradh
6114e390cabSriastradh result += 4;
6124e390cabSriastradh buf += 4;
6134e390cabSriastradh *pos += 4;
6144e390cabSriastradh size -= 4;
6154e390cabSriastradh }
6164e390cabSriastradh
6174e390cabSriastradh kfree(config);
6184e390cabSriastradh return result;
6194e390cabSriastradh }
6204e390cabSriastradh
6214e390cabSriastradh /**
6224e390cabSriastradh * amdgpu_debugfs_sensor_read - Read from the powerplay sensors
6234e390cabSriastradh *
6244e390cabSriastradh * @f: open file handle
6254e390cabSriastradh * @buf: User buffer to store read data in
6264e390cabSriastradh * @size: Number of bytes to read
6274e390cabSriastradh * @pos: Offset to seek to
6284e390cabSriastradh *
6294e390cabSriastradh * The offset is treated as the BYTE address of one of the sensors
6304e390cabSriastradh * enumerated in amd/include/kgd_pp_interface.h under the
6314e390cabSriastradh * 'amd_pp_sensors' enumeration. For instance to read the UVD VCLK
6324e390cabSriastradh * you would use the offset 3 * 4 = 12.
6334e390cabSriastradh */
amdgpu_debugfs_sensor_read(struct file * f,char __user * buf,size_t size,loff_t * pos)6344e390cabSriastradh static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
6354e390cabSriastradh size_t size, loff_t *pos)
6364e390cabSriastradh {
6374e390cabSriastradh struct amdgpu_device *adev = file_inode(f)->i_private;
6384e390cabSriastradh int idx, x, outsize, r, valuesize;
6394e390cabSriastradh uint32_t values[16];
6404e390cabSriastradh
6414e390cabSriastradh if (size & 3 || *pos & 0x3)
6424e390cabSriastradh return -EINVAL;
6434e390cabSriastradh
6444e390cabSriastradh if (!adev->pm.dpm_enabled)
6454e390cabSriastradh return -EINVAL;
6464e390cabSriastradh
6474e390cabSriastradh /* convert offset to sensor number */
6484e390cabSriastradh idx = *pos >> 2;
6494e390cabSriastradh
6504e390cabSriastradh valuesize = sizeof(values);
6514e390cabSriastradh
6524e390cabSriastradh r = pm_runtime_get_sync(adev->ddev->dev);
6534e390cabSriastradh if (r < 0)
6544e390cabSriastradh return r;
6554e390cabSriastradh
6564e390cabSriastradh r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize);
6574e390cabSriastradh
6584e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
6594e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
6604e390cabSriastradh
6614e390cabSriastradh if (r)
6624e390cabSriastradh return r;
6634e390cabSriastradh
6644e390cabSriastradh if (size > valuesize)
6654e390cabSriastradh return -EINVAL;
6664e390cabSriastradh
6674e390cabSriastradh outsize = 0;
6684e390cabSriastradh x = 0;
6694e390cabSriastradh if (!r) {
6704e390cabSriastradh while (size) {
6714e390cabSriastradh r = put_user(values[x++], (int32_t *)buf);
6724e390cabSriastradh buf += 4;
6734e390cabSriastradh size -= 4;
6744e390cabSriastradh outsize += 4;
6754e390cabSriastradh }
6764e390cabSriastradh }
6774e390cabSriastradh
6784e390cabSriastradh return !r ? outsize : r;
6794e390cabSriastradh }
6804e390cabSriastradh
6814e390cabSriastradh /** amdgpu_debugfs_wave_read - Read WAVE STATUS data
6824e390cabSriastradh *
6834e390cabSriastradh * @f: open file handle
6844e390cabSriastradh * @buf: User buffer to store read data in
6854e390cabSriastradh * @size: Number of bytes to read
6864e390cabSriastradh * @pos: Offset to seek to
6874e390cabSriastradh *
6884e390cabSriastradh * The offset being sought changes which wave that the status data
6894e390cabSriastradh * will be returned for. The bits are used as follows:
6904e390cabSriastradh *
6914e390cabSriastradh * Bits 0..6: Byte offset into data
6924e390cabSriastradh * Bits 7..14: SE selector
6934e390cabSriastradh * Bits 15..22: SH/SA selector
6944e390cabSriastradh * Bits 23..30: CU/{WGP+SIMD} selector
6954e390cabSriastradh * Bits 31..36: WAVE ID selector
6964e390cabSriastradh * Bits 37..44: SIMD ID selector
6974e390cabSriastradh *
6984e390cabSriastradh * The returned data begins with one DWORD of version information
6994e390cabSriastradh * Followed by WAVE STATUS registers relevant to the GFX IP version
7004e390cabSriastradh * being used. See gfx_v8_0_read_wave_data() for an example output.
7014e390cabSriastradh */
amdgpu_debugfs_wave_read(struct file * f,char __user * buf,size_t size,loff_t * pos)7024e390cabSriastradh static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
7034e390cabSriastradh size_t size, loff_t *pos)
7044e390cabSriastradh {
7054e390cabSriastradh struct amdgpu_device *adev = f->f_inode->i_private;
7064e390cabSriastradh int r, x;
7074e390cabSriastradh ssize_t result=0;
7084e390cabSriastradh uint32_t offset, se, sh, cu, wave, simd, data[32];
7094e390cabSriastradh
7104e390cabSriastradh if (size & 3 || *pos & 3)
7114e390cabSriastradh return -EINVAL;
7124e390cabSriastradh
7134e390cabSriastradh /* decode offset */
7144e390cabSriastradh offset = (*pos & GENMASK_ULL(6, 0));
7154e390cabSriastradh se = (*pos & GENMASK_ULL(14, 7)) >> 7;
7164e390cabSriastradh sh = (*pos & GENMASK_ULL(22, 15)) >> 15;
7174e390cabSriastradh cu = (*pos & GENMASK_ULL(30, 23)) >> 23;
7184e390cabSriastradh wave = (*pos & GENMASK_ULL(36, 31)) >> 31;
7194e390cabSriastradh simd = (*pos & GENMASK_ULL(44, 37)) >> 37;
7204e390cabSriastradh
7214e390cabSriastradh r = pm_runtime_get_sync(adev->ddev->dev);
7224e390cabSriastradh if (r < 0)
7234e390cabSriastradh return r;
7244e390cabSriastradh
7254e390cabSriastradh /* switch to the specific se/sh/cu */
7264e390cabSriastradh mutex_lock(&adev->grbm_idx_mutex);
7274e390cabSriastradh amdgpu_gfx_select_se_sh(adev, se, sh, cu);
7284e390cabSriastradh
7294e390cabSriastradh x = 0;
7304e390cabSriastradh if (adev->gfx.funcs->read_wave_data)
7314e390cabSriastradh adev->gfx.funcs->read_wave_data(adev, simd, wave, data, &x);
7324e390cabSriastradh
7334e390cabSriastradh amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
7344e390cabSriastradh mutex_unlock(&adev->grbm_idx_mutex);
7354e390cabSriastradh
7364e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
7374e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
7384e390cabSriastradh
7394e390cabSriastradh if (!x)
7404e390cabSriastradh return -EINVAL;
7414e390cabSriastradh
7424e390cabSriastradh while (size && (offset < x * 4)) {
7434e390cabSriastradh uint32_t value;
7444e390cabSriastradh
7454e390cabSriastradh value = data[offset >> 2];
7464e390cabSriastradh r = put_user(value, (uint32_t *)buf);
7474e390cabSriastradh if (r)
7484e390cabSriastradh return r;
7494e390cabSriastradh
7504e390cabSriastradh result += 4;
7514e390cabSriastradh buf += 4;
7524e390cabSriastradh offset += 4;
7534e390cabSriastradh size -= 4;
7544e390cabSriastradh }
7554e390cabSriastradh
7564e390cabSriastradh return result;
7574e390cabSriastradh }
7584e390cabSriastradh
7594e390cabSriastradh /** amdgpu_debugfs_gpr_read - Read wave gprs
7604e390cabSriastradh *
7614e390cabSriastradh * @f: open file handle
7624e390cabSriastradh * @buf: User buffer to store read data in
7634e390cabSriastradh * @size: Number of bytes to read
7644e390cabSriastradh * @pos: Offset to seek to
7654e390cabSriastradh *
7664e390cabSriastradh * The offset being sought changes which wave that the status data
7674e390cabSriastradh * will be returned for. The bits are used as follows:
7684e390cabSriastradh *
7694e390cabSriastradh * Bits 0..11: Byte offset into data
7704e390cabSriastradh * Bits 12..19: SE selector
7714e390cabSriastradh * Bits 20..27: SH/SA selector
7724e390cabSriastradh * Bits 28..35: CU/{WGP+SIMD} selector
7734e390cabSriastradh * Bits 36..43: WAVE ID selector
7744e390cabSriastradh * Bits 37..44: SIMD ID selector
7754e390cabSriastradh * Bits 52..59: Thread selector
7764e390cabSriastradh * Bits 60..61: Bank selector (VGPR=0,SGPR=1)
7774e390cabSriastradh *
7784e390cabSriastradh * The return data comes from the SGPR or VGPR register bank for
7794e390cabSriastradh * the selected operational unit.
7804e390cabSriastradh */
amdgpu_debugfs_gpr_read(struct file * f,char __user * buf,size_t size,loff_t * pos)7814e390cabSriastradh static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
7824e390cabSriastradh size_t size, loff_t *pos)
7834e390cabSriastradh {
7844e390cabSriastradh struct amdgpu_device *adev = f->f_inode->i_private;
7854e390cabSriastradh int r;
7864e390cabSriastradh ssize_t result = 0;
7874e390cabSriastradh uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data;
7884e390cabSriastradh
7894e390cabSriastradh if (size & 3 || *pos & 3)
7904e390cabSriastradh return -EINVAL;
7914e390cabSriastradh
7924e390cabSriastradh /* decode offset */
7934e390cabSriastradh offset = *pos & GENMASK_ULL(11, 0);
7944e390cabSriastradh se = (*pos & GENMASK_ULL(19, 12)) >> 12;
7954e390cabSriastradh sh = (*pos & GENMASK_ULL(27, 20)) >> 20;
7964e390cabSriastradh cu = (*pos & GENMASK_ULL(35, 28)) >> 28;
7974e390cabSriastradh wave = (*pos & GENMASK_ULL(43, 36)) >> 36;
7984e390cabSriastradh simd = (*pos & GENMASK_ULL(51, 44)) >> 44;
7994e390cabSriastradh thread = (*pos & GENMASK_ULL(59, 52)) >> 52;
8004e390cabSriastradh bank = (*pos & GENMASK_ULL(61, 60)) >> 60;
8014e390cabSriastradh
8024e390cabSriastradh data = kcalloc(1024, sizeof(*data), GFP_KERNEL);
8034e390cabSriastradh if (!data)
8044e390cabSriastradh return -ENOMEM;
8054e390cabSriastradh
8064e390cabSriastradh r = pm_runtime_get_sync(adev->ddev->dev);
8074e390cabSriastradh if (r < 0)
8084e390cabSriastradh return r;
8094e390cabSriastradh
8104e390cabSriastradh /* switch to the specific se/sh/cu */
8114e390cabSriastradh mutex_lock(&adev->grbm_idx_mutex);
8124e390cabSriastradh amdgpu_gfx_select_se_sh(adev, se, sh, cu);
8134e390cabSriastradh
8144e390cabSriastradh if (bank == 0) {
8154e390cabSriastradh if (adev->gfx.funcs->read_wave_vgprs)
8164e390cabSriastradh adev->gfx.funcs->read_wave_vgprs(adev, simd, wave, thread, offset, size>>2, data);
8174e390cabSriastradh } else {
8184e390cabSriastradh if (adev->gfx.funcs->read_wave_sgprs)
8194e390cabSriastradh adev->gfx.funcs->read_wave_sgprs(adev, simd, wave, offset, size>>2, data);
8204e390cabSriastradh }
8214e390cabSriastradh
8224e390cabSriastradh amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
8234e390cabSriastradh mutex_unlock(&adev->grbm_idx_mutex);
8244e390cabSriastradh
8254e390cabSriastradh pm_runtime_mark_last_busy(adev->ddev->dev);
8264e390cabSriastradh pm_runtime_put_autosuspend(adev->ddev->dev);
8274e390cabSriastradh
8284e390cabSriastradh while (size) {
8294e390cabSriastradh uint32_t value;
8304e390cabSriastradh
8314e390cabSriastradh value = data[offset++];
8324e390cabSriastradh r = put_user(value, (uint32_t *)buf);
8334e390cabSriastradh if (r) {
8344e390cabSriastradh result = r;
8354e390cabSriastradh goto err;
8364e390cabSriastradh }
8374e390cabSriastradh
8384e390cabSriastradh result += 4;
8394e390cabSriastradh buf += 4;
8404e390cabSriastradh size -= 4;
8414e390cabSriastradh }
8424e390cabSriastradh
8434e390cabSriastradh err:
8444e390cabSriastradh kfree(data);
8454e390cabSriastradh return result;
8464e390cabSriastradh }
8474e390cabSriastradh
8484e390cabSriastradh static const struct file_operations amdgpu_debugfs_regs_fops = {
8494e390cabSriastradh .owner = THIS_MODULE,
8504e390cabSriastradh .read = amdgpu_debugfs_regs_read,
8514e390cabSriastradh .write = amdgpu_debugfs_regs_write,
8524e390cabSriastradh .llseek = default_llseek
8534e390cabSriastradh };
8544e390cabSriastradh static const struct file_operations amdgpu_debugfs_regs_didt_fops = {
8554e390cabSriastradh .owner = THIS_MODULE,
8564e390cabSriastradh .read = amdgpu_debugfs_regs_didt_read,
8574e390cabSriastradh .write = amdgpu_debugfs_regs_didt_write,
8584e390cabSriastradh .llseek = default_llseek
8594e390cabSriastradh };
8604e390cabSriastradh static const struct file_operations amdgpu_debugfs_regs_pcie_fops = {
8614e390cabSriastradh .owner = THIS_MODULE,
8624e390cabSriastradh .read = amdgpu_debugfs_regs_pcie_read,
8634e390cabSriastradh .write = amdgpu_debugfs_regs_pcie_write,
8644e390cabSriastradh .llseek = default_llseek
8654e390cabSriastradh };
8664e390cabSriastradh static const struct file_operations amdgpu_debugfs_regs_smc_fops = {
8674e390cabSriastradh .owner = THIS_MODULE,
8684e390cabSriastradh .read = amdgpu_debugfs_regs_smc_read,
8694e390cabSriastradh .write = amdgpu_debugfs_regs_smc_write,
8704e390cabSriastradh .llseek = default_llseek
8714e390cabSriastradh };
8724e390cabSriastradh
8734e390cabSriastradh static const struct file_operations amdgpu_debugfs_gca_config_fops = {
8744e390cabSriastradh .owner = THIS_MODULE,
8754e390cabSriastradh .read = amdgpu_debugfs_gca_config_read,
8764e390cabSriastradh .llseek = default_llseek
8774e390cabSriastradh };
8784e390cabSriastradh
8794e390cabSriastradh static const struct file_operations amdgpu_debugfs_sensors_fops = {
8804e390cabSriastradh .owner = THIS_MODULE,
8814e390cabSriastradh .read = amdgpu_debugfs_sensor_read,
8824e390cabSriastradh .llseek = default_llseek
8834e390cabSriastradh };
8844e390cabSriastradh
8854e390cabSriastradh static const struct file_operations amdgpu_debugfs_wave_fops = {
8864e390cabSriastradh .owner = THIS_MODULE,
8874e390cabSriastradh .read = amdgpu_debugfs_wave_read,
8884e390cabSriastradh .llseek = default_llseek
8894e390cabSriastradh };
8904e390cabSriastradh static const struct file_operations amdgpu_debugfs_gpr_fops = {
8914e390cabSriastradh .owner = THIS_MODULE,
8924e390cabSriastradh .read = amdgpu_debugfs_gpr_read,
8934e390cabSriastradh .llseek = default_llseek
8944e390cabSriastradh };
8954e390cabSriastradh
8964e390cabSriastradh static const struct file_operations *debugfs_regs[] = {
8974e390cabSriastradh &amdgpu_debugfs_regs_fops,
8984e390cabSriastradh &amdgpu_debugfs_regs_didt_fops,
8994e390cabSriastradh &amdgpu_debugfs_regs_pcie_fops,
9004e390cabSriastradh &amdgpu_debugfs_regs_smc_fops,
9014e390cabSriastradh &amdgpu_debugfs_gca_config_fops,
9024e390cabSriastradh &amdgpu_debugfs_sensors_fops,
9034e390cabSriastradh &amdgpu_debugfs_wave_fops,
9044e390cabSriastradh &amdgpu_debugfs_gpr_fops,
9054e390cabSriastradh };
9064e390cabSriastradh
9074e390cabSriastradh static const char *debugfs_regs_names[] = {
9084e390cabSriastradh "amdgpu_regs",
9094e390cabSriastradh "amdgpu_regs_didt",
9104e390cabSriastradh "amdgpu_regs_pcie",
9114e390cabSriastradh "amdgpu_regs_smc",
9124e390cabSriastradh "amdgpu_gca_config",
9134e390cabSriastradh "amdgpu_sensors",
9144e390cabSriastradh "amdgpu_wave",
9154e390cabSriastradh "amdgpu_gpr",
9164e390cabSriastradh };
9174e390cabSriastradh
9184e390cabSriastradh /**
9194e390cabSriastradh * amdgpu_debugfs_regs_init - Initialize debugfs entries that provide
9204e390cabSriastradh * register access.
9214e390cabSriastradh *
9224e390cabSriastradh * @adev: The device to attach the debugfs entries to
9234e390cabSriastradh */
amdgpu_debugfs_regs_init(struct amdgpu_device * adev)9244e390cabSriastradh int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)
9254e390cabSriastradh {
9264e390cabSriastradh struct drm_minor *minor = adev->ddev->primary;
9274e390cabSriastradh struct dentry *ent, *root = minor->debugfs_root;
9284e390cabSriastradh unsigned int i;
9294e390cabSriastradh
9304e390cabSriastradh for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) {
9314e390cabSriastradh ent = debugfs_create_file(debugfs_regs_names[i],
9324e390cabSriastradh S_IFREG | S_IRUGO, root,
9334e390cabSriastradh adev, debugfs_regs[i]);
9344e390cabSriastradh if (!i && !IS_ERR_OR_NULL(ent))
9354e390cabSriastradh i_size_write(ent->d_inode, adev->rmmio_size);
9364e390cabSriastradh adev->debugfs_regs[i] = ent;
9374e390cabSriastradh }
9384e390cabSriastradh
9394e390cabSriastradh return 0;
9404e390cabSriastradh }
9414e390cabSriastradh
amdgpu_debugfs_regs_cleanup(struct amdgpu_device * adev)9424e390cabSriastradh void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev)
9434e390cabSriastradh {
9444e390cabSriastradh unsigned i;
9454e390cabSriastradh
9464e390cabSriastradh for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) {
9474e390cabSriastradh if (adev->debugfs_regs[i]) {
9484e390cabSriastradh debugfs_remove(adev->debugfs_regs[i]);
9494e390cabSriastradh adev->debugfs_regs[i] = NULL;
9504e390cabSriastradh }
9514e390cabSriastradh }
9524e390cabSriastradh }
9534e390cabSriastradh
amdgpu_debugfs_test_ib(struct seq_file * m,void * data)9544e390cabSriastradh static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data)
9554e390cabSriastradh {
9564e390cabSriastradh struct drm_info_node *node = (struct drm_info_node *) m->private;
9574e390cabSriastradh struct drm_device *dev = node->minor->dev;
9584e390cabSriastradh struct amdgpu_device *adev = dev->dev_private;
9594e390cabSriastradh int r = 0, i;
9604e390cabSriastradh
9614e390cabSriastradh r = pm_runtime_get_sync(dev->dev);
9624e390cabSriastradh if (r < 0)
9634e390cabSriastradh return r;
9644e390cabSriastradh
9654e390cabSriastradh /* Avoid accidently unparking the sched thread during GPU reset */
9664e390cabSriastradh mutex_lock(&adev->lock_reset);
9674e390cabSriastradh
9684e390cabSriastradh /* hold on the scheduler */
9694e390cabSriastradh for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
9704e390cabSriastradh struct amdgpu_ring *ring = adev->rings[i];
9714e390cabSriastradh
9724e390cabSriastradh if (!ring || !ring->sched.thread)
9734e390cabSriastradh continue;
9744e390cabSriastradh kthread_park(ring->sched.thread);
9754e390cabSriastradh }
9764e390cabSriastradh
9774e390cabSriastradh seq_printf(m, "run ib test:\n");
9784e390cabSriastradh r = amdgpu_ib_ring_tests(adev);
9794e390cabSriastradh if (r)
9804e390cabSriastradh seq_printf(m, "ib ring tests failed (%d).\n", r);
9814e390cabSriastradh else
9824e390cabSriastradh seq_printf(m, "ib ring tests passed.\n");
9834e390cabSriastradh
9844e390cabSriastradh /* go on the scheduler */
9854e390cabSriastradh for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
9864e390cabSriastradh struct amdgpu_ring *ring = adev->rings[i];
9874e390cabSriastradh
9884e390cabSriastradh if (!ring || !ring->sched.thread)
9894e390cabSriastradh continue;
9904e390cabSriastradh kthread_unpark(ring->sched.thread);
9914e390cabSriastradh }
9924e390cabSriastradh
9934e390cabSriastradh mutex_unlock(&adev->lock_reset);
9944e390cabSriastradh
9954e390cabSriastradh pm_runtime_mark_last_busy(dev->dev);
9964e390cabSriastradh pm_runtime_put_autosuspend(dev->dev);
9974e390cabSriastradh
9984e390cabSriastradh return 0;
9994e390cabSriastradh }
10004e390cabSriastradh
amdgpu_debugfs_get_vbios_dump(struct seq_file * m,void * data)10014e390cabSriastradh static int amdgpu_debugfs_get_vbios_dump(struct seq_file *m, void *data)
10024e390cabSriastradh {
10034e390cabSriastradh struct drm_info_node *node = (struct drm_info_node *) m->private;
10044e390cabSriastradh struct drm_device *dev = node->minor->dev;
10054e390cabSriastradh struct amdgpu_device *adev = dev->dev_private;
10064e390cabSriastradh
10074e390cabSriastradh seq_write(m, adev->bios, adev->bios_size);
10084e390cabSriastradh return 0;
10094e390cabSriastradh }
10104e390cabSriastradh
amdgpu_debugfs_evict_vram(struct seq_file * m,void * data)10114e390cabSriastradh static int amdgpu_debugfs_evict_vram(struct seq_file *m, void *data)
10124e390cabSriastradh {
10134e390cabSriastradh struct drm_info_node *node = (struct drm_info_node *)m->private;
10144e390cabSriastradh struct drm_device *dev = node->minor->dev;
10154e390cabSriastradh struct amdgpu_device *adev = dev->dev_private;
10164e390cabSriastradh int r;
10174e390cabSriastradh
10184e390cabSriastradh r = pm_runtime_get_sync(dev->dev);
10194e390cabSriastradh if (r < 0)
10204e390cabSriastradh return r;
10214e390cabSriastradh
10224e390cabSriastradh seq_printf(m, "(%d)\n", amdgpu_bo_evict_vram(adev));
10234e390cabSriastradh
10244e390cabSriastradh pm_runtime_mark_last_busy(dev->dev);
10254e390cabSriastradh pm_runtime_put_autosuspend(dev->dev);
10264e390cabSriastradh
10274e390cabSriastradh return 0;
10284e390cabSriastradh }
10294e390cabSriastradh
amdgpu_debugfs_evict_gtt(struct seq_file * m,void * data)10304e390cabSriastradh static int amdgpu_debugfs_evict_gtt(struct seq_file *m, void *data)
10314e390cabSriastradh {
10324e390cabSriastradh struct drm_info_node *node = (struct drm_info_node *)m->private;
10334e390cabSriastradh struct drm_device *dev = node->minor->dev;
10344e390cabSriastradh struct amdgpu_device *adev = dev->dev_private;
10354e390cabSriastradh int r;
10364e390cabSriastradh
10374e390cabSriastradh r = pm_runtime_get_sync(dev->dev);
10384e390cabSriastradh if (r < 0)
10394e390cabSriastradh return r;
10404e390cabSriastradh
10414e390cabSriastradh seq_printf(m, "(%d)\n", ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_TT));
10424e390cabSriastradh
10434e390cabSriastradh pm_runtime_mark_last_busy(dev->dev);
10444e390cabSriastradh pm_runtime_put_autosuspend(dev->dev);
10454e390cabSriastradh
10464e390cabSriastradh return 0;
10474e390cabSriastradh }
10484e390cabSriastradh
10494e390cabSriastradh static const struct drm_info_list amdgpu_debugfs_list[] = {
10504e390cabSriastradh {"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump},
10514e390cabSriastradh {"amdgpu_test_ib", &amdgpu_debugfs_test_ib},
10524e390cabSriastradh {"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram},
10534e390cabSriastradh {"amdgpu_evict_gtt", &amdgpu_debugfs_evict_gtt},
10544e390cabSriastradh };
10554e390cabSriastradh
amdgpu_ib_preempt_fences_swap(struct amdgpu_ring * ring,struct dma_fence ** fences)10564e390cabSriastradh static void amdgpu_ib_preempt_fences_swap(struct amdgpu_ring *ring,
10574e390cabSriastradh struct dma_fence **fences)
10584e390cabSriastradh {
10594e390cabSriastradh struct amdgpu_fence_driver *drv = &ring->fence_drv;
10604e390cabSriastradh uint32_t sync_seq, last_seq;
10614e390cabSriastradh
10624e390cabSriastradh last_seq = atomic_read(&ring->fence_drv.last_seq);
10634e390cabSriastradh sync_seq = ring->fence_drv.sync_seq;
10644e390cabSriastradh
10654e390cabSriastradh last_seq &= drv->num_fences_mask;
10664e390cabSriastradh sync_seq &= drv->num_fences_mask;
10674e390cabSriastradh
10684e390cabSriastradh do {
10694e390cabSriastradh struct dma_fence *fence, **ptr;
10704e390cabSriastradh
10714e390cabSriastradh ++last_seq;
10724e390cabSriastradh last_seq &= drv->num_fences_mask;
10734e390cabSriastradh ptr = &drv->fences[last_seq];
10744e390cabSriastradh
10754e390cabSriastradh fence = rcu_dereference_protected(*ptr, 1);
10764e390cabSriastradh RCU_INIT_POINTER(*ptr, NULL);
10774e390cabSriastradh
10784e390cabSriastradh if (!fence)
10794e390cabSriastradh continue;
10804e390cabSriastradh
10814e390cabSriastradh fences[last_seq] = fence;
10824e390cabSriastradh
10834e390cabSriastradh } while (last_seq != sync_seq);
10844e390cabSriastradh }
10854e390cabSriastradh
amdgpu_ib_preempt_signal_fences(struct dma_fence ** fences,int length)10864e390cabSriastradh static void amdgpu_ib_preempt_signal_fences(struct dma_fence **fences,
10874e390cabSriastradh int length)
10884e390cabSriastradh {
10894e390cabSriastradh int i;
10904e390cabSriastradh struct dma_fence *fence;
10914e390cabSriastradh
10924e390cabSriastradh for (i = 0; i < length; i++) {
10934e390cabSriastradh fence = fences[i];
10944e390cabSriastradh if (!fence)
10954e390cabSriastradh continue;
10964e390cabSriastradh dma_fence_signal(fence);
10974e390cabSriastradh dma_fence_put(fence);
10984e390cabSriastradh }
10994e390cabSriastradh }
11004e390cabSriastradh
amdgpu_ib_preempt_job_recovery(struct drm_gpu_scheduler * sched)11014e390cabSriastradh static void amdgpu_ib_preempt_job_recovery(struct drm_gpu_scheduler *sched)
11024e390cabSriastradh {
11034e390cabSriastradh struct drm_sched_job *s_job;
11044e390cabSriastradh struct dma_fence *fence;
11054e390cabSriastradh
11064e390cabSriastradh spin_lock(&sched->job_list_lock);
11074e390cabSriastradh list_for_each_entry(s_job, &sched->ring_mirror_list, node) {
11084e390cabSriastradh fence = sched->ops->run_job(s_job);
11094e390cabSriastradh dma_fence_put(fence);
11104e390cabSriastradh }
11114e390cabSriastradh spin_unlock(&sched->job_list_lock);
11124e390cabSriastradh }
11134e390cabSriastradh
amdgpu_ib_preempt_mark_partial_job(struct amdgpu_ring * ring)11144e390cabSriastradh static void amdgpu_ib_preempt_mark_partial_job(struct amdgpu_ring *ring)
11154e390cabSriastradh {
11164e390cabSriastradh struct amdgpu_job *job;
11174e390cabSriastradh struct drm_sched_job *s_job;
11184e390cabSriastradh uint32_t preempt_seq;
11194e390cabSriastradh struct dma_fence *fence, **ptr;
11204e390cabSriastradh struct amdgpu_fence_driver *drv = &ring->fence_drv;
11214e390cabSriastradh struct drm_gpu_scheduler *sched = &ring->sched;
11224e390cabSriastradh
11234e390cabSriastradh if (ring->funcs->type != AMDGPU_RING_TYPE_GFX)
11244e390cabSriastradh return;
11254e390cabSriastradh
11264e390cabSriastradh preempt_seq = le32_to_cpu(*(drv->cpu_addr + 2));
11274e390cabSriastradh if (preempt_seq <= atomic_read(&drv->last_seq))
11284e390cabSriastradh return;
11294e390cabSriastradh
11304e390cabSriastradh preempt_seq &= drv->num_fences_mask;
11314e390cabSriastradh ptr = &drv->fences[preempt_seq];
11324e390cabSriastradh fence = rcu_dereference_protected(*ptr, 1);
11334e390cabSriastradh
11344e390cabSriastradh spin_lock(&sched->job_list_lock);
11354e390cabSriastradh list_for_each_entry(s_job, &sched->ring_mirror_list, node) {
11364e390cabSriastradh job = to_amdgpu_job(s_job);
11374e390cabSriastradh if (job->fence == fence)
11384e390cabSriastradh /* mark the job as preempted */
11394e390cabSriastradh job->preemption_status |= AMDGPU_IB_PREEMPTED;
11404e390cabSriastradh }
11414e390cabSriastradh spin_unlock(&sched->job_list_lock);
11424e390cabSriastradh }
11434e390cabSriastradh
amdgpu_debugfs_ib_preempt(void * data,u64 val)11444e390cabSriastradh static int amdgpu_debugfs_ib_preempt(void *data, u64 val)
11454e390cabSriastradh {
11464e390cabSriastradh int r, resched, length;
11474e390cabSriastradh struct amdgpu_ring *ring;
11484e390cabSriastradh struct dma_fence **fences = NULL;
11494e390cabSriastradh struct amdgpu_device *adev = (struct amdgpu_device *)data;
11504e390cabSriastradh
11514e390cabSriastradh if (val >= AMDGPU_MAX_RINGS)
11524e390cabSriastradh return -EINVAL;
11534e390cabSriastradh
11544e390cabSriastradh ring = adev->rings[val];
11554e390cabSriastradh
11564e390cabSriastradh if (!ring || !ring->funcs->preempt_ib || !ring->sched.thread)
11574e390cabSriastradh return -EINVAL;
11584e390cabSriastradh
11594e390cabSriastradh /* the last preemption failed */
11604e390cabSriastradh if (ring->trail_seq != le32_to_cpu(*ring->trail_fence_cpu_addr))
11614e390cabSriastradh return -EBUSY;
11624e390cabSriastradh
11634e390cabSriastradh length = ring->fence_drv.num_fences_mask + 1;
11644e390cabSriastradh fences = kcalloc(length, sizeof(void *), GFP_KERNEL);
11654e390cabSriastradh if (!fences)
11664e390cabSriastradh return -ENOMEM;
11674e390cabSriastradh
11684e390cabSriastradh /* Avoid accidently unparking the sched thread during GPU reset */
11694e390cabSriastradh mutex_lock(&adev->lock_reset);
11704e390cabSriastradh
11714e390cabSriastradh /* stop the scheduler */
11724e390cabSriastradh kthread_park(ring->sched.thread);
11734e390cabSriastradh
11744e390cabSriastradh resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
11754e390cabSriastradh
11764e390cabSriastradh /* preempt the IB */
11774e390cabSriastradh r = amdgpu_ring_preempt_ib(ring);
11784e390cabSriastradh if (r) {
11794e390cabSriastradh DRM_WARN("failed to preempt ring %d\n", ring->idx);
11804e390cabSriastradh goto failure;
11814e390cabSriastradh }
11824e390cabSriastradh
11834e390cabSriastradh amdgpu_fence_process(ring);
11844e390cabSriastradh
11854e390cabSriastradh if (atomic_read(&ring->fence_drv.last_seq) !=
11864e390cabSriastradh ring->fence_drv.sync_seq) {
11874e390cabSriastradh DRM_INFO("ring %d was preempted\n", ring->idx);
11884e390cabSriastradh
11894e390cabSriastradh amdgpu_ib_preempt_mark_partial_job(ring);
11904e390cabSriastradh
11914e390cabSriastradh /* swap out the old fences */
11924e390cabSriastradh amdgpu_ib_preempt_fences_swap(ring, fences);
11934e390cabSriastradh
11944e390cabSriastradh amdgpu_fence_driver_force_completion(ring);
11954e390cabSriastradh
11964e390cabSriastradh /* resubmit unfinished jobs */
11974e390cabSriastradh amdgpu_ib_preempt_job_recovery(&ring->sched);
11984e390cabSriastradh
11994e390cabSriastradh /* wait for jobs finished */
12004e390cabSriastradh amdgpu_fence_wait_empty(ring);
12014e390cabSriastradh
12024e390cabSriastradh /* signal the old fences */
12034e390cabSriastradh amdgpu_ib_preempt_signal_fences(fences, length);
12044e390cabSriastradh }
12054e390cabSriastradh
12064e390cabSriastradh failure:
12074e390cabSriastradh /* restart the scheduler */
12084e390cabSriastradh kthread_unpark(ring->sched.thread);
12094e390cabSriastradh
12104e390cabSriastradh mutex_unlock(&adev->lock_reset);
12114e390cabSriastradh
12124e390cabSriastradh ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched);
12134e390cabSriastradh
12144e390cabSriastradh kfree(fences);
12154e390cabSriastradh
12164e390cabSriastradh return 0;
12174e390cabSriastradh }
12184e390cabSriastradh
12194e390cabSriastradh DEFINE_SIMPLE_ATTRIBUTE(fops_ib_preempt, NULL,
12204e390cabSriastradh amdgpu_debugfs_ib_preempt, "%llu\n");
12214e390cabSriastradh
amdgpu_debugfs_init(struct amdgpu_device * adev)12224e390cabSriastradh int amdgpu_debugfs_init(struct amdgpu_device *adev)
12234e390cabSriastradh {
12244e390cabSriastradh adev->debugfs_preempt =
12254e390cabSriastradh debugfs_create_file("amdgpu_preempt_ib", 0600,
12264e390cabSriastradh adev->ddev->primary->debugfs_root, adev,
12274e390cabSriastradh &fops_ib_preempt);
12284e390cabSriastradh if (!(adev->debugfs_preempt)) {
12294e390cabSriastradh DRM_ERROR("unable to create amdgpu_preempt_ib debugsfs file\n");
12304e390cabSriastradh return -EIO;
12314e390cabSriastradh }
12324e390cabSriastradh
12334e390cabSriastradh return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_list,
12344e390cabSriastradh ARRAY_SIZE(amdgpu_debugfs_list));
12354e390cabSriastradh }
12364e390cabSriastradh
amdgpu_debugfs_preempt_cleanup(struct amdgpu_device * adev)12374e390cabSriastradh void amdgpu_debugfs_preempt_cleanup(struct amdgpu_device *adev)
12384e390cabSriastradh {
12394e390cabSriastradh debugfs_remove(adev->debugfs_preempt);
12404e390cabSriastradh }
12414e390cabSriastradh
12424e390cabSriastradh #else
amdgpu_debugfs_init(struct amdgpu_device * adev)12434e390cabSriastradh int amdgpu_debugfs_init(struct amdgpu_device *adev)
12444e390cabSriastradh {
12454e390cabSriastradh return 0;
12464e390cabSriastradh }
amdgpu_debugfs_preempt_cleanup(struct amdgpu_device * adev)12474e390cabSriastradh void amdgpu_debugfs_preempt_cleanup(struct amdgpu_device *adev) { }
amdgpu_debugfs_regs_init(struct amdgpu_device * adev)12484e390cabSriastradh int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)
12494e390cabSriastradh {
12504e390cabSriastradh return 0;
12514e390cabSriastradh }
amdgpu_debugfs_regs_cleanup(struct amdgpu_device * adev)12524e390cabSriastradh void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) { }
12534e390cabSriastradh #endif
1254