1fb4d8502Sjsg /* 2fb4d8502Sjsg * Copyright 2008 Advanced Micro Devices, Inc. 3fb4d8502Sjsg * Copyright 2008 Red Hat Inc. 4fb4d8502Sjsg * Copyright 2009 Jerome Glisse. 5fb4d8502Sjsg * 6fb4d8502Sjsg * Permission is hereby granted, free of charge, to any person obtaining a 7fb4d8502Sjsg * copy of this software and associated documentation files (the "Software"), 8fb4d8502Sjsg * to deal in the Software without restriction, including without limitation 9fb4d8502Sjsg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10fb4d8502Sjsg * and/or sell copies of the Software, and to permit persons to whom the 11fb4d8502Sjsg * Software is furnished to do so, subject to the following conditions: 12fb4d8502Sjsg * 13fb4d8502Sjsg * The above copyright notice and this permission notice shall be included in 14fb4d8502Sjsg * all copies or substantial portions of the Software. 15fb4d8502Sjsg * 16fb4d8502Sjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17fb4d8502Sjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18fb4d8502Sjsg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19fb4d8502Sjsg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20fb4d8502Sjsg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21fb4d8502Sjsg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22fb4d8502Sjsg * OTHER DEALINGS IN THE SOFTWARE. 23fb4d8502Sjsg * 24fb4d8502Sjsg */ 25fb4d8502Sjsg 26fb4d8502Sjsg #include <linux/kthread.h> 27c349dbc7Sjsg #include <linux/pci.h> 28c349dbc7Sjsg #include <linux/uaccess.h> 29c349dbc7Sjsg #include <linux/pm_runtime.h> 30c349dbc7Sjsg 31fb4d8502Sjsg #include "amdgpu.h" 32c349dbc7Sjsg #include "amdgpu_pm.h" 33c349dbc7Sjsg #include "amdgpu_dm_debugfs.h" 34c349dbc7Sjsg #include "amdgpu_ras.h" 35ad8b1aafSjsg #include "amdgpu_rap.h" 365ca02815Sjsg #include "amdgpu_securedisplay.h" 375ca02815Sjsg #include "amdgpu_fw_attestation.h" 381bb76ff1Sjsg #include "amdgpu_umr.h" 391bb76ff1Sjsg 401bb76ff1Sjsg #include "amdgpu_reset.h" 411bb76ff1Sjsg #include "amdgpu_psp_ta.h" 42fb4d8502Sjsg 43fb4d8502Sjsg #if defined(CONFIG_DEBUG_FS) 44fb4d8502Sjsg 45fb4d8502Sjsg /** 46fb4d8502Sjsg * amdgpu_debugfs_process_reg_op - Handle MMIO register reads/writes 47fb4d8502Sjsg * 48fb4d8502Sjsg * @read: True if reading 49fb4d8502Sjsg * @f: open file handle 50fb4d8502Sjsg * @buf: User buffer to write/read to 51fb4d8502Sjsg * @size: Number of bytes to write/read 52fb4d8502Sjsg * @pos: Offset to seek to 53fb4d8502Sjsg * 54fb4d8502Sjsg * This debugfs entry has special meaning on the offset being sought. 55fb4d8502Sjsg * Various bits have different meanings: 56fb4d8502Sjsg * 57fb4d8502Sjsg * Bit 62: Indicates a GRBM bank switch is needed 58fb4d8502Sjsg * Bit 61: Indicates a SRBM bank switch is needed (implies bit 62 is 59fb4d8502Sjsg * zero) 60fb4d8502Sjsg * Bits 24..33: The SE or ME selector if needed 61fb4d8502Sjsg * Bits 34..43: The SH (or SA) or PIPE selector if needed 62fb4d8502Sjsg * Bits 44..53: The INSTANCE (or CU/WGP) or QUEUE selector if needed 63fb4d8502Sjsg * 64fb4d8502Sjsg * Bit 23: Indicates that the PM power gating lock should be held 65fb4d8502Sjsg * This is necessary to read registers that might be 66fb4d8502Sjsg * unreliable during a power gating transistion. 67fb4d8502Sjsg * 68fb4d8502Sjsg * The lower bits are the BYTE offset of the register to read. This 69fb4d8502Sjsg * allows reading multiple registers in a single call and having 70fb4d8502Sjsg * the returned size reflect that. 71fb4d8502Sjsg */ 72fb4d8502Sjsg static int amdgpu_debugfs_process_reg_op(bool read, struct file *f, 73fb4d8502Sjsg char __user *buf, size_t size, loff_t *pos) 74fb4d8502Sjsg { 75fb4d8502Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 76fb4d8502Sjsg ssize_t result = 0; 77fb4d8502Sjsg int r; 78fb4d8502Sjsg bool pm_pg_lock, use_bank, use_ring; 79f005ef32Sjsg unsigned int instance_bank, sh_bank, se_bank, me, pipe, queue, vmid; 80fb4d8502Sjsg 81fb4d8502Sjsg pm_pg_lock = use_bank = use_ring = false; 82c349dbc7Sjsg instance_bank = sh_bank = se_bank = me = pipe = queue = vmid = 0; 83fb4d8502Sjsg 84fb4d8502Sjsg if (size & 0x3 || *pos & 0x3 || 85fb4d8502Sjsg ((*pos & (1ULL << 62)) && (*pos & (1ULL << 61)))) 86fb4d8502Sjsg return -EINVAL; 87fb4d8502Sjsg 88fb4d8502Sjsg /* are we reading registers for which a PG lock is necessary? */ 89fb4d8502Sjsg pm_pg_lock = (*pos >> 23) & 1; 90fb4d8502Sjsg 91fb4d8502Sjsg if (*pos & (1ULL << 62)) { 92fb4d8502Sjsg se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24; 93fb4d8502Sjsg sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34; 94fb4d8502Sjsg instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44; 95fb4d8502Sjsg 96fb4d8502Sjsg if (se_bank == 0x3FF) 97fb4d8502Sjsg se_bank = 0xFFFFFFFF; 98fb4d8502Sjsg if (sh_bank == 0x3FF) 99fb4d8502Sjsg sh_bank = 0xFFFFFFFF; 100fb4d8502Sjsg if (instance_bank == 0x3FF) 101fb4d8502Sjsg instance_bank = 0xFFFFFFFF; 102c349dbc7Sjsg use_bank = true; 103fb4d8502Sjsg } else if (*pos & (1ULL << 61)) { 104fb4d8502Sjsg 105fb4d8502Sjsg me = (*pos & GENMASK_ULL(33, 24)) >> 24; 106fb4d8502Sjsg pipe = (*pos & GENMASK_ULL(43, 34)) >> 34; 107fb4d8502Sjsg queue = (*pos & GENMASK_ULL(53, 44)) >> 44; 108c349dbc7Sjsg vmid = (*pos & GENMASK_ULL(58, 54)) >> 54; 109fb4d8502Sjsg 110c349dbc7Sjsg use_ring = true; 111fb4d8502Sjsg } else { 112c349dbc7Sjsg use_bank = use_ring = false; 113fb4d8502Sjsg } 114fb4d8502Sjsg 115fb4d8502Sjsg *pos &= (1UL << 22) - 1; 116fb4d8502Sjsg 117ad8b1aafSjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 118ad8b1aafSjsg if (r < 0) { 119ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 120c349dbc7Sjsg return r; 121ad8b1aafSjsg } 122ad8b1aafSjsg 123ad8b1aafSjsg r = amdgpu_virt_enable_access_debugfs(adev); 124ad8b1aafSjsg if (r < 0) { 125ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 126ad8b1aafSjsg return r; 127ad8b1aafSjsg } 128c349dbc7Sjsg 129fb4d8502Sjsg if (use_bank) { 130fb4d8502Sjsg if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) || 131c349dbc7Sjsg (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines)) { 132ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 133ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 134ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 135fb4d8502Sjsg return -EINVAL; 136c349dbc7Sjsg } 137fb4d8502Sjsg mutex_lock(&adev->grbm_idx_mutex); 138fb4d8502Sjsg amdgpu_gfx_select_se_sh(adev, se_bank, 139f005ef32Sjsg sh_bank, instance_bank, 0); 140fb4d8502Sjsg } else if (use_ring) { 141fb4d8502Sjsg mutex_lock(&adev->srbm_mutex); 142f005ef32Sjsg amdgpu_gfx_select_me_pipe_q(adev, me, pipe, queue, vmid, 0); 143fb4d8502Sjsg } 144fb4d8502Sjsg 145fb4d8502Sjsg if (pm_pg_lock) 146fb4d8502Sjsg mutex_lock(&adev->pm.mutex); 147fb4d8502Sjsg 148fb4d8502Sjsg while (size) { 149fb4d8502Sjsg uint32_t value; 150fb4d8502Sjsg 151fb4d8502Sjsg if (read) { 152fb4d8502Sjsg value = RREG32(*pos >> 2); 153fb4d8502Sjsg r = put_user(value, (uint32_t *)buf); 154fb4d8502Sjsg } else { 155fb4d8502Sjsg r = get_user(value, (uint32_t *)buf); 156fb4d8502Sjsg if (!r) 157f005ef32Sjsg amdgpu_mm_wreg_mmio_rlc(adev, *pos >> 2, value, 0); 158fb4d8502Sjsg } 159fb4d8502Sjsg if (r) { 160fb4d8502Sjsg result = r; 161fb4d8502Sjsg goto end; 162fb4d8502Sjsg } 163fb4d8502Sjsg 164fb4d8502Sjsg result += 4; 165fb4d8502Sjsg buf += 4; 166fb4d8502Sjsg *pos += 4; 167fb4d8502Sjsg size -= 4; 168fb4d8502Sjsg } 169fb4d8502Sjsg 170fb4d8502Sjsg end: 171fb4d8502Sjsg if (use_bank) { 172f005ef32Sjsg amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, 0); 173fb4d8502Sjsg mutex_unlock(&adev->grbm_idx_mutex); 174fb4d8502Sjsg } else if (use_ring) { 175f005ef32Sjsg amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0, 0); 176fb4d8502Sjsg mutex_unlock(&adev->srbm_mutex); 177fb4d8502Sjsg } 178fb4d8502Sjsg 179fb4d8502Sjsg if (pm_pg_lock) 180fb4d8502Sjsg mutex_unlock(&adev->pm.mutex); 181fb4d8502Sjsg 182ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 183ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 184c349dbc7Sjsg 185ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 186fb4d8502Sjsg return result; 187fb4d8502Sjsg } 188fb4d8502Sjsg 1895ca02815Sjsg /* 190fb4d8502Sjsg * amdgpu_debugfs_regs_read - Callback for reading MMIO registers 191fb4d8502Sjsg */ 192fb4d8502Sjsg static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, 193fb4d8502Sjsg size_t size, loff_t *pos) 194fb4d8502Sjsg { 195fb4d8502Sjsg return amdgpu_debugfs_process_reg_op(true, f, buf, size, pos); 196fb4d8502Sjsg } 197fb4d8502Sjsg 1985ca02815Sjsg /* 199fb4d8502Sjsg * amdgpu_debugfs_regs_write - Callback for writing MMIO registers 200fb4d8502Sjsg */ 201fb4d8502Sjsg static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf, 202fb4d8502Sjsg size_t size, loff_t *pos) 203fb4d8502Sjsg { 204fb4d8502Sjsg return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos); 205fb4d8502Sjsg } 206fb4d8502Sjsg 2071bb76ff1Sjsg static int amdgpu_debugfs_regs2_open(struct inode *inode, struct file *file) 2081bb76ff1Sjsg { 2091bb76ff1Sjsg struct amdgpu_debugfs_regs2_data *rd; 2101bb76ff1Sjsg 211f005ef32Sjsg rd = kzalloc(sizeof(*rd), GFP_KERNEL); 2121bb76ff1Sjsg if (!rd) 2131bb76ff1Sjsg return -ENOMEM; 2141bb76ff1Sjsg rd->adev = file_inode(file)->i_private; 2151bb76ff1Sjsg file->private_data = rd; 2161bb76ff1Sjsg mutex_init(&rd->lock); 2171bb76ff1Sjsg 2181bb76ff1Sjsg return 0; 2191bb76ff1Sjsg } 2201bb76ff1Sjsg 2211bb76ff1Sjsg static int amdgpu_debugfs_regs2_release(struct inode *inode, struct file *file) 2221bb76ff1Sjsg { 2231bb76ff1Sjsg struct amdgpu_debugfs_regs2_data *rd = file->private_data; 224f005ef32Sjsg 2251bb76ff1Sjsg mutex_destroy(&rd->lock); 2261bb76ff1Sjsg kfree(file->private_data); 2271bb76ff1Sjsg return 0; 2281bb76ff1Sjsg } 2291bb76ff1Sjsg 2301bb76ff1Sjsg static ssize_t amdgpu_debugfs_regs2_op(struct file *f, char __user *buf, u32 offset, size_t size, int write_en) 2311bb76ff1Sjsg { 2321bb76ff1Sjsg struct amdgpu_debugfs_regs2_data *rd = f->private_data; 2331bb76ff1Sjsg struct amdgpu_device *adev = rd->adev; 2341bb76ff1Sjsg ssize_t result = 0; 2351bb76ff1Sjsg int r; 2361bb76ff1Sjsg uint32_t value; 2371bb76ff1Sjsg 2381bb76ff1Sjsg if (size & 0x3 || offset & 0x3) 2391bb76ff1Sjsg return -EINVAL; 2401bb76ff1Sjsg 2411bb76ff1Sjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 2421bb76ff1Sjsg if (r < 0) { 2431bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 2441bb76ff1Sjsg return r; 2451bb76ff1Sjsg } 2461bb76ff1Sjsg 2471bb76ff1Sjsg r = amdgpu_virt_enable_access_debugfs(adev); 2481bb76ff1Sjsg if (r < 0) { 2491bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 2501bb76ff1Sjsg return r; 2511bb76ff1Sjsg } 2521bb76ff1Sjsg 2531bb76ff1Sjsg mutex_lock(&rd->lock); 2541bb76ff1Sjsg 2551bb76ff1Sjsg if (rd->id.use_grbm) { 2561bb76ff1Sjsg if ((rd->id.grbm.sh != 0xFFFFFFFF && rd->id.grbm.sh >= adev->gfx.config.max_sh_per_se) || 2571bb76ff1Sjsg (rd->id.grbm.se != 0xFFFFFFFF && rd->id.grbm.se >= adev->gfx.config.max_shader_engines)) { 2581bb76ff1Sjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 2591bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 2601bb76ff1Sjsg amdgpu_virt_disable_access_debugfs(adev); 2611bb76ff1Sjsg mutex_unlock(&rd->lock); 2621bb76ff1Sjsg return -EINVAL; 2631bb76ff1Sjsg } 2641bb76ff1Sjsg mutex_lock(&adev->grbm_idx_mutex); 2651bb76ff1Sjsg amdgpu_gfx_select_se_sh(adev, rd->id.grbm.se, 2661bb76ff1Sjsg rd->id.grbm.sh, 267f005ef32Sjsg rd->id.grbm.instance, rd->id.xcc_id); 2681bb76ff1Sjsg } 2691bb76ff1Sjsg 2701bb76ff1Sjsg if (rd->id.use_srbm) { 2711bb76ff1Sjsg mutex_lock(&adev->srbm_mutex); 2721bb76ff1Sjsg amdgpu_gfx_select_me_pipe_q(adev, rd->id.srbm.me, rd->id.srbm.pipe, 273f005ef32Sjsg rd->id.srbm.queue, rd->id.srbm.vmid, rd->id.xcc_id); 2741bb76ff1Sjsg } 2751bb76ff1Sjsg 2761bb76ff1Sjsg if (rd->id.pg_lock) 2771bb76ff1Sjsg mutex_lock(&adev->pm.mutex); 2781bb76ff1Sjsg 2791bb76ff1Sjsg while (size) { 2801bb76ff1Sjsg if (!write_en) { 2811bb76ff1Sjsg value = RREG32(offset >> 2); 2821bb76ff1Sjsg r = put_user(value, (uint32_t *)buf); 2831bb76ff1Sjsg } else { 2841bb76ff1Sjsg r = get_user(value, (uint32_t *)buf); 2851bb76ff1Sjsg if (!r) 286f005ef32Sjsg amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, value, rd->id.xcc_id); 2871bb76ff1Sjsg } 2881bb76ff1Sjsg if (r) { 2891bb76ff1Sjsg result = r; 2901bb76ff1Sjsg goto end; 2911bb76ff1Sjsg } 2921bb76ff1Sjsg offset += 4; 2931bb76ff1Sjsg size -= 4; 2941bb76ff1Sjsg result += 4; 2951bb76ff1Sjsg buf += 4; 2961bb76ff1Sjsg } 2971bb76ff1Sjsg end: 2981bb76ff1Sjsg if (rd->id.use_grbm) { 299f005ef32Sjsg amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, rd->id.xcc_id); 3001bb76ff1Sjsg mutex_unlock(&adev->grbm_idx_mutex); 3011bb76ff1Sjsg } 3021bb76ff1Sjsg 3031bb76ff1Sjsg if (rd->id.use_srbm) { 304f005ef32Sjsg amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0, rd->id.xcc_id); 3051bb76ff1Sjsg mutex_unlock(&adev->srbm_mutex); 3061bb76ff1Sjsg } 3071bb76ff1Sjsg 3081bb76ff1Sjsg if (rd->id.pg_lock) 3091bb76ff1Sjsg mutex_unlock(&adev->pm.mutex); 3101bb76ff1Sjsg 3111bb76ff1Sjsg mutex_unlock(&rd->lock); 3121bb76ff1Sjsg 3131bb76ff1Sjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 3141bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 3151bb76ff1Sjsg 3161bb76ff1Sjsg amdgpu_virt_disable_access_debugfs(adev); 3171bb76ff1Sjsg return result; 3181bb76ff1Sjsg } 3191bb76ff1Sjsg 3201bb76ff1Sjsg static long amdgpu_debugfs_regs2_ioctl(struct file *f, unsigned int cmd, unsigned long data) 3211bb76ff1Sjsg { 3221bb76ff1Sjsg struct amdgpu_debugfs_regs2_data *rd = f->private_data; 323f005ef32Sjsg struct amdgpu_debugfs_regs2_iocdata v1_data; 3241bb76ff1Sjsg int r; 3251bb76ff1Sjsg 3261bb76ff1Sjsg mutex_lock(&rd->lock); 327f005ef32Sjsg 328f005ef32Sjsg switch (cmd) { 329f005ef32Sjsg case AMDGPU_DEBUGFS_REGS2_IOC_SET_STATE_V2: 330f005ef32Sjsg r = copy_from_user(&rd->id, (struct amdgpu_debugfs_regs2_iocdata_v2 *)data, 331f005ef32Sjsg sizeof(rd->id)); 332f005ef32Sjsg if (r) 333f005ef32Sjsg r = -EINVAL; 334f005ef32Sjsg goto done; 335f005ef32Sjsg case AMDGPU_DEBUGFS_REGS2_IOC_SET_STATE: 336f005ef32Sjsg r = copy_from_user(&v1_data, (struct amdgpu_debugfs_regs2_iocdata *)data, 337f005ef32Sjsg sizeof(v1_data)); 338f005ef32Sjsg if (r) { 339f005ef32Sjsg r = -EINVAL; 340f005ef32Sjsg goto done; 3411bb76ff1Sjsg } 342f005ef32Sjsg goto v1_copy; 343f005ef32Sjsg default: 344f005ef32Sjsg r = -EINVAL; 345f005ef32Sjsg goto done; 346f005ef32Sjsg } 347f005ef32Sjsg 348f005ef32Sjsg v1_copy: 349f005ef32Sjsg rd->id.use_srbm = v1_data.use_srbm; 350f005ef32Sjsg rd->id.use_grbm = v1_data.use_grbm; 351f005ef32Sjsg rd->id.pg_lock = v1_data.pg_lock; 352f005ef32Sjsg rd->id.grbm.se = v1_data.grbm.se; 353f005ef32Sjsg rd->id.grbm.sh = v1_data.grbm.sh; 354f005ef32Sjsg rd->id.grbm.instance = v1_data.grbm.instance; 355f005ef32Sjsg rd->id.srbm.me = v1_data.srbm.me; 356f005ef32Sjsg rd->id.srbm.pipe = v1_data.srbm.pipe; 357f005ef32Sjsg rd->id.srbm.queue = v1_data.srbm.queue; 358f005ef32Sjsg rd->id.xcc_id = 0; 359f005ef32Sjsg done: 360f005ef32Sjsg mutex_unlock(&rd->lock); 361f005ef32Sjsg return r; 3621bb76ff1Sjsg } 3631bb76ff1Sjsg 3641bb76ff1Sjsg static ssize_t amdgpu_debugfs_regs2_read(struct file *f, char __user *buf, size_t size, loff_t *pos) 3651bb76ff1Sjsg { 3661bb76ff1Sjsg return amdgpu_debugfs_regs2_op(f, buf, *pos, size, 0); 3671bb76ff1Sjsg } 3681bb76ff1Sjsg 3691bb76ff1Sjsg static ssize_t amdgpu_debugfs_regs2_write(struct file *f, const char __user *buf, size_t size, loff_t *pos) 3701bb76ff1Sjsg { 3711bb76ff1Sjsg return amdgpu_debugfs_regs2_op(f, (char __user *)buf, *pos, size, 1); 3721bb76ff1Sjsg } 3731bb76ff1Sjsg 374f005ef32Sjsg static int amdgpu_debugfs_gprwave_open(struct inode *inode, struct file *file) 375f005ef32Sjsg { 376f005ef32Sjsg struct amdgpu_debugfs_gprwave_data *rd; 377f005ef32Sjsg 378f005ef32Sjsg rd = kzalloc(sizeof(*rd), GFP_KERNEL); 379f005ef32Sjsg if (!rd) 380f005ef32Sjsg return -ENOMEM; 381f005ef32Sjsg rd->adev = file_inode(file)->i_private; 382f005ef32Sjsg file->private_data = rd; 383f005ef32Sjsg mutex_init(&rd->lock); 384f005ef32Sjsg 385f005ef32Sjsg return 0; 386f005ef32Sjsg } 387f005ef32Sjsg 388f005ef32Sjsg static int amdgpu_debugfs_gprwave_release(struct inode *inode, struct file *file) 389f005ef32Sjsg { 390f005ef32Sjsg struct amdgpu_debugfs_gprwave_data *rd = file->private_data; 391f005ef32Sjsg 392f005ef32Sjsg mutex_destroy(&rd->lock); 393f005ef32Sjsg kfree(file->private_data); 394f005ef32Sjsg return 0; 395f005ef32Sjsg } 396f005ef32Sjsg 397f005ef32Sjsg static ssize_t amdgpu_debugfs_gprwave_read(struct file *f, char __user *buf, size_t size, loff_t *pos) 398f005ef32Sjsg { 399f005ef32Sjsg struct amdgpu_debugfs_gprwave_data *rd = f->private_data; 400f005ef32Sjsg struct amdgpu_device *adev = rd->adev; 401f005ef32Sjsg ssize_t result = 0; 402f005ef32Sjsg int r; 403f005ef32Sjsg uint32_t *data, x; 404f005ef32Sjsg 4059eddea1dSjsg if (size > 4096 || size & 0x3 || *pos & 0x3) 406f005ef32Sjsg return -EINVAL; 407f005ef32Sjsg 408f005ef32Sjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 409f005ef32Sjsg if (r < 0) { 410f005ef32Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 411f005ef32Sjsg return r; 412f005ef32Sjsg } 413f005ef32Sjsg 414f005ef32Sjsg r = amdgpu_virt_enable_access_debugfs(adev); 415f005ef32Sjsg if (r < 0) { 416f005ef32Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 417f005ef32Sjsg return r; 418f005ef32Sjsg } 419f005ef32Sjsg 420f005ef32Sjsg data = kcalloc(1024, sizeof(*data), GFP_KERNEL); 421f005ef32Sjsg if (!data) { 422f005ef32Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 423f005ef32Sjsg amdgpu_virt_disable_access_debugfs(adev); 424f005ef32Sjsg return -ENOMEM; 425f005ef32Sjsg } 426f005ef32Sjsg 427f005ef32Sjsg /* switch to the specific se/sh/cu */ 428f005ef32Sjsg mutex_lock(&adev->grbm_idx_mutex); 429f005ef32Sjsg amdgpu_gfx_select_se_sh(adev, rd->id.se, rd->id.sh, rd->id.cu, rd->id.xcc_id); 430f005ef32Sjsg 431f005ef32Sjsg if (!rd->id.gpr_or_wave) { 432f005ef32Sjsg x = 0; 433f005ef32Sjsg if (adev->gfx.funcs->read_wave_data) 434f005ef32Sjsg adev->gfx.funcs->read_wave_data(adev, rd->id.xcc_id, rd->id.simd, rd->id.wave, data, &x); 435f005ef32Sjsg } else { 436f005ef32Sjsg x = size >> 2; 437f005ef32Sjsg if (rd->id.gpr.vpgr_or_sgpr) { 438f005ef32Sjsg if (adev->gfx.funcs->read_wave_vgprs) 439f005ef32Sjsg adev->gfx.funcs->read_wave_vgprs(adev, rd->id.xcc_id, rd->id.simd, rd->id.wave, rd->id.gpr.thread, *pos, size>>2, data); 440f005ef32Sjsg } else { 441f005ef32Sjsg if (adev->gfx.funcs->read_wave_sgprs) 442f005ef32Sjsg adev->gfx.funcs->read_wave_sgprs(adev, rd->id.xcc_id, rd->id.simd, rd->id.wave, *pos, size>>2, data); 443f005ef32Sjsg } 444f005ef32Sjsg } 445f005ef32Sjsg 446f005ef32Sjsg amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, rd->id.xcc_id); 447f005ef32Sjsg mutex_unlock(&adev->grbm_idx_mutex); 448f005ef32Sjsg 449f005ef32Sjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 450f005ef32Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 451f005ef32Sjsg 452f005ef32Sjsg if (!x) { 453f005ef32Sjsg result = -EINVAL; 454f005ef32Sjsg goto done; 455f005ef32Sjsg } 456f005ef32Sjsg 457f005ef32Sjsg while (size && (*pos < x * 4)) { 458f005ef32Sjsg uint32_t value; 459f005ef32Sjsg 460f005ef32Sjsg value = data[*pos >> 2]; 461f005ef32Sjsg r = put_user(value, (uint32_t *)buf); 462f005ef32Sjsg if (r) { 463f005ef32Sjsg result = r; 464f005ef32Sjsg goto done; 465f005ef32Sjsg } 466f005ef32Sjsg 467f005ef32Sjsg result += 4; 468f005ef32Sjsg buf += 4; 469f005ef32Sjsg *pos += 4; 470f005ef32Sjsg size -= 4; 471f005ef32Sjsg } 472f005ef32Sjsg 473f005ef32Sjsg done: 474f005ef32Sjsg amdgpu_virt_disable_access_debugfs(adev); 475f005ef32Sjsg kfree(data); 476f005ef32Sjsg return result; 477f005ef32Sjsg } 478f005ef32Sjsg 479f005ef32Sjsg static long amdgpu_debugfs_gprwave_ioctl(struct file *f, unsigned int cmd, unsigned long data) 480f005ef32Sjsg { 481f005ef32Sjsg struct amdgpu_debugfs_gprwave_data *rd = f->private_data; 482f005ef32Sjsg int r = 0; 483f005ef32Sjsg 484f005ef32Sjsg mutex_lock(&rd->lock); 485f005ef32Sjsg 486f005ef32Sjsg switch (cmd) { 487f005ef32Sjsg case AMDGPU_DEBUGFS_GPRWAVE_IOC_SET_STATE: 488f005ef32Sjsg if (copy_from_user(&rd->id, 489f005ef32Sjsg (struct amdgpu_debugfs_gprwave_iocdata *)data, 490f005ef32Sjsg sizeof(rd->id))) 491f005ef32Sjsg r = -EFAULT; 492f005ef32Sjsg goto done; 493f005ef32Sjsg default: 494f005ef32Sjsg r = -EINVAL; 495f005ef32Sjsg goto done; 496f005ef32Sjsg } 497f005ef32Sjsg 498f005ef32Sjsg done: 499f005ef32Sjsg mutex_unlock(&rd->lock); 500f005ef32Sjsg return r; 501f005ef32Sjsg } 502f005ef32Sjsg 503f005ef32Sjsg 504f005ef32Sjsg 505fb4d8502Sjsg 506fb4d8502Sjsg /** 507fb4d8502Sjsg * amdgpu_debugfs_regs_pcie_read - Read from a PCIE register 508fb4d8502Sjsg * 509fb4d8502Sjsg * @f: open file handle 510fb4d8502Sjsg * @buf: User buffer to store read data in 511fb4d8502Sjsg * @size: Number of bytes to read 512fb4d8502Sjsg * @pos: Offset to seek to 513fb4d8502Sjsg * 514fb4d8502Sjsg * The lower bits are the BYTE offset of the register to read. This 515fb4d8502Sjsg * allows reading multiple registers in a single call and having 516fb4d8502Sjsg * the returned size reflect that. 517fb4d8502Sjsg */ 518fb4d8502Sjsg static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf, 519fb4d8502Sjsg size_t size, loff_t *pos) 520fb4d8502Sjsg { 521fb4d8502Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 522fb4d8502Sjsg ssize_t result = 0; 523fb4d8502Sjsg int r; 524fb4d8502Sjsg 525fb4d8502Sjsg if (size & 0x3 || *pos & 0x3) 526fb4d8502Sjsg return -EINVAL; 527fb4d8502Sjsg 528ad8b1aafSjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 529ad8b1aafSjsg if (r < 0) { 530ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 531c349dbc7Sjsg return r; 532ad8b1aafSjsg } 533ad8b1aafSjsg 534ad8b1aafSjsg r = amdgpu_virt_enable_access_debugfs(adev); 535ad8b1aafSjsg if (r < 0) { 536ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 537ad8b1aafSjsg return r; 538ad8b1aafSjsg } 539c349dbc7Sjsg 540fb4d8502Sjsg while (size) { 541fb4d8502Sjsg uint32_t value; 542fb4d8502Sjsg 543ad8b1aafSjsg value = RREG32_PCIE(*pos); 544fb4d8502Sjsg r = put_user(value, (uint32_t *)buf); 5451bb76ff1Sjsg if (r) 5461bb76ff1Sjsg goto out; 547fb4d8502Sjsg 548fb4d8502Sjsg result += 4; 549fb4d8502Sjsg buf += 4; 550fb4d8502Sjsg *pos += 4; 551fb4d8502Sjsg size -= 4; 552fb4d8502Sjsg } 553fb4d8502Sjsg 5541bb76ff1Sjsg r = result; 5551bb76ff1Sjsg out: 556ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 557ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 558ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 5591bb76ff1Sjsg return r; 560fb4d8502Sjsg } 561fb4d8502Sjsg 562fb4d8502Sjsg /** 563fb4d8502Sjsg * amdgpu_debugfs_regs_pcie_write - Write to a PCIE register 564fb4d8502Sjsg * 565fb4d8502Sjsg * @f: open file handle 566fb4d8502Sjsg * @buf: User buffer to write data from 567fb4d8502Sjsg * @size: Number of bytes to write 568fb4d8502Sjsg * @pos: Offset to seek to 569fb4d8502Sjsg * 570fb4d8502Sjsg * The lower bits are the BYTE offset of the register to write. This 571fb4d8502Sjsg * allows writing multiple registers in a single call and having 572fb4d8502Sjsg * the returned size reflect that. 573fb4d8502Sjsg */ 574fb4d8502Sjsg static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user *buf, 575fb4d8502Sjsg size_t size, loff_t *pos) 576fb4d8502Sjsg { 577fb4d8502Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 578fb4d8502Sjsg ssize_t result = 0; 579fb4d8502Sjsg int r; 580fb4d8502Sjsg 581fb4d8502Sjsg if (size & 0x3 || *pos & 0x3) 582fb4d8502Sjsg return -EINVAL; 583fb4d8502Sjsg 584ad8b1aafSjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 585ad8b1aafSjsg if (r < 0) { 586ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 587c349dbc7Sjsg return r; 588ad8b1aafSjsg } 589ad8b1aafSjsg 590ad8b1aafSjsg r = amdgpu_virt_enable_access_debugfs(adev); 591ad8b1aafSjsg if (r < 0) { 592ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 593ad8b1aafSjsg return r; 594ad8b1aafSjsg } 595c349dbc7Sjsg 596fb4d8502Sjsg while (size) { 597fb4d8502Sjsg uint32_t value; 598fb4d8502Sjsg 599fb4d8502Sjsg r = get_user(value, (uint32_t *)buf); 6001bb76ff1Sjsg if (r) 6011bb76ff1Sjsg goto out; 602fb4d8502Sjsg 603ad8b1aafSjsg WREG32_PCIE(*pos, value); 604fb4d8502Sjsg 605fb4d8502Sjsg result += 4; 606fb4d8502Sjsg buf += 4; 607fb4d8502Sjsg *pos += 4; 608fb4d8502Sjsg size -= 4; 609fb4d8502Sjsg } 610fb4d8502Sjsg 6111bb76ff1Sjsg r = result; 6121bb76ff1Sjsg out: 613ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 614ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 615ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 6161bb76ff1Sjsg return r; 617fb4d8502Sjsg } 618fb4d8502Sjsg 619fb4d8502Sjsg /** 620fb4d8502Sjsg * amdgpu_debugfs_regs_didt_read - Read from a DIDT register 621fb4d8502Sjsg * 622fb4d8502Sjsg * @f: open file handle 623fb4d8502Sjsg * @buf: User buffer to store read data in 624fb4d8502Sjsg * @size: Number of bytes to read 625fb4d8502Sjsg * @pos: Offset to seek to 626fb4d8502Sjsg * 627fb4d8502Sjsg * The lower bits are the BYTE offset of the register to read. This 628fb4d8502Sjsg * allows reading multiple registers in a single call and having 629fb4d8502Sjsg * the returned size reflect that. 630fb4d8502Sjsg */ 631fb4d8502Sjsg static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf, 632fb4d8502Sjsg size_t size, loff_t *pos) 633fb4d8502Sjsg { 634fb4d8502Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 635fb4d8502Sjsg ssize_t result = 0; 636fb4d8502Sjsg int r; 637fb4d8502Sjsg 638fb4d8502Sjsg if (size & 0x3 || *pos & 0x3) 639fb4d8502Sjsg return -EINVAL; 640fb4d8502Sjsg 64141d7f58fSjsg if (!adev->didt_rreg) 64241d7f58fSjsg return -EOPNOTSUPP; 64341d7f58fSjsg 644ad8b1aafSjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 645ad8b1aafSjsg if (r < 0) { 646ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 647c349dbc7Sjsg return r; 648ad8b1aafSjsg } 649ad8b1aafSjsg 650ad8b1aafSjsg r = amdgpu_virt_enable_access_debugfs(adev); 651ad8b1aafSjsg if (r < 0) { 652ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 653ad8b1aafSjsg return r; 654ad8b1aafSjsg } 655c349dbc7Sjsg 656fb4d8502Sjsg while (size) { 657fb4d8502Sjsg uint32_t value; 658fb4d8502Sjsg 659fb4d8502Sjsg value = RREG32_DIDT(*pos >> 2); 660fb4d8502Sjsg r = put_user(value, (uint32_t *)buf); 6611bb76ff1Sjsg if (r) 6621bb76ff1Sjsg goto out; 663fb4d8502Sjsg 664fb4d8502Sjsg result += 4; 665fb4d8502Sjsg buf += 4; 666fb4d8502Sjsg *pos += 4; 667fb4d8502Sjsg size -= 4; 668fb4d8502Sjsg } 669fb4d8502Sjsg 6701bb76ff1Sjsg r = result; 6711bb76ff1Sjsg out: 672ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 673ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 674ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 6751bb76ff1Sjsg return r; 676fb4d8502Sjsg } 677fb4d8502Sjsg 678fb4d8502Sjsg /** 679fb4d8502Sjsg * amdgpu_debugfs_regs_didt_write - Write to a DIDT register 680fb4d8502Sjsg * 681fb4d8502Sjsg * @f: open file handle 682fb4d8502Sjsg * @buf: User buffer to write data from 683fb4d8502Sjsg * @size: Number of bytes to write 684fb4d8502Sjsg * @pos: Offset to seek to 685fb4d8502Sjsg * 686fb4d8502Sjsg * The lower bits are the BYTE offset of the register to write. This 687fb4d8502Sjsg * allows writing multiple registers in a single call and having 688fb4d8502Sjsg * the returned size reflect that. 689fb4d8502Sjsg */ 690fb4d8502Sjsg static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user *buf, 691fb4d8502Sjsg size_t size, loff_t *pos) 692fb4d8502Sjsg { 693fb4d8502Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 694fb4d8502Sjsg ssize_t result = 0; 695fb4d8502Sjsg int r; 696fb4d8502Sjsg 697fb4d8502Sjsg if (size & 0x3 || *pos & 0x3) 698fb4d8502Sjsg return -EINVAL; 699fb4d8502Sjsg 70041d7f58fSjsg if (!adev->didt_wreg) 70141d7f58fSjsg return -EOPNOTSUPP; 70241d7f58fSjsg 703ad8b1aafSjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 704ad8b1aafSjsg if (r < 0) { 705ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 706c349dbc7Sjsg return r; 707ad8b1aafSjsg } 708ad8b1aafSjsg 709ad8b1aafSjsg r = amdgpu_virt_enable_access_debugfs(adev); 710ad8b1aafSjsg if (r < 0) { 711ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 712ad8b1aafSjsg return r; 713ad8b1aafSjsg } 714c349dbc7Sjsg 715fb4d8502Sjsg while (size) { 716fb4d8502Sjsg uint32_t value; 717fb4d8502Sjsg 718fb4d8502Sjsg r = get_user(value, (uint32_t *)buf); 7191bb76ff1Sjsg if (r) 7201bb76ff1Sjsg goto out; 721fb4d8502Sjsg 722fb4d8502Sjsg WREG32_DIDT(*pos >> 2, value); 723fb4d8502Sjsg 724fb4d8502Sjsg result += 4; 725fb4d8502Sjsg buf += 4; 726fb4d8502Sjsg *pos += 4; 727fb4d8502Sjsg size -= 4; 728fb4d8502Sjsg } 729fb4d8502Sjsg 7301bb76ff1Sjsg r = result; 7311bb76ff1Sjsg out: 732ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 733ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 734ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 7351bb76ff1Sjsg return r; 736fb4d8502Sjsg } 737fb4d8502Sjsg 738fb4d8502Sjsg /** 739fb4d8502Sjsg * amdgpu_debugfs_regs_smc_read - Read from a SMC register 740fb4d8502Sjsg * 741fb4d8502Sjsg * @f: open file handle 742fb4d8502Sjsg * @buf: User buffer to store read data in 743fb4d8502Sjsg * @size: Number of bytes to read 744fb4d8502Sjsg * @pos: Offset to seek to 745fb4d8502Sjsg * 746fb4d8502Sjsg * The lower bits are the BYTE offset of the register to read. This 747fb4d8502Sjsg * allows reading multiple registers in a single call and having 748fb4d8502Sjsg * the returned size reflect that. 749fb4d8502Sjsg */ 750fb4d8502Sjsg static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, 751fb4d8502Sjsg size_t size, loff_t *pos) 752fb4d8502Sjsg { 753fb4d8502Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 754fb4d8502Sjsg ssize_t result = 0; 755fb4d8502Sjsg int r; 756fb4d8502Sjsg 7579bc9405eSjsg if (!adev->smc_rreg) 7588fc7c305Sjsg return -EOPNOTSUPP; 7599bc9405eSjsg 760fb4d8502Sjsg if (size & 0x3 || *pos & 0x3) 761fb4d8502Sjsg return -EINVAL; 762fb4d8502Sjsg 763ad8b1aafSjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 764ad8b1aafSjsg if (r < 0) { 765ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 766c349dbc7Sjsg return r; 767ad8b1aafSjsg } 768ad8b1aafSjsg 769ad8b1aafSjsg r = amdgpu_virt_enable_access_debugfs(adev); 770ad8b1aafSjsg if (r < 0) { 771ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 772ad8b1aafSjsg return r; 773ad8b1aafSjsg } 774c349dbc7Sjsg 775fb4d8502Sjsg while (size) { 776fb4d8502Sjsg uint32_t value; 777fb4d8502Sjsg 778fb4d8502Sjsg value = RREG32_SMC(*pos); 779fb4d8502Sjsg r = put_user(value, (uint32_t *)buf); 7801bb76ff1Sjsg if (r) 7811bb76ff1Sjsg goto out; 782fb4d8502Sjsg 783fb4d8502Sjsg result += 4; 784fb4d8502Sjsg buf += 4; 785fb4d8502Sjsg *pos += 4; 786fb4d8502Sjsg size -= 4; 787fb4d8502Sjsg } 788fb4d8502Sjsg 7891bb76ff1Sjsg r = result; 7901bb76ff1Sjsg out: 791ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 792ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 793ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 7941bb76ff1Sjsg return r; 795fb4d8502Sjsg } 796fb4d8502Sjsg 797fb4d8502Sjsg /** 798fb4d8502Sjsg * amdgpu_debugfs_regs_smc_write - Write to a SMC register 799fb4d8502Sjsg * 800fb4d8502Sjsg * @f: open file handle 801fb4d8502Sjsg * @buf: User buffer to write data from 802fb4d8502Sjsg * @size: Number of bytes to write 803fb4d8502Sjsg * @pos: Offset to seek to 804fb4d8502Sjsg * 805fb4d8502Sjsg * The lower bits are the BYTE offset of the register to write. This 806fb4d8502Sjsg * allows writing multiple registers in a single call and having 807fb4d8502Sjsg * the returned size reflect that. 808fb4d8502Sjsg */ 809fb4d8502Sjsg static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *buf, 810fb4d8502Sjsg size_t size, loff_t *pos) 811fb4d8502Sjsg { 812fb4d8502Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 813fb4d8502Sjsg ssize_t result = 0; 814fb4d8502Sjsg int r; 815fb4d8502Sjsg 8169bc9405eSjsg if (!adev->smc_wreg) 8178fc7c305Sjsg return -EOPNOTSUPP; 8189bc9405eSjsg 819fb4d8502Sjsg if (size & 0x3 || *pos & 0x3) 820fb4d8502Sjsg return -EINVAL; 821fb4d8502Sjsg 822ad8b1aafSjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 823ad8b1aafSjsg if (r < 0) { 824ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 825c349dbc7Sjsg return r; 826ad8b1aafSjsg } 827ad8b1aafSjsg 828ad8b1aafSjsg r = amdgpu_virt_enable_access_debugfs(adev); 829ad8b1aafSjsg if (r < 0) { 830ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 831ad8b1aafSjsg return r; 832ad8b1aafSjsg } 833c349dbc7Sjsg 834fb4d8502Sjsg while (size) { 835fb4d8502Sjsg uint32_t value; 836fb4d8502Sjsg 837fb4d8502Sjsg r = get_user(value, (uint32_t *)buf); 8381bb76ff1Sjsg if (r) 8391bb76ff1Sjsg goto out; 840fb4d8502Sjsg 841fb4d8502Sjsg WREG32_SMC(*pos, value); 842fb4d8502Sjsg 843fb4d8502Sjsg result += 4; 844fb4d8502Sjsg buf += 4; 845fb4d8502Sjsg *pos += 4; 846fb4d8502Sjsg size -= 4; 847fb4d8502Sjsg } 848fb4d8502Sjsg 8491bb76ff1Sjsg r = result; 8501bb76ff1Sjsg out: 851ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 852ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 853ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 8541bb76ff1Sjsg return r; 855fb4d8502Sjsg } 856fb4d8502Sjsg 857fb4d8502Sjsg /** 858fb4d8502Sjsg * amdgpu_debugfs_gca_config_read - Read from gfx config data 859fb4d8502Sjsg * 860fb4d8502Sjsg * @f: open file handle 861fb4d8502Sjsg * @buf: User buffer to store read data in 862fb4d8502Sjsg * @size: Number of bytes to read 863fb4d8502Sjsg * @pos: Offset to seek to 864fb4d8502Sjsg * 865fb4d8502Sjsg * This file is used to access configuration data in a somewhat 866fb4d8502Sjsg * stable fashion. The format is a series of DWORDs with the first 867fb4d8502Sjsg * indicating which revision it is. New content is appended to the 868fb4d8502Sjsg * end so that older software can still read the data. 869fb4d8502Sjsg */ 870fb4d8502Sjsg 871fb4d8502Sjsg static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, 872fb4d8502Sjsg size_t size, loff_t *pos) 873fb4d8502Sjsg { 874fb4d8502Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 875fb4d8502Sjsg ssize_t result = 0; 876fb4d8502Sjsg int r; 877fb4d8502Sjsg uint32_t *config, no_regs = 0; 878fb4d8502Sjsg 879fb4d8502Sjsg if (size & 0x3 || *pos & 0x3) 880fb4d8502Sjsg return -EINVAL; 881fb4d8502Sjsg 882fb4d8502Sjsg config = kmalloc_array(256, sizeof(*config), GFP_KERNEL); 883fb4d8502Sjsg if (!config) 884fb4d8502Sjsg return -ENOMEM; 885fb4d8502Sjsg 886fb4d8502Sjsg /* version, increment each time something is added */ 8871bb76ff1Sjsg config[no_regs++] = 5; 888fb4d8502Sjsg config[no_regs++] = adev->gfx.config.max_shader_engines; 889fb4d8502Sjsg config[no_regs++] = adev->gfx.config.max_tile_pipes; 890fb4d8502Sjsg config[no_regs++] = adev->gfx.config.max_cu_per_sh; 891fb4d8502Sjsg config[no_regs++] = adev->gfx.config.max_sh_per_se; 892fb4d8502Sjsg config[no_regs++] = adev->gfx.config.max_backends_per_se; 893fb4d8502Sjsg config[no_regs++] = adev->gfx.config.max_texture_channel_caches; 894fb4d8502Sjsg config[no_regs++] = adev->gfx.config.max_gprs; 895fb4d8502Sjsg config[no_regs++] = adev->gfx.config.max_gs_threads; 896fb4d8502Sjsg config[no_regs++] = adev->gfx.config.max_hw_contexts; 897fb4d8502Sjsg config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_frontend; 898fb4d8502Sjsg config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_backend; 899fb4d8502Sjsg config[no_regs++] = adev->gfx.config.sc_hiz_tile_fifo_size; 900fb4d8502Sjsg config[no_regs++] = adev->gfx.config.sc_earlyz_tile_fifo_size; 901fb4d8502Sjsg config[no_regs++] = adev->gfx.config.num_tile_pipes; 902fb4d8502Sjsg config[no_regs++] = adev->gfx.config.backend_enable_mask; 903fb4d8502Sjsg config[no_regs++] = adev->gfx.config.mem_max_burst_length_bytes; 904fb4d8502Sjsg config[no_regs++] = adev->gfx.config.mem_row_size_in_kb; 905fb4d8502Sjsg config[no_regs++] = adev->gfx.config.shader_engine_tile_size; 906fb4d8502Sjsg config[no_regs++] = adev->gfx.config.num_gpus; 907fb4d8502Sjsg config[no_regs++] = adev->gfx.config.multi_gpu_tile_size; 908fb4d8502Sjsg config[no_regs++] = adev->gfx.config.mc_arb_ramcfg; 909fb4d8502Sjsg config[no_regs++] = adev->gfx.config.gb_addr_config; 910fb4d8502Sjsg config[no_regs++] = adev->gfx.config.num_rbs; 911fb4d8502Sjsg 912fb4d8502Sjsg /* rev==1 */ 913fb4d8502Sjsg config[no_regs++] = adev->rev_id; 9141bb76ff1Sjsg config[no_regs++] = lower_32_bits(adev->pg_flags); 9151bb76ff1Sjsg config[no_regs++] = lower_32_bits(adev->cg_flags); 916fb4d8502Sjsg 917fb4d8502Sjsg /* rev==2 */ 918fb4d8502Sjsg config[no_regs++] = adev->family; 919fb4d8502Sjsg config[no_regs++] = adev->external_rev_id; 920fb4d8502Sjsg 921fb4d8502Sjsg /* rev==3 */ 922fb4d8502Sjsg config[no_regs++] = adev->pdev->device; 923fb4d8502Sjsg config[no_regs++] = adev->pdev->revision; 924fb4d8502Sjsg config[no_regs++] = adev->pdev->subsystem_device; 925fb4d8502Sjsg config[no_regs++] = adev->pdev->subsystem_vendor; 926fb4d8502Sjsg 9271bb76ff1Sjsg /* rev==4 APU flag */ 9281bb76ff1Sjsg config[no_regs++] = adev->flags & AMD_IS_APU ? 1 : 0; 9291bb76ff1Sjsg 9301bb76ff1Sjsg /* rev==5 PG/CG flag upper 32bit */ 9311bb76ff1Sjsg config[no_regs++] = upper_32_bits(adev->pg_flags); 9321bb76ff1Sjsg config[no_regs++] = upper_32_bits(adev->cg_flags); 9331bb76ff1Sjsg 934fb4d8502Sjsg while (size && (*pos < no_regs * 4)) { 935fb4d8502Sjsg uint32_t value; 936fb4d8502Sjsg 937fb4d8502Sjsg value = config[*pos >> 2]; 938fb4d8502Sjsg r = put_user(value, (uint32_t *)buf); 939fb4d8502Sjsg if (r) { 940fb4d8502Sjsg kfree(config); 941fb4d8502Sjsg return r; 942fb4d8502Sjsg } 943fb4d8502Sjsg 944fb4d8502Sjsg result += 4; 945fb4d8502Sjsg buf += 4; 946fb4d8502Sjsg *pos += 4; 947fb4d8502Sjsg size -= 4; 948fb4d8502Sjsg } 949fb4d8502Sjsg 950fb4d8502Sjsg kfree(config); 951fb4d8502Sjsg return result; 952fb4d8502Sjsg } 953fb4d8502Sjsg 954fb4d8502Sjsg /** 955fb4d8502Sjsg * amdgpu_debugfs_sensor_read - Read from the powerplay sensors 956fb4d8502Sjsg * 957fb4d8502Sjsg * @f: open file handle 958fb4d8502Sjsg * @buf: User buffer to store read data in 959fb4d8502Sjsg * @size: Number of bytes to read 960fb4d8502Sjsg * @pos: Offset to seek to 961fb4d8502Sjsg * 962fb4d8502Sjsg * The offset is treated as the BYTE address of one of the sensors 963fb4d8502Sjsg * enumerated in amd/include/kgd_pp_interface.h under the 964fb4d8502Sjsg * 'amd_pp_sensors' enumeration. For instance to read the UVD VCLK 965fb4d8502Sjsg * you would use the offset 3 * 4 = 12. 966fb4d8502Sjsg */ 967fb4d8502Sjsg static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf, 968fb4d8502Sjsg size_t size, loff_t *pos) 969fb4d8502Sjsg { 970fb4d8502Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 971fb4d8502Sjsg int idx, x, outsize, r, valuesize; 972fb4d8502Sjsg uint32_t values[16]; 973fb4d8502Sjsg 974fb4d8502Sjsg if (size & 3 || *pos & 0x3) 975fb4d8502Sjsg return -EINVAL; 976fb4d8502Sjsg 977fb4d8502Sjsg if (!adev->pm.dpm_enabled) 978fb4d8502Sjsg return -EINVAL; 979fb4d8502Sjsg 980fb4d8502Sjsg /* convert offset to sensor number */ 981fb4d8502Sjsg idx = *pos >> 2; 982fb4d8502Sjsg 983fb4d8502Sjsg valuesize = sizeof(values); 984c349dbc7Sjsg 985ad8b1aafSjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 986ad8b1aafSjsg if (r < 0) { 987ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 988c349dbc7Sjsg return r; 989ad8b1aafSjsg } 990ad8b1aafSjsg 991ad8b1aafSjsg r = amdgpu_virt_enable_access_debugfs(adev); 992ad8b1aafSjsg if (r < 0) { 993ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 994ad8b1aafSjsg return r; 995ad8b1aafSjsg } 996c349dbc7Sjsg 997fb4d8502Sjsg r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize); 998c349dbc7Sjsg 999ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 1000ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 1001c349dbc7Sjsg 1002ad8b1aafSjsg if (r) { 1003ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 1004c349dbc7Sjsg return r; 1005ad8b1aafSjsg } 1006fb4d8502Sjsg 1007ad8b1aafSjsg if (size > valuesize) { 1008ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 1009fb4d8502Sjsg return -EINVAL; 1010ad8b1aafSjsg } 1011fb4d8502Sjsg 1012fb4d8502Sjsg outsize = 0; 1013fb4d8502Sjsg x = 0; 1014fb4d8502Sjsg if (!r) { 1015fb4d8502Sjsg while (size) { 1016fb4d8502Sjsg r = put_user(values[x++], (int32_t *)buf); 1017fb4d8502Sjsg buf += 4; 1018fb4d8502Sjsg size -= 4; 1019fb4d8502Sjsg outsize += 4; 1020fb4d8502Sjsg } 1021fb4d8502Sjsg } 1022fb4d8502Sjsg 1023ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 1024fb4d8502Sjsg return !r ? outsize : r; 1025fb4d8502Sjsg } 1026fb4d8502Sjsg 1027fb4d8502Sjsg /** amdgpu_debugfs_wave_read - Read WAVE STATUS data 1028fb4d8502Sjsg * 1029fb4d8502Sjsg * @f: open file handle 1030fb4d8502Sjsg * @buf: User buffer to store read data in 1031fb4d8502Sjsg * @size: Number of bytes to read 1032fb4d8502Sjsg * @pos: Offset to seek to 1033fb4d8502Sjsg * 1034fb4d8502Sjsg * The offset being sought changes which wave that the status data 1035fb4d8502Sjsg * will be returned for. The bits are used as follows: 1036fb4d8502Sjsg * 1037fb4d8502Sjsg * Bits 0..6: Byte offset into data 1038fb4d8502Sjsg * Bits 7..14: SE selector 1039fb4d8502Sjsg * Bits 15..22: SH/SA selector 1040fb4d8502Sjsg * Bits 23..30: CU/{WGP+SIMD} selector 1041fb4d8502Sjsg * Bits 31..36: WAVE ID selector 1042fb4d8502Sjsg * Bits 37..44: SIMD ID selector 1043fb4d8502Sjsg * 1044fb4d8502Sjsg * The returned data begins with one DWORD of version information 1045fb4d8502Sjsg * Followed by WAVE STATUS registers relevant to the GFX IP version 1046fb4d8502Sjsg * being used. See gfx_v8_0_read_wave_data() for an example output. 1047fb4d8502Sjsg */ 1048fb4d8502Sjsg static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf, 1049fb4d8502Sjsg size_t size, loff_t *pos) 1050fb4d8502Sjsg { 1051fb4d8502Sjsg struct amdgpu_device *adev = f->f_inode->i_private; 1052fb4d8502Sjsg int r, x; 1053fb4d8502Sjsg ssize_t result = 0; 1054fb4d8502Sjsg uint32_t offset, se, sh, cu, wave, simd, data[32]; 1055fb4d8502Sjsg 1056fb4d8502Sjsg if (size & 3 || *pos & 3) 1057fb4d8502Sjsg return -EINVAL; 1058fb4d8502Sjsg 1059fb4d8502Sjsg /* decode offset */ 1060fb4d8502Sjsg offset = (*pos & GENMASK_ULL(6, 0)); 1061fb4d8502Sjsg se = (*pos & GENMASK_ULL(14, 7)) >> 7; 1062fb4d8502Sjsg sh = (*pos & GENMASK_ULL(22, 15)) >> 15; 1063fb4d8502Sjsg cu = (*pos & GENMASK_ULL(30, 23)) >> 23; 1064fb4d8502Sjsg wave = (*pos & GENMASK_ULL(36, 31)) >> 31; 1065fb4d8502Sjsg simd = (*pos & GENMASK_ULL(44, 37)) >> 37; 1066fb4d8502Sjsg 1067ad8b1aafSjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 1068ad8b1aafSjsg if (r < 0) { 1069ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 1070c349dbc7Sjsg return r; 1071ad8b1aafSjsg } 1072ad8b1aafSjsg 1073ad8b1aafSjsg r = amdgpu_virt_enable_access_debugfs(adev); 1074ad8b1aafSjsg if (r < 0) { 1075ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 1076ad8b1aafSjsg return r; 1077ad8b1aafSjsg } 1078c349dbc7Sjsg 1079fb4d8502Sjsg /* switch to the specific se/sh/cu */ 1080fb4d8502Sjsg mutex_lock(&adev->grbm_idx_mutex); 1081f005ef32Sjsg amdgpu_gfx_select_se_sh(adev, se, sh, cu, 0); 1082fb4d8502Sjsg 1083fb4d8502Sjsg x = 0; 1084fb4d8502Sjsg if (adev->gfx.funcs->read_wave_data) 1085f005ef32Sjsg adev->gfx.funcs->read_wave_data(adev, 0, simd, wave, data, &x); 1086fb4d8502Sjsg 1087f005ef32Sjsg amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0); 1088fb4d8502Sjsg mutex_unlock(&adev->grbm_idx_mutex); 1089fb4d8502Sjsg 1090ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 1091ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 1092c349dbc7Sjsg 1093ad8b1aafSjsg if (!x) { 1094ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 1095fb4d8502Sjsg return -EINVAL; 1096ad8b1aafSjsg } 1097fb4d8502Sjsg 1098fb4d8502Sjsg while (size && (offset < x * 4)) { 1099fb4d8502Sjsg uint32_t value; 1100fb4d8502Sjsg 1101fb4d8502Sjsg value = data[offset >> 2]; 1102fb4d8502Sjsg r = put_user(value, (uint32_t *)buf); 1103ad8b1aafSjsg if (r) { 1104ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 1105fb4d8502Sjsg return r; 1106ad8b1aafSjsg } 1107fb4d8502Sjsg 1108fb4d8502Sjsg result += 4; 1109fb4d8502Sjsg buf += 4; 1110fb4d8502Sjsg offset += 4; 1111fb4d8502Sjsg size -= 4; 1112fb4d8502Sjsg } 1113fb4d8502Sjsg 1114ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 1115fb4d8502Sjsg return result; 1116fb4d8502Sjsg } 1117fb4d8502Sjsg 1118fb4d8502Sjsg /** amdgpu_debugfs_gpr_read - Read wave gprs 1119fb4d8502Sjsg * 1120fb4d8502Sjsg * @f: open file handle 1121fb4d8502Sjsg * @buf: User buffer to store read data in 1122fb4d8502Sjsg * @size: Number of bytes to read 1123fb4d8502Sjsg * @pos: Offset to seek to 1124fb4d8502Sjsg * 1125fb4d8502Sjsg * The offset being sought changes which wave that the status data 1126fb4d8502Sjsg * will be returned for. The bits are used as follows: 1127fb4d8502Sjsg * 1128fb4d8502Sjsg * Bits 0..11: Byte offset into data 1129fb4d8502Sjsg * Bits 12..19: SE selector 1130fb4d8502Sjsg * Bits 20..27: SH/SA selector 1131fb4d8502Sjsg * Bits 28..35: CU/{WGP+SIMD} selector 1132fb4d8502Sjsg * Bits 36..43: WAVE ID selector 1133fb4d8502Sjsg * Bits 37..44: SIMD ID selector 1134fb4d8502Sjsg * Bits 52..59: Thread selector 1135fb4d8502Sjsg * Bits 60..61: Bank selector (VGPR=0,SGPR=1) 1136fb4d8502Sjsg * 1137fb4d8502Sjsg * The return data comes from the SGPR or VGPR register bank for 1138fb4d8502Sjsg * the selected operational unit. 1139fb4d8502Sjsg */ 1140fb4d8502Sjsg static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, 1141fb4d8502Sjsg size_t size, loff_t *pos) 1142fb4d8502Sjsg { 1143fb4d8502Sjsg struct amdgpu_device *adev = f->f_inode->i_private; 1144fb4d8502Sjsg int r; 1145fb4d8502Sjsg ssize_t result = 0; 1146fb4d8502Sjsg uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data; 1147fb4d8502Sjsg 11483f25a8deSjsg if (size > 4096 || size & 3 || *pos & 3) 1149fb4d8502Sjsg return -EINVAL; 1150fb4d8502Sjsg 1151fb4d8502Sjsg /* decode offset */ 11523f25a8deSjsg offset = (*pos & GENMASK_ULL(11, 0)) >> 2; 1153fb4d8502Sjsg se = (*pos & GENMASK_ULL(19, 12)) >> 12; 1154fb4d8502Sjsg sh = (*pos & GENMASK_ULL(27, 20)) >> 20; 1155fb4d8502Sjsg cu = (*pos & GENMASK_ULL(35, 28)) >> 28; 1156fb4d8502Sjsg wave = (*pos & GENMASK_ULL(43, 36)) >> 36; 1157fb4d8502Sjsg simd = (*pos & GENMASK_ULL(51, 44)) >> 44; 1158fb4d8502Sjsg thread = (*pos & GENMASK_ULL(59, 52)) >> 52; 1159fb4d8502Sjsg bank = (*pos & GENMASK_ULL(61, 60)) >> 60; 1160fb4d8502Sjsg 11612be7e6d1Sjsg data = kcalloc(1024, sizeof(*data), GFP_KERNEL); 1162fb4d8502Sjsg if (!data) 1163fb4d8502Sjsg return -ENOMEM; 1164fb4d8502Sjsg 1165ad8b1aafSjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 1166c349dbc7Sjsg if (r < 0) 1167ad8b1aafSjsg goto err; 1168ad8b1aafSjsg 1169ad8b1aafSjsg r = amdgpu_virt_enable_access_debugfs(adev); 1170ad8b1aafSjsg if (r < 0) 1171ad8b1aafSjsg goto err; 1172c349dbc7Sjsg 1173fb4d8502Sjsg /* switch to the specific se/sh/cu */ 1174fb4d8502Sjsg mutex_lock(&adev->grbm_idx_mutex); 1175f005ef32Sjsg amdgpu_gfx_select_se_sh(adev, se, sh, cu, 0); 1176fb4d8502Sjsg 1177fb4d8502Sjsg if (bank == 0) { 1178fb4d8502Sjsg if (adev->gfx.funcs->read_wave_vgprs) 1179f005ef32Sjsg adev->gfx.funcs->read_wave_vgprs(adev, 0, simd, wave, thread, offset, size>>2, data); 1180fb4d8502Sjsg } else { 1181fb4d8502Sjsg if (adev->gfx.funcs->read_wave_sgprs) 1182f005ef32Sjsg adev->gfx.funcs->read_wave_sgprs(adev, 0, simd, wave, offset, size>>2, data); 1183fb4d8502Sjsg } 1184fb4d8502Sjsg 1185f005ef32Sjsg amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0); 1186fb4d8502Sjsg mutex_unlock(&adev->grbm_idx_mutex); 1187fb4d8502Sjsg 1188ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 1189ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 1190c349dbc7Sjsg 1191fb4d8502Sjsg while (size) { 1192fb4d8502Sjsg uint32_t value; 1193fb4d8502Sjsg 11943f25a8deSjsg value = data[result >> 2]; 1195fb4d8502Sjsg r = put_user(value, (uint32_t *)buf); 1196fb4d8502Sjsg if (r) { 1197ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 1198fb4d8502Sjsg goto err; 1199fb4d8502Sjsg } 1200fb4d8502Sjsg 1201fb4d8502Sjsg result += 4; 1202fb4d8502Sjsg buf += 4; 1203fb4d8502Sjsg size -= 4; 1204fb4d8502Sjsg } 1205fb4d8502Sjsg 1206fb4d8502Sjsg kfree(data); 1207ad8b1aafSjsg amdgpu_virt_disable_access_debugfs(adev); 1208fb4d8502Sjsg return result; 1209ad8b1aafSjsg 1210ad8b1aafSjsg err: 1211ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 1212ad8b1aafSjsg kfree(data); 1213ad8b1aafSjsg return r; 1214fb4d8502Sjsg } 1215fb4d8502Sjsg 1216c349dbc7Sjsg /** 12171bb76ff1Sjsg * amdgpu_debugfs_gfxoff_residency_read - Read GFXOFF residency 12181bb76ff1Sjsg * 12191bb76ff1Sjsg * @f: open file handle 12201bb76ff1Sjsg * @buf: User buffer to store read data in 12211bb76ff1Sjsg * @size: Number of bytes to read 12221bb76ff1Sjsg * @pos: Offset to seek to 12231bb76ff1Sjsg * 12241bb76ff1Sjsg * Read the last residency value logged. It doesn't auto update, one needs to 12251bb76ff1Sjsg * stop logging before getting the current value. 12261bb76ff1Sjsg */ 12271bb76ff1Sjsg static ssize_t amdgpu_debugfs_gfxoff_residency_read(struct file *f, char __user *buf, 12281bb76ff1Sjsg size_t size, loff_t *pos) 12291bb76ff1Sjsg { 12301bb76ff1Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 12311bb76ff1Sjsg ssize_t result = 0; 12321bb76ff1Sjsg int r; 12331bb76ff1Sjsg 12341bb76ff1Sjsg if (size & 0x3 || *pos & 0x3) 12351bb76ff1Sjsg return -EINVAL; 12361bb76ff1Sjsg 12371bb76ff1Sjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 12381bb76ff1Sjsg if (r < 0) { 12391bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 12401bb76ff1Sjsg return r; 12411bb76ff1Sjsg } 12421bb76ff1Sjsg 12431bb76ff1Sjsg while (size) { 12441bb76ff1Sjsg uint32_t value; 12451bb76ff1Sjsg 12461bb76ff1Sjsg r = amdgpu_get_gfx_off_residency(adev, &value); 12471bb76ff1Sjsg if (r) 12481bb76ff1Sjsg goto out; 12491bb76ff1Sjsg 12501bb76ff1Sjsg r = put_user(value, (uint32_t *)buf); 12511bb76ff1Sjsg if (r) 12521bb76ff1Sjsg goto out; 12531bb76ff1Sjsg 12541bb76ff1Sjsg result += 4; 12551bb76ff1Sjsg buf += 4; 12561bb76ff1Sjsg *pos += 4; 12571bb76ff1Sjsg size -= 4; 12581bb76ff1Sjsg } 12591bb76ff1Sjsg 12601bb76ff1Sjsg r = result; 12611bb76ff1Sjsg out: 12621bb76ff1Sjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 12631bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 12641bb76ff1Sjsg 12651bb76ff1Sjsg return r; 12661bb76ff1Sjsg } 12671bb76ff1Sjsg 12681bb76ff1Sjsg /** 12691bb76ff1Sjsg * amdgpu_debugfs_gfxoff_residency_write - Log GFXOFF Residency 12701bb76ff1Sjsg * 12711bb76ff1Sjsg * @f: open file handle 12721bb76ff1Sjsg * @buf: User buffer to write data from 12731bb76ff1Sjsg * @size: Number of bytes to write 12741bb76ff1Sjsg * @pos: Offset to seek to 12751bb76ff1Sjsg * 12761bb76ff1Sjsg * Write a 32-bit non-zero to start logging; write a 32-bit zero to stop 12771bb76ff1Sjsg */ 12781bb76ff1Sjsg static ssize_t amdgpu_debugfs_gfxoff_residency_write(struct file *f, const char __user *buf, 12791bb76ff1Sjsg size_t size, loff_t *pos) 12801bb76ff1Sjsg { 12811bb76ff1Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 12821bb76ff1Sjsg ssize_t result = 0; 12831bb76ff1Sjsg int r; 12841bb76ff1Sjsg 12851bb76ff1Sjsg if (size & 0x3 || *pos & 0x3) 12861bb76ff1Sjsg return -EINVAL; 12871bb76ff1Sjsg 12881bb76ff1Sjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 12891bb76ff1Sjsg if (r < 0) { 12901bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 12911bb76ff1Sjsg return r; 12921bb76ff1Sjsg } 12931bb76ff1Sjsg 12941bb76ff1Sjsg while (size) { 12951bb76ff1Sjsg u32 value; 12961bb76ff1Sjsg 12971bb76ff1Sjsg r = get_user(value, (uint32_t *)buf); 12981bb76ff1Sjsg if (r) 12991bb76ff1Sjsg goto out; 13001bb76ff1Sjsg 13011bb76ff1Sjsg amdgpu_set_gfx_off_residency(adev, value ? true : false); 13021bb76ff1Sjsg 13031bb76ff1Sjsg result += 4; 13041bb76ff1Sjsg buf += 4; 13051bb76ff1Sjsg *pos += 4; 13061bb76ff1Sjsg size -= 4; 13071bb76ff1Sjsg } 13081bb76ff1Sjsg 13091bb76ff1Sjsg r = result; 13101bb76ff1Sjsg out: 13111bb76ff1Sjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 13121bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 13131bb76ff1Sjsg 13141bb76ff1Sjsg return r; 13151bb76ff1Sjsg } 13161bb76ff1Sjsg 13171bb76ff1Sjsg 13181bb76ff1Sjsg /** 13191bb76ff1Sjsg * amdgpu_debugfs_gfxoff_count_read - Read GFXOFF entry count 13201bb76ff1Sjsg * 13211bb76ff1Sjsg * @f: open file handle 13221bb76ff1Sjsg * @buf: User buffer to store read data in 13231bb76ff1Sjsg * @size: Number of bytes to read 13241bb76ff1Sjsg * @pos: Offset to seek to 13251bb76ff1Sjsg */ 13261bb76ff1Sjsg static ssize_t amdgpu_debugfs_gfxoff_count_read(struct file *f, char __user *buf, 13271bb76ff1Sjsg size_t size, loff_t *pos) 13281bb76ff1Sjsg { 13291bb76ff1Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 13301bb76ff1Sjsg ssize_t result = 0; 13311bb76ff1Sjsg int r; 13321bb76ff1Sjsg 13331bb76ff1Sjsg if (size & 0x3 || *pos & 0x3) 13341bb76ff1Sjsg return -EINVAL; 13351bb76ff1Sjsg 13361bb76ff1Sjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 13371bb76ff1Sjsg if (r < 0) { 13381bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 13391bb76ff1Sjsg return r; 13401bb76ff1Sjsg } 13411bb76ff1Sjsg 13421bb76ff1Sjsg while (size) { 13431bb76ff1Sjsg u64 value = 0; 13441bb76ff1Sjsg 13451bb76ff1Sjsg r = amdgpu_get_gfx_off_entrycount(adev, &value); 13461bb76ff1Sjsg if (r) 13471bb76ff1Sjsg goto out; 13481bb76ff1Sjsg 13491bb76ff1Sjsg r = put_user(value, (u64 *)buf); 13501bb76ff1Sjsg if (r) 13511bb76ff1Sjsg goto out; 13521bb76ff1Sjsg 13531bb76ff1Sjsg result += 4; 13541bb76ff1Sjsg buf += 4; 13551bb76ff1Sjsg *pos += 4; 13561bb76ff1Sjsg size -= 4; 13571bb76ff1Sjsg } 13581bb76ff1Sjsg 13591bb76ff1Sjsg r = result; 13601bb76ff1Sjsg out: 13611bb76ff1Sjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 13621bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 13631bb76ff1Sjsg 13641bb76ff1Sjsg return r; 13651bb76ff1Sjsg } 13661bb76ff1Sjsg 13671bb76ff1Sjsg /** 13685ca02815Sjsg * amdgpu_debugfs_gfxoff_write - Enable/disable GFXOFF 1369c349dbc7Sjsg * 1370c349dbc7Sjsg * @f: open file handle 1371c349dbc7Sjsg * @buf: User buffer to write data from 1372c349dbc7Sjsg * @size: Number of bytes to write 1373c349dbc7Sjsg * @pos: Offset to seek to 1374c349dbc7Sjsg * 1375c349dbc7Sjsg * Write a 32-bit zero to disable or a 32-bit non-zero to enable 1376c349dbc7Sjsg */ 1377c349dbc7Sjsg static ssize_t amdgpu_debugfs_gfxoff_write(struct file *f, const char __user *buf, 1378c349dbc7Sjsg size_t size, loff_t *pos) 1379c349dbc7Sjsg { 1380c349dbc7Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 1381c349dbc7Sjsg ssize_t result = 0; 1382c349dbc7Sjsg int r; 1383c349dbc7Sjsg 1384c349dbc7Sjsg if (size & 0x3 || *pos & 0x3) 1385c349dbc7Sjsg return -EINVAL; 1386c349dbc7Sjsg 1387ad8b1aafSjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 1388ad8b1aafSjsg if (r < 0) { 1389ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 1390c349dbc7Sjsg return r; 1391ad8b1aafSjsg } 1392c349dbc7Sjsg 1393c349dbc7Sjsg while (size) { 1394c349dbc7Sjsg uint32_t value; 1395c349dbc7Sjsg 1396c349dbc7Sjsg r = get_user(value, (uint32_t *)buf); 13971bb76ff1Sjsg if (r) 13981bb76ff1Sjsg goto out; 1399c349dbc7Sjsg 1400c349dbc7Sjsg amdgpu_gfx_off_ctrl(adev, value ? true : false); 1401c349dbc7Sjsg 1402c349dbc7Sjsg result += 4; 1403c349dbc7Sjsg buf += 4; 1404c349dbc7Sjsg *pos += 4; 1405c349dbc7Sjsg size -= 4; 1406c349dbc7Sjsg } 1407c349dbc7Sjsg 14081bb76ff1Sjsg r = result; 14091bb76ff1Sjsg out: 1410ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 1411ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 1412c349dbc7Sjsg 14131bb76ff1Sjsg return r; 1414c349dbc7Sjsg } 1415c349dbc7Sjsg 1416c349dbc7Sjsg 1417ad8b1aafSjsg /** 14185ca02815Sjsg * amdgpu_debugfs_gfxoff_read - read gfxoff status 1419ad8b1aafSjsg * 1420ad8b1aafSjsg * @f: open file handle 1421ad8b1aafSjsg * @buf: User buffer to store read data in 1422ad8b1aafSjsg * @size: Number of bytes to read 1423ad8b1aafSjsg * @pos: Offset to seek to 1424ad8b1aafSjsg */ 1425ad8b1aafSjsg static ssize_t amdgpu_debugfs_gfxoff_read(struct file *f, char __user *buf, 1426ad8b1aafSjsg size_t size, loff_t *pos) 1427ad8b1aafSjsg { 1428ad8b1aafSjsg struct amdgpu_device *adev = file_inode(f)->i_private; 1429ad8b1aafSjsg ssize_t result = 0; 1430ad8b1aafSjsg int r; 1431ad8b1aafSjsg 1432ad8b1aafSjsg if (size & 0x3 || *pos & 0x3) 1433ad8b1aafSjsg return -EINVAL; 1434ad8b1aafSjsg 1435ad8b1aafSjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 14361bb76ff1Sjsg if (r < 0) { 14371bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 1438ad8b1aafSjsg return r; 14391bb76ff1Sjsg } 1440ad8b1aafSjsg 1441ad8b1aafSjsg while (size) { 14421bb76ff1Sjsg u32 value = adev->gfx.gfx_off_state; 1443ad8b1aafSjsg 14441bb76ff1Sjsg r = put_user(value, (u32 *)buf); 14451bb76ff1Sjsg if (r) 14461bb76ff1Sjsg goto out; 1447ad8b1aafSjsg 1448ad8b1aafSjsg result += 4; 1449ad8b1aafSjsg buf += 4; 1450ad8b1aafSjsg *pos += 4; 1451ad8b1aafSjsg size -= 4; 1452ad8b1aafSjsg } 1453ad8b1aafSjsg 14541bb76ff1Sjsg r = result; 14551bb76ff1Sjsg out: 1456ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 1457ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 1458ad8b1aafSjsg 14591bb76ff1Sjsg return r; 1460ad8b1aafSjsg } 1461ad8b1aafSjsg 14621bb76ff1Sjsg static ssize_t amdgpu_debugfs_gfxoff_status_read(struct file *f, char __user *buf, 14631bb76ff1Sjsg size_t size, loff_t *pos) 14641bb76ff1Sjsg { 14651bb76ff1Sjsg struct amdgpu_device *adev = file_inode(f)->i_private; 14661bb76ff1Sjsg ssize_t result = 0; 14671bb76ff1Sjsg int r; 14681bb76ff1Sjsg 14691bb76ff1Sjsg if (size & 0x3 || *pos & 0x3) 14701bb76ff1Sjsg return -EINVAL; 14711bb76ff1Sjsg 14721bb76ff1Sjsg r = pm_runtime_get_sync(adev_to_drm(adev)->dev); 14731bb76ff1Sjsg if (r < 0) { 14741bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 14751bb76ff1Sjsg return r; 14761bb76ff1Sjsg } 14771bb76ff1Sjsg 14781bb76ff1Sjsg while (size) { 14791bb76ff1Sjsg u32 value; 14801bb76ff1Sjsg 14811bb76ff1Sjsg r = amdgpu_get_gfx_off_status(adev, &value); 14821bb76ff1Sjsg if (r) 14831bb76ff1Sjsg goto out; 14841bb76ff1Sjsg 14851bb76ff1Sjsg r = put_user(value, (u32 *)buf); 14861bb76ff1Sjsg if (r) 14871bb76ff1Sjsg goto out; 14881bb76ff1Sjsg 14891bb76ff1Sjsg result += 4; 14901bb76ff1Sjsg buf += 4; 14911bb76ff1Sjsg *pos += 4; 14921bb76ff1Sjsg size -= 4; 14931bb76ff1Sjsg } 14941bb76ff1Sjsg 14951bb76ff1Sjsg r = result; 14961bb76ff1Sjsg out: 14971bb76ff1Sjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 14981bb76ff1Sjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 14991bb76ff1Sjsg 15001bb76ff1Sjsg return r; 15011bb76ff1Sjsg } 15021bb76ff1Sjsg 15031bb76ff1Sjsg static const struct file_operations amdgpu_debugfs_regs2_fops = { 15041bb76ff1Sjsg .owner = THIS_MODULE, 15051bb76ff1Sjsg .unlocked_ioctl = amdgpu_debugfs_regs2_ioctl, 15061bb76ff1Sjsg .read = amdgpu_debugfs_regs2_read, 15071bb76ff1Sjsg .write = amdgpu_debugfs_regs2_write, 15081bb76ff1Sjsg .open = amdgpu_debugfs_regs2_open, 15091bb76ff1Sjsg .release = amdgpu_debugfs_regs2_release, 15101bb76ff1Sjsg .llseek = default_llseek 15111bb76ff1Sjsg }; 15121bb76ff1Sjsg 1513f005ef32Sjsg static const struct file_operations amdgpu_debugfs_gprwave_fops = { 1514f005ef32Sjsg .owner = THIS_MODULE, 1515f005ef32Sjsg .unlocked_ioctl = amdgpu_debugfs_gprwave_ioctl, 1516f005ef32Sjsg .read = amdgpu_debugfs_gprwave_read, 1517f005ef32Sjsg .open = amdgpu_debugfs_gprwave_open, 1518f005ef32Sjsg .release = amdgpu_debugfs_gprwave_release, 1519f005ef32Sjsg .llseek = default_llseek 1520f005ef32Sjsg }; 1521f005ef32Sjsg 1522fb4d8502Sjsg static const struct file_operations amdgpu_debugfs_regs_fops = { 1523fb4d8502Sjsg .owner = THIS_MODULE, 1524fb4d8502Sjsg .read = amdgpu_debugfs_regs_read, 1525fb4d8502Sjsg .write = amdgpu_debugfs_regs_write, 1526fb4d8502Sjsg .llseek = default_llseek 1527fb4d8502Sjsg }; 1528fb4d8502Sjsg static const struct file_operations amdgpu_debugfs_regs_didt_fops = { 1529fb4d8502Sjsg .owner = THIS_MODULE, 1530fb4d8502Sjsg .read = amdgpu_debugfs_regs_didt_read, 1531fb4d8502Sjsg .write = amdgpu_debugfs_regs_didt_write, 1532fb4d8502Sjsg .llseek = default_llseek 1533fb4d8502Sjsg }; 1534fb4d8502Sjsg static const struct file_operations amdgpu_debugfs_regs_pcie_fops = { 1535fb4d8502Sjsg .owner = THIS_MODULE, 1536fb4d8502Sjsg .read = amdgpu_debugfs_regs_pcie_read, 1537fb4d8502Sjsg .write = amdgpu_debugfs_regs_pcie_write, 1538fb4d8502Sjsg .llseek = default_llseek 1539fb4d8502Sjsg }; 1540fb4d8502Sjsg static const struct file_operations amdgpu_debugfs_regs_smc_fops = { 1541fb4d8502Sjsg .owner = THIS_MODULE, 1542fb4d8502Sjsg .read = amdgpu_debugfs_regs_smc_read, 1543fb4d8502Sjsg .write = amdgpu_debugfs_regs_smc_write, 1544fb4d8502Sjsg .llseek = default_llseek 1545fb4d8502Sjsg }; 1546fb4d8502Sjsg 1547fb4d8502Sjsg static const struct file_operations amdgpu_debugfs_gca_config_fops = { 1548fb4d8502Sjsg .owner = THIS_MODULE, 1549fb4d8502Sjsg .read = amdgpu_debugfs_gca_config_read, 1550fb4d8502Sjsg .llseek = default_llseek 1551fb4d8502Sjsg }; 1552fb4d8502Sjsg 1553fb4d8502Sjsg static const struct file_operations amdgpu_debugfs_sensors_fops = { 1554fb4d8502Sjsg .owner = THIS_MODULE, 1555fb4d8502Sjsg .read = amdgpu_debugfs_sensor_read, 1556fb4d8502Sjsg .llseek = default_llseek 1557fb4d8502Sjsg }; 1558fb4d8502Sjsg 1559fb4d8502Sjsg static const struct file_operations amdgpu_debugfs_wave_fops = { 1560fb4d8502Sjsg .owner = THIS_MODULE, 1561fb4d8502Sjsg .read = amdgpu_debugfs_wave_read, 1562fb4d8502Sjsg .llseek = default_llseek 1563fb4d8502Sjsg }; 1564fb4d8502Sjsg static const struct file_operations amdgpu_debugfs_gpr_fops = { 1565fb4d8502Sjsg .owner = THIS_MODULE, 1566fb4d8502Sjsg .read = amdgpu_debugfs_gpr_read, 1567fb4d8502Sjsg .llseek = default_llseek 1568fb4d8502Sjsg }; 1569fb4d8502Sjsg 1570c349dbc7Sjsg static const struct file_operations amdgpu_debugfs_gfxoff_fops = { 1571c349dbc7Sjsg .owner = THIS_MODULE, 1572ad8b1aafSjsg .read = amdgpu_debugfs_gfxoff_read, 1573c349dbc7Sjsg .write = amdgpu_debugfs_gfxoff_write, 1574ad8b1aafSjsg .llseek = default_llseek 1575c349dbc7Sjsg }; 1576c349dbc7Sjsg 15771bb76ff1Sjsg static const struct file_operations amdgpu_debugfs_gfxoff_status_fops = { 15781bb76ff1Sjsg .owner = THIS_MODULE, 15791bb76ff1Sjsg .read = amdgpu_debugfs_gfxoff_status_read, 15801bb76ff1Sjsg .llseek = default_llseek 15811bb76ff1Sjsg }; 15821bb76ff1Sjsg 15831bb76ff1Sjsg static const struct file_operations amdgpu_debugfs_gfxoff_count_fops = { 15841bb76ff1Sjsg .owner = THIS_MODULE, 15851bb76ff1Sjsg .read = amdgpu_debugfs_gfxoff_count_read, 15861bb76ff1Sjsg .llseek = default_llseek 15871bb76ff1Sjsg }; 15881bb76ff1Sjsg 15891bb76ff1Sjsg static const struct file_operations amdgpu_debugfs_gfxoff_residency_fops = { 15901bb76ff1Sjsg .owner = THIS_MODULE, 15911bb76ff1Sjsg .read = amdgpu_debugfs_gfxoff_residency_read, 15921bb76ff1Sjsg .write = amdgpu_debugfs_gfxoff_residency_write, 15931bb76ff1Sjsg .llseek = default_llseek 15941bb76ff1Sjsg }; 15951bb76ff1Sjsg 1596fb4d8502Sjsg static const struct file_operations *debugfs_regs[] = { 1597fb4d8502Sjsg &amdgpu_debugfs_regs_fops, 15981bb76ff1Sjsg &amdgpu_debugfs_regs2_fops, 1599f005ef32Sjsg &amdgpu_debugfs_gprwave_fops, 1600fb4d8502Sjsg &amdgpu_debugfs_regs_didt_fops, 1601fb4d8502Sjsg &amdgpu_debugfs_regs_pcie_fops, 1602fb4d8502Sjsg &amdgpu_debugfs_regs_smc_fops, 1603fb4d8502Sjsg &amdgpu_debugfs_gca_config_fops, 1604fb4d8502Sjsg &amdgpu_debugfs_sensors_fops, 1605fb4d8502Sjsg &amdgpu_debugfs_wave_fops, 1606fb4d8502Sjsg &amdgpu_debugfs_gpr_fops, 1607c349dbc7Sjsg &amdgpu_debugfs_gfxoff_fops, 16081bb76ff1Sjsg &amdgpu_debugfs_gfxoff_status_fops, 16091bb76ff1Sjsg &amdgpu_debugfs_gfxoff_count_fops, 16101bb76ff1Sjsg &amdgpu_debugfs_gfxoff_residency_fops, 1611fb4d8502Sjsg }; 1612fb4d8502Sjsg 1613f005ef32Sjsg static const char * const debugfs_regs_names[] = { 1614fb4d8502Sjsg "amdgpu_regs", 16151bb76ff1Sjsg "amdgpu_regs2", 1616f005ef32Sjsg "amdgpu_gprwave", 1617fb4d8502Sjsg "amdgpu_regs_didt", 1618fb4d8502Sjsg "amdgpu_regs_pcie", 1619fb4d8502Sjsg "amdgpu_regs_smc", 1620fb4d8502Sjsg "amdgpu_gca_config", 1621fb4d8502Sjsg "amdgpu_sensors", 1622fb4d8502Sjsg "amdgpu_wave", 1623fb4d8502Sjsg "amdgpu_gpr", 1624c349dbc7Sjsg "amdgpu_gfxoff", 16251bb76ff1Sjsg "amdgpu_gfxoff_status", 16261bb76ff1Sjsg "amdgpu_gfxoff_count", 16271bb76ff1Sjsg "amdgpu_gfxoff_residency", 1628fb4d8502Sjsg }; 1629fb4d8502Sjsg 1630fb4d8502Sjsg /** 1631fb4d8502Sjsg * amdgpu_debugfs_regs_init - Initialize debugfs entries that provide 1632fb4d8502Sjsg * register access. 1633fb4d8502Sjsg * 1634fb4d8502Sjsg * @adev: The device to attach the debugfs entries to 1635fb4d8502Sjsg */ 1636fb4d8502Sjsg int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) 1637fb4d8502Sjsg { 1638ad8b1aafSjsg struct drm_minor *minor = adev_to_drm(adev)->primary; 1639fb4d8502Sjsg struct dentry *ent, *root = minor->debugfs_root; 1640c349dbc7Sjsg unsigned int i; 1641fb4d8502Sjsg 1642fb4d8502Sjsg for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) { 1643fb4d8502Sjsg ent = debugfs_create_file(debugfs_regs_names[i], 1644*bbaa42a2Sjsg S_IFREG | 0400, root, 1645fb4d8502Sjsg adev, debugfs_regs[i]); 1646c349dbc7Sjsg if (!i && !IS_ERR_OR_NULL(ent)) 1647fb4d8502Sjsg i_size_write(ent->d_inode, adev->rmmio_size); 1648fb4d8502Sjsg } 1649fb4d8502Sjsg 1650fb4d8502Sjsg return 0; 1651fb4d8502Sjsg } 1652fb4d8502Sjsg 16535ca02815Sjsg static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused) 1654fb4d8502Sjsg { 1655f005ef32Sjsg struct amdgpu_device *adev = m->private; 16565ca02815Sjsg struct drm_device *dev = adev_to_drm(adev); 1657fb4d8502Sjsg int r = 0, i; 1658fb4d8502Sjsg 1659c349dbc7Sjsg r = pm_runtime_get_sync(dev->dev); 1660ad8b1aafSjsg if (r < 0) { 16615ca02815Sjsg pm_runtime_put_autosuspend(dev->dev); 1662c349dbc7Sjsg return r; 1663ad8b1aafSjsg } 1664c349dbc7Sjsg 1665c349dbc7Sjsg /* Avoid accidently unparking the sched thread during GPU reset */ 16661bb76ff1Sjsg r = down_write_killable(&adev->reset_domain->sem); 1667ad8b1aafSjsg if (r) 1668ad8b1aafSjsg return r; 1669c349dbc7Sjsg 1670fb4d8502Sjsg /* hold on the scheduler */ 1671fb4d8502Sjsg for (i = 0; i < AMDGPU_MAX_RINGS; i++) { 1672fb4d8502Sjsg struct amdgpu_ring *ring = adev->rings[i]; 1673fb4d8502Sjsg 1674fb4d8502Sjsg if (!ring || !ring->sched.thread) 1675fb4d8502Sjsg continue; 1676fb4d8502Sjsg kthread_park(ring->sched.thread); 1677fb4d8502Sjsg } 1678fb4d8502Sjsg 1679f005ef32Sjsg seq_puts(m, "run ib test:\n"); 1680fb4d8502Sjsg r = amdgpu_ib_ring_tests(adev); 1681fb4d8502Sjsg if (r) 1682fb4d8502Sjsg seq_printf(m, "ib ring tests failed (%d).\n", r); 1683fb4d8502Sjsg else 1684f005ef32Sjsg seq_puts(m, "ib ring tests passed.\n"); 1685fb4d8502Sjsg 1686fb4d8502Sjsg /* go on the scheduler */ 1687fb4d8502Sjsg for (i = 0; i < AMDGPU_MAX_RINGS; i++) { 1688fb4d8502Sjsg struct amdgpu_ring *ring = adev->rings[i]; 1689fb4d8502Sjsg 1690fb4d8502Sjsg if (!ring || !ring->sched.thread) 1691fb4d8502Sjsg continue; 1692fb4d8502Sjsg kthread_unpark(ring->sched.thread); 1693fb4d8502Sjsg } 1694fb4d8502Sjsg 16951bb76ff1Sjsg up_write(&adev->reset_domain->sem); 1696c349dbc7Sjsg 1697c349dbc7Sjsg pm_runtime_mark_last_busy(dev->dev); 1698c349dbc7Sjsg pm_runtime_put_autosuspend(dev->dev); 1699c349dbc7Sjsg 1700fb4d8502Sjsg return 0; 1701fb4d8502Sjsg } 1702fb4d8502Sjsg 17035ca02815Sjsg static int amdgpu_debugfs_evict_vram(void *data, u64 *val) 1704fb4d8502Sjsg { 17055ca02815Sjsg struct amdgpu_device *adev = (struct amdgpu_device *)data; 17065ca02815Sjsg struct drm_device *dev = adev_to_drm(adev); 17075ca02815Sjsg int r; 1708fb4d8502Sjsg 17095ca02815Sjsg r = pm_runtime_get_sync(dev->dev); 17105ca02815Sjsg if (r < 0) { 17115ca02815Sjsg pm_runtime_put_autosuspend(dev->dev); 17125ca02815Sjsg return r; 17135ca02815Sjsg } 17145ca02815Sjsg 17158e01f7deSjsg *val = amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM); 17165ca02815Sjsg 17175ca02815Sjsg pm_runtime_mark_last_busy(dev->dev); 17185ca02815Sjsg pm_runtime_put_autosuspend(dev->dev); 17195ca02815Sjsg 1720fb4d8502Sjsg return 0; 1721fb4d8502Sjsg } 1722fb4d8502Sjsg 17235ca02815Sjsg 17245ca02815Sjsg static int amdgpu_debugfs_evict_gtt(void *data, u64 *val) 1725fb4d8502Sjsg { 17265ca02815Sjsg struct amdgpu_device *adev = (struct amdgpu_device *)data; 17275ca02815Sjsg struct drm_device *dev = adev_to_drm(adev); 1728c349dbc7Sjsg int r; 1729c349dbc7Sjsg 1730c349dbc7Sjsg r = pm_runtime_get_sync(dev->dev); 1731ad8b1aafSjsg if (r < 0) { 17328e01f7deSjsg pm_runtime_put_autosuspend(dev->dev); 1733c349dbc7Sjsg return r; 1734ad8b1aafSjsg } 1735fb4d8502Sjsg 17368e01f7deSjsg *val = amdgpu_ttm_evict_resources(adev, TTM_PL_TT); 1737c349dbc7Sjsg 1738c349dbc7Sjsg pm_runtime_mark_last_busy(dev->dev); 1739c349dbc7Sjsg pm_runtime_put_autosuspend(dev->dev); 1740c349dbc7Sjsg 1741fb4d8502Sjsg return 0; 1742fb4d8502Sjsg } 1743fb4d8502Sjsg 17441bb76ff1Sjsg static int amdgpu_debugfs_benchmark(void *data, u64 val) 17451bb76ff1Sjsg { 17461bb76ff1Sjsg struct amdgpu_device *adev = (struct amdgpu_device *)data; 17471bb76ff1Sjsg struct drm_device *dev = adev_to_drm(adev); 17481bb76ff1Sjsg int r; 17491bb76ff1Sjsg 17501bb76ff1Sjsg r = pm_runtime_get_sync(dev->dev); 17511bb76ff1Sjsg if (r < 0) { 17521bb76ff1Sjsg pm_runtime_put_autosuspend(dev->dev); 17531bb76ff1Sjsg return r; 17541bb76ff1Sjsg } 17551bb76ff1Sjsg 17561bb76ff1Sjsg r = amdgpu_benchmark(adev, val); 17571bb76ff1Sjsg 17581bb76ff1Sjsg pm_runtime_mark_last_busy(dev->dev); 17591bb76ff1Sjsg pm_runtime_put_autosuspend(dev->dev); 17601bb76ff1Sjsg 17611bb76ff1Sjsg return r; 17621bb76ff1Sjsg } 17635ca02815Sjsg 17645ca02815Sjsg static int amdgpu_debugfs_vm_info_show(struct seq_file *m, void *unused) 1765fb4d8502Sjsg { 1766f005ef32Sjsg struct amdgpu_device *adev = m->private; 17675ca02815Sjsg struct drm_device *dev = adev_to_drm(adev); 17685ca02815Sjsg struct drm_file *file; 1769c349dbc7Sjsg int r; 1770c349dbc7Sjsg 17715ca02815Sjsg r = mutex_lock_interruptible(&dev->filelist_mutex); 17725ca02815Sjsg if (r) 17735ca02815Sjsg return r; 17745ca02815Sjsg 17755ca02815Sjsg list_for_each_entry(file, &dev->filelist, lhead) { 17765ca02815Sjsg struct amdgpu_fpriv *fpriv = file->driver_priv; 17775ca02815Sjsg struct amdgpu_vm *vm = &fpriv->vm; 17785ca02815Sjsg 17795ca02815Sjsg seq_printf(m, "pid:%d\tProcess:%s ----------\n", 17805ca02815Sjsg vm->task_info.pid, vm->task_info.process_name); 17815ca02815Sjsg r = amdgpu_bo_reserve(vm->root.bo, true); 17825ca02815Sjsg if (r) 17835ca02815Sjsg break; 17845ca02815Sjsg amdgpu_debugfs_vm_bo_info(vm, m); 17855ca02815Sjsg amdgpu_bo_unreserve(vm->root.bo); 17865ca02815Sjsg } 17875ca02815Sjsg 17885ca02815Sjsg mutex_unlock(&dev->filelist_mutex); 17895ca02815Sjsg 1790c349dbc7Sjsg return r; 1791ad8b1aafSjsg } 1792fb4d8502Sjsg 17935ca02815Sjsg DEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_test_ib); 17945ca02815Sjsg DEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_vm_info); 17955ca02815Sjsg DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_evict_vram_fops, amdgpu_debugfs_evict_vram, 17965ca02815Sjsg NULL, "%lld\n"); 17975ca02815Sjsg DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_evict_gtt_fops, amdgpu_debugfs_evict_gtt, 17985ca02815Sjsg NULL, "%lld\n"); 17991bb76ff1Sjsg DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_benchmark_fops, NULL, amdgpu_debugfs_benchmark, 18001bb76ff1Sjsg "%lld\n"); 1801fb4d8502Sjsg 1802c349dbc7Sjsg static void amdgpu_ib_preempt_fences_swap(struct amdgpu_ring *ring, 1803c349dbc7Sjsg struct dma_fence **fences) 1804c349dbc7Sjsg { 1805c349dbc7Sjsg struct amdgpu_fence_driver *drv = &ring->fence_drv; 1806c349dbc7Sjsg uint32_t sync_seq, last_seq; 1807c349dbc7Sjsg 1808c349dbc7Sjsg last_seq = atomic_read(&ring->fence_drv.last_seq); 1809c349dbc7Sjsg sync_seq = ring->fence_drv.sync_seq; 1810c349dbc7Sjsg 1811c349dbc7Sjsg last_seq &= drv->num_fences_mask; 1812c349dbc7Sjsg sync_seq &= drv->num_fences_mask; 1813c349dbc7Sjsg 1814c349dbc7Sjsg do { 1815c349dbc7Sjsg struct dma_fence *fence, **ptr; 1816c349dbc7Sjsg 1817c349dbc7Sjsg ++last_seq; 1818c349dbc7Sjsg last_seq &= drv->num_fences_mask; 1819c349dbc7Sjsg ptr = &drv->fences[last_seq]; 1820c349dbc7Sjsg 1821c349dbc7Sjsg fence = rcu_dereference_protected(*ptr, 1); 1822c349dbc7Sjsg RCU_INIT_POINTER(*ptr, NULL); 1823c349dbc7Sjsg 1824c349dbc7Sjsg if (!fence) 1825c349dbc7Sjsg continue; 1826c349dbc7Sjsg 1827c349dbc7Sjsg fences[last_seq] = fence; 1828c349dbc7Sjsg 1829c349dbc7Sjsg } while (last_seq != sync_seq); 1830c349dbc7Sjsg } 1831c349dbc7Sjsg 1832c349dbc7Sjsg static void amdgpu_ib_preempt_signal_fences(struct dma_fence **fences, 1833c349dbc7Sjsg int length) 1834c349dbc7Sjsg { 1835c349dbc7Sjsg int i; 1836c349dbc7Sjsg struct dma_fence *fence; 1837c349dbc7Sjsg 1838c349dbc7Sjsg for (i = 0; i < length; i++) { 1839c349dbc7Sjsg fence = fences[i]; 1840c349dbc7Sjsg if (!fence) 1841c349dbc7Sjsg continue; 1842c349dbc7Sjsg dma_fence_signal(fence); 1843c349dbc7Sjsg dma_fence_put(fence); 1844c349dbc7Sjsg } 1845c349dbc7Sjsg } 1846c349dbc7Sjsg 1847c349dbc7Sjsg static void amdgpu_ib_preempt_job_recovery(struct drm_gpu_scheduler *sched) 1848c349dbc7Sjsg { 1849c349dbc7Sjsg struct drm_sched_job *s_job; 1850c349dbc7Sjsg struct dma_fence *fence; 1851c349dbc7Sjsg 1852c349dbc7Sjsg spin_lock(&sched->job_list_lock); 18535ca02815Sjsg list_for_each_entry(s_job, &sched->pending_list, list) { 1854c349dbc7Sjsg fence = sched->ops->run_job(s_job); 1855c349dbc7Sjsg dma_fence_put(fence); 1856c349dbc7Sjsg } 1857c349dbc7Sjsg spin_unlock(&sched->job_list_lock); 1858c349dbc7Sjsg } 1859c349dbc7Sjsg 1860c349dbc7Sjsg static void amdgpu_ib_preempt_mark_partial_job(struct amdgpu_ring *ring) 1861c349dbc7Sjsg { 1862c349dbc7Sjsg struct amdgpu_job *job; 186371f14979Sjsg struct drm_sched_job *s_job, *tmp; 1864c349dbc7Sjsg uint32_t preempt_seq; 1865c349dbc7Sjsg struct dma_fence *fence, **ptr; 1866c349dbc7Sjsg struct amdgpu_fence_driver *drv = &ring->fence_drv; 1867c349dbc7Sjsg struct drm_gpu_scheduler *sched = &ring->sched; 186871f14979Sjsg bool preempted = true; 1869c349dbc7Sjsg 1870c349dbc7Sjsg if (ring->funcs->type != AMDGPU_RING_TYPE_GFX) 1871c349dbc7Sjsg return; 1872c349dbc7Sjsg 1873c349dbc7Sjsg preempt_seq = le32_to_cpu(*(drv->cpu_addr + 2)); 187471f14979Sjsg if (preempt_seq <= atomic_read(&drv->last_seq)) { 187571f14979Sjsg preempted = false; 187671f14979Sjsg goto no_preempt; 187771f14979Sjsg } 1878c349dbc7Sjsg 1879c349dbc7Sjsg preempt_seq &= drv->num_fences_mask; 1880c349dbc7Sjsg ptr = &drv->fences[preempt_seq]; 1881c349dbc7Sjsg fence = rcu_dereference_protected(*ptr, 1); 1882c349dbc7Sjsg 188371f14979Sjsg no_preempt: 1884c349dbc7Sjsg spin_lock(&sched->job_list_lock); 18855ca02815Sjsg list_for_each_entry_safe(s_job, tmp, &sched->pending_list, list) { 188671f14979Sjsg if (dma_fence_is_signaled(&s_job->s_fence->finished)) { 188771f14979Sjsg /* remove job from ring_mirror_list */ 18885ca02815Sjsg list_del_init(&s_job->list); 188971f14979Sjsg sched->ops->free_job(s_job); 189071f14979Sjsg continue; 189171f14979Sjsg } 1892c349dbc7Sjsg job = to_amdgpu_job(s_job); 18935ca02815Sjsg if (preempted && (&job->hw_fence) == fence) 1894c349dbc7Sjsg /* mark the job as preempted */ 1895c349dbc7Sjsg job->preemption_status |= AMDGPU_IB_PREEMPTED; 1896c349dbc7Sjsg } 1897c349dbc7Sjsg spin_unlock(&sched->job_list_lock); 1898c349dbc7Sjsg } 1899c349dbc7Sjsg 1900c349dbc7Sjsg static int amdgpu_debugfs_ib_preempt(void *data, u64 val) 1901c349dbc7Sjsg { 1902f005ef32Sjsg int r, length; 1903c349dbc7Sjsg struct amdgpu_ring *ring; 1904c349dbc7Sjsg struct dma_fence **fences = NULL; 1905c349dbc7Sjsg struct amdgpu_device *adev = (struct amdgpu_device *)data; 1906c349dbc7Sjsg 1907c349dbc7Sjsg if (val >= AMDGPU_MAX_RINGS) 1908c349dbc7Sjsg return -EINVAL; 1909c349dbc7Sjsg 1910c349dbc7Sjsg ring = adev->rings[val]; 1911c349dbc7Sjsg 1912c349dbc7Sjsg if (!ring || !ring->funcs->preempt_ib || !ring->sched.thread) 1913c349dbc7Sjsg return -EINVAL; 1914c349dbc7Sjsg 1915c349dbc7Sjsg /* the last preemption failed */ 1916c349dbc7Sjsg if (ring->trail_seq != le32_to_cpu(*ring->trail_fence_cpu_addr)) 1917c349dbc7Sjsg return -EBUSY; 1918c349dbc7Sjsg 1919c349dbc7Sjsg length = ring->fence_drv.num_fences_mask + 1; 1920c349dbc7Sjsg fences = kcalloc(length, sizeof(void *), GFP_KERNEL); 1921c349dbc7Sjsg if (!fences) 1922c349dbc7Sjsg return -ENOMEM; 1923c349dbc7Sjsg 1924c349dbc7Sjsg /* Avoid accidently unparking the sched thread during GPU reset */ 19251bb76ff1Sjsg r = down_read_killable(&adev->reset_domain->sem); 1926ad8b1aafSjsg if (r) 1927ad8b1aafSjsg goto pro_end; 1928c349dbc7Sjsg 1929c349dbc7Sjsg /* stop the scheduler */ 1930c349dbc7Sjsg kthread_park(ring->sched.thread); 1931c349dbc7Sjsg 1932c349dbc7Sjsg /* preempt the IB */ 1933c349dbc7Sjsg r = amdgpu_ring_preempt_ib(ring); 1934c349dbc7Sjsg if (r) { 1935c349dbc7Sjsg DRM_WARN("failed to preempt ring %d\n", ring->idx); 1936c349dbc7Sjsg goto failure; 1937c349dbc7Sjsg } 1938c349dbc7Sjsg 1939c349dbc7Sjsg amdgpu_fence_process(ring); 1940c349dbc7Sjsg 1941c349dbc7Sjsg if (atomic_read(&ring->fence_drv.last_seq) != 1942c349dbc7Sjsg ring->fence_drv.sync_seq) { 1943c349dbc7Sjsg DRM_INFO("ring %d was preempted\n", ring->idx); 1944c349dbc7Sjsg 1945c349dbc7Sjsg amdgpu_ib_preempt_mark_partial_job(ring); 1946c349dbc7Sjsg 1947c349dbc7Sjsg /* swap out the old fences */ 1948c349dbc7Sjsg amdgpu_ib_preempt_fences_swap(ring, fences); 1949c349dbc7Sjsg 1950c349dbc7Sjsg amdgpu_fence_driver_force_completion(ring); 1951c349dbc7Sjsg 1952c349dbc7Sjsg /* resubmit unfinished jobs */ 1953c349dbc7Sjsg amdgpu_ib_preempt_job_recovery(&ring->sched); 1954c349dbc7Sjsg 1955c349dbc7Sjsg /* wait for jobs finished */ 1956c349dbc7Sjsg amdgpu_fence_wait_empty(ring); 1957c349dbc7Sjsg 1958c349dbc7Sjsg /* signal the old fences */ 1959c349dbc7Sjsg amdgpu_ib_preempt_signal_fences(fences, length); 1960c349dbc7Sjsg } 1961c349dbc7Sjsg 1962c349dbc7Sjsg failure: 1963c349dbc7Sjsg /* restart the scheduler */ 1964c349dbc7Sjsg kthread_unpark(ring->sched.thread); 1965c349dbc7Sjsg 19661bb76ff1Sjsg up_read(&adev->reset_domain->sem); 1967c349dbc7Sjsg 1968ad8b1aafSjsg pro_end: 1969c349dbc7Sjsg kfree(fences); 1970c349dbc7Sjsg 1971ad8b1aafSjsg return r; 1972c349dbc7Sjsg } 1973c349dbc7Sjsg 1974c349dbc7Sjsg static int amdgpu_debugfs_sclk_set(void *data, u64 val) 1975c349dbc7Sjsg { 1976c349dbc7Sjsg int ret = 0; 1977c349dbc7Sjsg uint32_t max_freq, min_freq; 1978c349dbc7Sjsg struct amdgpu_device *adev = (struct amdgpu_device *)data; 1979c349dbc7Sjsg 1980c349dbc7Sjsg if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) 1981c349dbc7Sjsg return -EINVAL; 1982c349dbc7Sjsg 1983ad8b1aafSjsg ret = pm_runtime_get_sync(adev_to_drm(adev)->dev); 1984ad8b1aafSjsg if (ret < 0) { 1985ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 1986c349dbc7Sjsg return ret; 1987ad8b1aafSjsg } 1988c349dbc7Sjsg 19891bb76ff1Sjsg ret = amdgpu_dpm_get_dpm_freq_range(adev, PP_SCLK, &min_freq, &max_freq); 19901bb76ff1Sjsg if (ret == -EOPNOTSUPP) { 19911bb76ff1Sjsg ret = 0; 19921bb76ff1Sjsg goto out; 19931bb76ff1Sjsg } 19941bb76ff1Sjsg if (ret || val > max_freq || val < min_freq) { 19951bb76ff1Sjsg ret = -EINVAL; 19961bb76ff1Sjsg goto out; 1997c349dbc7Sjsg } 1998c349dbc7Sjsg 19991bb76ff1Sjsg ret = amdgpu_dpm_set_soft_freq_range(adev, PP_SCLK, (uint32_t)val, (uint32_t)val); 20001bb76ff1Sjsg if (ret) 20011bb76ff1Sjsg ret = -EINVAL; 20021bb76ff1Sjsg 20031bb76ff1Sjsg out: 2004ad8b1aafSjsg pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); 2005ad8b1aafSjsg pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); 2006c349dbc7Sjsg 20071bb76ff1Sjsg return ret; 2008c349dbc7Sjsg } 2009c349dbc7Sjsg 20105ca02815Sjsg DEFINE_DEBUGFS_ATTRIBUTE(fops_ib_preempt, NULL, 2011c349dbc7Sjsg amdgpu_debugfs_ib_preempt, "%llu\n"); 2012c349dbc7Sjsg 20135ca02815Sjsg DEFINE_DEBUGFS_ATTRIBUTE(fops_sclk_set, NULL, 2014c349dbc7Sjsg amdgpu_debugfs_sclk_set, "%llu\n"); 2015c349dbc7Sjsg 20161bb76ff1Sjsg static ssize_t amdgpu_reset_dump_register_list_read(struct file *f, 20171bb76ff1Sjsg char __user *buf, size_t size, loff_t *pos) 20181bb76ff1Sjsg { 20191bb76ff1Sjsg struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private; 20201bb76ff1Sjsg char reg_offset[12]; 20211bb76ff1Sjsg int i, ret, len = 0; 20221bb76ff1Sjsg 20231bb76ff1Sjsg if (*pos) 20241bb76ff1Sjsg return 0; 20251bb76ff1Sjsg 20261bb76ff1Sjsg memset(reg_offset, 0, 12); 20271bb76ff1Sjsg ret = down_read_killable(&adev->reset_domain->sem); 20281bb76ff1Sjsg if (ret) 20291bb76ff1Sjsg return ret; 20301bb76ff1Sjsg 20311bb76ff1Sjsg for (i = 0; i < adev->num_regs; i++) { 20321bb76ff1Sjsg sprintf(reg_offset, "0x%x\n", adev->reset_dump_reg_list[i]); 20331bb76ff1Sjsg up_read(&adev->reset_domain->sem); 20341bb76ff1Sjsg if (copy_to_user(buf + len, reg_offset, strlen(reg_offset))) 20351bb76ff1Sjsg return -EFAULT; 20361bb76ff1Sjsg 20371bb76ff1Sjsg len += strlen(reg_offset); 20381bb76ff1Sjsg ret = down_read_killable(&adev->reset_domain->sem); 20391bb76ff1Sjsg if (ret) 20401bb76ff1Sjsg return ret; 20411bb76ff1Sjsg } 20421bb76ff1Sjsg 20431bb76ff1Sjsg up_read(&adev->reset_domain->sem); 20441bb76ff1Sjsg *pos += len; 20451bb76ff1Sjsg 20461bb76ff1Sjsg return len; 20471bb76ff1Sjsg } 20481bb76ff1Sjsg 20491bb76ff1Sjsg static ssize_t amdgpu_reset_dump_register_list_write(struct file *f, 20501bb76ff1Sjsg const char __user *buf, size_t size, loff_t *pos) 20511bb76ff1Sjsg { 20521bb76ff1Sjsg struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private; 20531bb76ff1Sjsg char reg_offset[11]; 20541bb76ff1Sjsg uint32_t *new = NULL, *tmp = NULL; 2055fb997c38Sjsg unsigned int len = 0; 2056fb997c38Sjsg int ret, i = 0; 20571bb76ff1Sjsg 20581bb76ff1Sjsg do { 20591bb76ff1Sjsg memset(reg_offset, 0, 11); 20601bb76ff1Sjsg if (copy_from_user(reg_offset, buf + len, 2061fb997c38Sjsg min(10, (size-len)))) { 20621bb76ff1Sjsg ret = -EFAULT; 20631bb76ff1Sjsg goto error_free; 20641bb76ff1Sjsg } 20651bb76ff1Sjsg 20661bb76ff1Sjsg new = krealloc_array(tmp, i + 1, sizeof(uint32_t), GFP_KERNEL); 20671bb76ff1Sjsg if (!new) { 20681bb76ff1Sjsg ret = -ENOMEM; 20691bb76ff1Sjsg goto error_free; 20701bb76ff1Sjsg } 20711bb76ff1Sjsg tmp = new; 20721bb76ff1Sjsg if (sscanf(reg_offset, "%X %n", &tmp[i], &ret) != 1) { 20731bb76ff1Sjsg ret = -EINVAL; 20741bb76ff1Sjsg goto error_free; 20751bb76ff1Sjsg } 20761bb76ff1Sjsg 20771bb76ff1Sjsg len += ret; 20781bb76ff1Sjsg i++; 20791bb76ff1Sjsg } while (len < size); 20801bb76ff1Sjsg 20811bb76ff1Sjsg new = kmalloc_array(i, sizeof(uint32_t), GFP_KERNEL); 20821bb76ff1Sjsg if (!new) { 20831bb76ff1Sjsg ret = -ENOMEM; 20841bb76ff1Sjsg goto error_free; 20851bb76ff1Sjsg } 20861bb76ff1Sjsg ret = down_write_killable(&adev->reset_domain->sem); 20871bb76ff1Sjsg if (ret) 20881bb76ff1Sjsg goto error_free; 20891bb76ff1Sjsg 20901bb76ff1Sjsg swap(adev->reset_dump_reg_list, tmp); 20911bb76ff1Sjsg swap(adev->reset_dump_reg_value, new); 20921bb76ff1Sjsg adev->num_regs = i; 20931bb76ff1Sjsg up_write(&adev->reset_domain->sem); 20941bb76ff1Sjsg ret = size; 20951bb76ff1Sjsg 20961bb76ff1Sjsg error_free: 20971bb76ff1Sjsg if (tmp != new) 20981bb76ff1Sjsg kfree(tmp); 20991bb76ff1Sjsg kfree(new); 21001bb76ff1Sjsg return ret; 21011bb76ff1Sjsg } 21021bb76ff1Sjsg 21031bb76ff1Sjsg static const struct file_operations amdgpu_reset_dump_register_list = { 21041bb76ff1Sjsg .owner = THIS_MODULE, 21051bb76ff1Sjsg .read = amdgpu_reset_dump_register_list_read, 21061bb76ff1Sjsg .write = amdgpu_reset_dump_register_list_write, 21071bb76ff1Sjsg .llseek = default_llseek 21081bb76ff1Sjsg }; 21091bb76ff1Sjsg 2110fb4d8502Sjsg int amdgpu_debugfs_init(struct amdgpu_device *adev) 2111fb4d8502Sjsg { 21125ca02815Sjsg struct dentry *root = adev_to_drm(adev)->primary->debugfs_root; 21135ca02815Sjsg struct dentry *ent; 2114c349dbc7Sjsg int r, i; 2115c349dbc7Sjsg 21161bb76ff1Sjsg if (!debugfs_initialized()) 21171bb76ff1Sjsg return 0; 21181bb76ff1Sjsg 21191bb76ff1Sjsg debugfs_create_x32("amdgpu_smu_debug", 0600, root, 21201bb76ff1Sjsg &adev->pm.smu_debug_mask); 21211bb76ff1Sjsg 21225ca02815Sjsg ent = debugfs_create_file("amdgpu_preempt_ib", 0600, root, adev, 2123c349dbc7Sjsg &fops_ib_preempt); 21245ca02815Sjsg if (IS_ERR(ent)) { 2125c349dbc7Sjsg DRM_ERROR("unable to create amdgpu_preempt_ib debugsfs file\n"); 21265ca02815Sjsg return PTR_ERR(ent); 2127c349dbc7Sjsg } 2128c349dbc7Sjsg 21295ca02815Sjsg ent = debugfs_create_file("amdgpu_force_sclk", 0200, root, adev, 2130c349dbc7Sjsg &fops_sclk_set); 21315ca02815Sjsg if (IS_ERR(ent)) { 2132c349dbc7Sjsg DRM_ERROR("unable to create amdgpu_set_sclk debugsfs file\n"); 21335ca02815Sjsg return PTR_ERR(ent); 2134c349dbc7Sjsg } 2135c349dbc7Sjsg 2136c349dbc7Sjsg /* Register debugfs entries for amdgpu_ttm */ 21375ca02815Sjsg amdgpu_ttm_debugfs_init(adev); 21385ca02815Sjsg amdgpu_debugfs_pm_init(adev); 21395ca02815Sjsg amdgpu_debugfs_sa_init(adev); 21405ca02815Sjsg amdgpu_debugfs_fence_init(adev); 21415ca02815Sjsg amdgpu_debugfs_gem_init(adev); 2142c349dbc7Sjsg 2143c349dbc7Sjsg r = amdgpu_debugfs_regs_init(adev); 2144c349dbc7Sjsg if (r) 2145c349dbc7Sjsg DRM_ERROR("registering register debugfs failed (%d).\n", r); 2146c349dbc7Sjsg 21475ca02815Sjsg amdgpu_debugfs_firmware_init(adev); 21481bb76ff1Sjsg amdgpu_ta_if_debugfs_init(adev); 2149c349dbc7Sjsg 2150c349dbc7Sjsg #if defined(CONFIG_DRM_AMD_DC) 2151f005ef32Sjsg if (adev->dc_enabled) 21525ca02815Sjsg dtn_debugfs_init(adev); 2153c349dbc7Sjsg #endif 2154c349dbc7Sjsg 2155c349dbc7Sjsg for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { 2156c349dbc7Sjsg struct amdgpu_ring *ring = adev->rings[i]; 2157c349dbc7Sjsg 2158c349dbc7Sjsg if (!ring) 2159c349dbc7Sjsg continue; 2160c349dbc7Sjsg 21611bb76ff1Sjsg amdgpu_debugfs_ring_init(adev, ring); 2162c349dbc7Sjsg } 21631bb76ff1Sjsg 21641bb76ff1Sjsg for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 21651bb76ff1Sjsg if (!amdgpu_vcnfw_log) 21661bb76ff1Sjsg break; 21671bb76ff1Sjsg 21681bb76ff1Sjsg if (adev->vcn.harvest_config & (1 << i)) 21691bb76ff1Sjsg continue; 21701bb76ff1Sjsg 21711bb76ff1Sjsg amdgpu_debugfs_vcn_fwlog_init(adev, i, &adev->vcn.inst[i]); 2172c349dbc7Sjsg } 2173c349dbc7Sjsg 2174c349dbc7Sjsg amdgpu_ras_debugfs_create_all(adev); 2175ad8b1aafSjsg amdgpu_rap_debugfs_init(adev); 21765ca02815Sjsg amdgpu_securedisplay_debugfs_init(adev); 21775ca02815Sjsg amdgpu_fw_attestation_debugfs_init(adev); 2178ad8b1aafSjsg 21793f670bccSjsg debugfs_create_file("amdgpu_evict_vram", 0400, root, adev, 21805ca02815Sjsg &amdgpu_evict_vram_fops); 21813f670bccSjsg debugfs_create_file("amdgpu_evict_gtt", 0400, root, adev, 21825ca02815Sjsg &amdgpu_evict_gtt_fops); 21833f670bccSjsg debugfs_create_file("amdgpu_test_ib", 0400, root, adev, 21845ca02815Sjsg &amdgpu_debugfs_test_ib_fops); 21855ca02815Sjsg debugfs_create_file("amdgpu_vm_info", 0444, root, adev, 21865ca02815Sjsg &amdgpu_debugfs_vm_info_fops); 21871bb76ff1Sjsg debugfs_create_file("amdgpu_benchmark", 0200, root, adev, 21881bb76ff1Sjsg &amdgpu_benchmark_fops); 21891bb76ff1Sjsg debugfs_create_file("amdgpu_reset_dump_register_list", 0644, root, adev, 21901bb76ff1Sjsg &amdgpu_reset_dump_register_list); 21915ca02815Sjsg 21925ca02815Sjsg adev->debugfs_vbios_blob.data = adev->bios; 21935ca02815Sjsg adev->debugfs_vbios_blob.size = adev->bios_size; 21945ca02815Sjsg debugfs_create_blob("amdgpu_vbios", 0444, root, 21955ca02815Sjsg &adev->debugfs_vbios_blob); 21965ca02815Sjsg 21971bb76ff1Sjsg adev->debugfs_discovery_blob.data = adev->mman.discovery_bin; 21981bb76ff1Sjsg adev->debugfs_discovery_blob.size = adev->mman.discovery_tmr_size; 21991bb76ff1Sjsg debugfs_create_blob("amdgpu_discovery", 0444, root, 22001bb76ff1Sjsg &adev->debugfs_discovery_blob); 22011bb76ff1Sjsg 22025ca02815Sjsg return 0; 2203fb4d8502Sjsg } 2204fb4d8502Sjsg 2205fb4d8502Sjsg #else 2206fb4d8502Sjsg int amdgpu_debugfs_init(struct amdgpu_device *adev) 2207fb4d8502Sjsg { 2208fb4d8502Sjsg return 0; 2209fb4d8502Sjsg } 2210fb4d8502Sjsg int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) 2211fb4d8502Sjsg { 2212fb4d8502Sjsg return 0; 2213fb4d8502Sjsg } 2214fb4d8502Sjsg #endif 2215