175758255SAlex Deucher /*
275758255SAlex Deucher  * Copyright 2008 Advanced Micro Devices, Inc.
375758255SAlex Deucher  * Copyright 2008 Red Hat Inc.
475758255SAlex Deucher  * Copyright 2009 Jerome Glisse.
575758255SAlex Deucher  *
675758255SAlex Deucher  * Permission is hereby granted, free of charge, to any person obtaining a
775758255SAlex Deucher  * copy of this software and associated documentation files (the "Software"),
875758255SAlex Deucher  * to deal in the Software without restriction, including without limitation
975758255SAlex Deucher  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1075758255SAlex Deucher  * and/or sell copies of the Software, and to permit persons to whom the
1175758255SAlex Deucher  * Software is furnished to do so, subject to the following conditions:
1275758255SAlex Deucher  *
1375758255SAlex Deucher  * The above copyright notice and this permission notice shall be included in
1475758255SAlex Deucher  * all copies or substantial portions of the Software.
1575758255SAlex Deucher  *
1675758255SAlex Deucher  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1775758255SAlex Deucher  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1875758255SAlex Deucher  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1975758255SAlex Deucher  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
2075758255SAlex Deucher  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2175758255SAlex Deucher  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2275758255SAlex Deucher  * OTHER DEALINGS IN THE SOFTWARE.
2375758255SAlex Deucher  *
2475758255SAlex Deucher  */
2575758255SAlex Deucher 
2675758255SAlex Deucher #include <linux/kthread.h>
27fdf2f6c5SSam Ravnborg #include <linux/pci.h>
28fdf2f6c5SSam Ravnborg #include <linux/uaccess.h>
29a9ffe2a9SAlex Deucher #include <linux/pm_runtime.h>
30fdf2f6c5SSam Ravnborg 
3175758255SAlex Deucher #include "amdgpu.h"
32a4c5b1bbSAlex Deucher #include "amdgpu_pm.h"
33d090e7dbSAlex Deucher #include "amdgpu_dm_debugfs.h"
3417cb04f2SStanley.Yang #include "amdgpu_ras.h"
35a4322e18SWenhui Sheng #include "amdgpu_rap.h"
36ecaafb7bSJinzhou Su #include "amdgpu_securedisplay.h"
3719ae3330SJohn Clements #include "amdgpu_fw_attestation.h"
3837df9560STom St Denis #include "amdgpu_umr.h"
3975758255SAlex Deucher 
40d0fb18b5SAndrey Grodzovsky #include "amdgpu_reset.h"
41e50d9ba0SCandice Li #include "amdgpu_psp_ta.h"
42d0fb18b5SAndrey Grodzovsky 
4375758255SAlex Deucher #if defined(CONFIG_DEBUG_FS)
4475758255SAlex Deucher 
457e4237dbSTom St Denis /**
467e4237dbSTom St Denis  * amdgpu_debugfs_process_reg_op - Handle MMIO register reads/writes
477e4237dbSTom St Denis  *
487e4237dbSTom St Denis  * @read: True if reading
497e4237dbSTom St Denis  * @f: open file handle
507e4237dbSTom St Denis  * @buf: User buffer to write/read to
517e4237dbSTom St Denis  * @size: Number of bytes to write/read
527e4237dbSTom St Denis  * @pos:  Offset to seek to
537e4237dbSTom St Denis  *
547e4237dbSTom St Denis  * This debugfs entry has special meaning on the offset being sought.
557e4237dbSTom St Denis  * Various bits have different meanings:
567e4237dbSTom St Denis  *
577e4237dbSTom St Denis  * Bit 62:  Indicates a GRBM bank switch is needed
587e4237dbSTom St Denis  * Bit 61:  Indicates a SRBM bank switch is needed (implies bit 62 is
597e4237dbSTom St Denis  * 	    zero)
607e4237dbSTom St Denis  * Bits 24..33: The SE or ME selector if needed
617e4237dbSTom St Denis  * Bits 34..43: The SH (or SA) or PIPE selector if needed
627e4237dbSTom St Denis  * Bits 44..53: The INSTANCE (or CU/WGP) or QUEUE selector if needed
637e4237dbSTom St Denis  *
647e4237dbSTom St Denis  * Bit 23:  Indicates that the PM power gating lock should be held
657e4237dbSTom St Denis  * 	    This is necessary to read registers that might be
667e4237dbSTom St Denis  * 	    unreliable during a power gating transistion.
677e4237dbSTom St Denis  *
687e4237dbSTom St Denis  * The lower bits are the BYTE offset of the register to read.  This
697e4237dbSTom St Denis  * allows reading multiple registers in a single call and having
707e4237dbSTom St Denis  * the returned size reflect that.
717e4237dbSTom St Denis  */
72f7a9ee81SAndrey Grodzovsky static int  amdgpu_debugfs_process_reg_op(bool read, struct file *f,
73f7a9ee81SAndrey Grodzovsky 		char __user *buf, size_t size, loff_t *pos)
7475758255SAlex Deucher {
7575758255SAlex Deucher 	struct amdgpu_device *adev = file_inode(f)->i_private;
7675758255SAlex Deucher 	ssize_t result = 0;
7775758255SAlex Deucher 	int r;
78f7a9ee81SAndrey Grodzovsky 	bool pm_pg_lock, use_bank, use_ring;
790fa4246eSTom St Denis 	unsigned instance_bank, sh_bank, se_bank, me, pipe, queue, vmid;
8075758255SAlex Deucher 
81f7a9ee81SAndrey Grodzovsky 	pm_pg_lock = use_bank = use_ring = false;
820fa4246eSTom St Denis 	instance_bank = sh_bank = se_bank = me = pipe = queue = vmid = 0;
83f7a9ee81SAndrey Grodzovsky 
84f7a9ee81SAndrey Grodzovsky 	if (size & 0x3 || *pos & 0x3 ||
85f7a9ee81SAndrey Grodzovsky 			((*pos & (1ULL << 62)) && (*pos & (1ULL << 61))))
8675758255SAlex Deucher 		return -EINVAL;
8775758255SAlex Deucher 
8875758255SAlex Deucher 	/* are we reading registers for which a PG lock is necessary? */
8975758255SAlex Deucher 	pm_pg_lock = (*pos >> 23) & 1;
9075758255SAlex Deucher 
9175758255SAlex Deucher 	if (*pos & (1ULL << 62)) {
9275758255SAlex Deucher 		se_bank = (*pos & GENMASK_ULL(33, 24)) >> 24;
9375758255SAlex Deucher 		sh_bank = (*pos & GENMASK_ULL(43, 34)) >> 34;
9475758255SAlex Deucher 		instance_bank = (*pos & GENMASK_ULL(53, 44)) >> 44;
9575758255SAlex Deucher 
9675758255SAlex Deucher 		if (se_bank == 0x3FF)
9775758255SAlex Deucher 			se_bank = 0xFFFFFFFF;
9875758255SAlex Deucher 		if (sh_bank == 0x3FF)
9975758255SAlex Deucher 			sh_bank = 0xFFFFFFFF;
10075758255SAlex Deucher 		if (instance_bank == 0x3FF)
10175758255SAlex Deucher 			instance_bank = 0xFFFFFFFF;
102c5b2bd5dSzhengbin 		use_bank = true;
103f7a9ee81SAndrey Grodzovsky 	} else if (*pos & (1ULL << 61)) {
104f7a9ee81SAndrey Grodzovsky 
105f7a9ee81SAndrey Grodzovsky 		me = (*pos & GENMASK_ULL(33, 24)) >> 24;
106f7a9ee81SAndrey Grodzovsky 		pipe = (*pos & GENMASK_ULL(43, 34)) >> 34;
107f7a9ee81SAndrey Grodzovsky 		queue = (*pos & GENMASK_ULL(53, 44)) >> 44;
10888891430STom St Denis 		vmid = (*pos & GENMASK_ULL(58, 54)) >> 54;
109f7a9ee81SAndrey Grodzovsky 
110c5b2bd5dSzhengbin 		use_ring = true;
11175758255SAlex Deucher 	} else {
112c5b2bd5dSzhengbin 		use_bank = use_ring = false;
11375758255SAlex Deucher 	}
11475758255SAlex Deucher 
11575758255SAlex Deucher 	*pos &= (1UL << 22) - 1;
11675758255SAlex Deucher 
1174a580877SLuben Tuikov 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
1189eee152aSAlex Deucher 	if (r < 0) {
1194a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
120a9ffe2a9SAlex Deucher 		return r;
1219eee152aSAlex Deucher 	}
122a9ffe2a9SAlex Deucher 
12395a2f917SYintian Tao 	r = amdgpu_virt_enable_access_debugfs(adev);
1249eee152aSAlex Deucher 	if (r < 0) {
1254a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
12695a2f917SYintian Tao 		return r;
1279eee152aSAlex Deucher 	}
12895a2f917SYintian Tao 
12975758255SAlex Deucher 	if (use_bank) {
13075758255SAlex Deucher 		if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) ||
131a9ffe2a9SAlex Deucher 		    (se_bank != 0xFFFFFFFF && se_bank >= adev->gfx.config.max_shader_engines)) {
1324a580877SLuben Tuikov 			pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
1334a580877SLuben Tuikov 			pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
13495a2f917SYintian Tao 			amdgpu_virt_disable_access_debugfs(adev);
13575758255SAlex Deucher 			return -EINVAL;
136a9ffe2a9SAlex Deucher 		}
13775758255SAlex Deucher 		mutex_lock(&adev->grbm_idx_mutex);
13875758255SAlex Deucher 		amdgpu_gfx_select_se_sh(adev, se_bank,
13975758255SAlex Deucher 					sh_bank, instance_bank);
140f7a9ee81SAndrey Grodzovsky 	} else if (use_ring) {
141f7a9ee81SAndrey Grodzovsky 		mutex_lock(&adev->srbm_mutex);
1420fa4246eSTom St Denis 		amdgpu_gfx_select_me_pipe_q(adev, me, pipe, queue, vmid);
14375758255SAlex Deucher 	}
14475758255SAlex Deucher 
14575758255SAlex Deucher 	if (pm_pg_lock)
14675758255SAlex Deucher 		mutex_lock(&adev->pm.mutex);
14775758255SAlex Deucher 
14875758255SAlex Deucher 	while (size) {
14975758255SAlex Deucher 		uint32_t value;
15075758255SAlex Deucher 
151f7a9ee81SAndrey Grodzovsky 		if (read) {
15275758255SAlex Deucher 			value = RREG32(*pos >> 2);
15375758255SAlex Deucher 			r = put_user(value, (uint32_t *)buf);
154f7a9ee81SAndrey Grodzovsky 		} else {
155f7a9ee81SAndrey Grodzovsky 			r = get_user(value, (uint32_t *)buf);
156f7a9ee81SAndrey Grodzovsky 			if (!r)
157f7ee1874SHawking Zhang 				amdgpu_mm_wreg_mmio_rlc(adev, *pos >> 2, value);
158f7a9ee81SAndrey Grodzovsky 		}
15975758255SAlex Deucher 		if (r) {
16075758255SAlex Deucher 			result = r;
16175758255SAlex Deucher 			goto end;
16275758255SAlex Deucher 		}
16375758255SAlex Deucher 
16475758255SAlex Deucher 		result += 4;
16575758255SAlex Deucher 		buf += 4;
16675758255SAlex Deucher 		*pos += 4;
16775758255SAlex Deucher 		size -= 4;
16875758255SAlex Deucher 	}
16975758255SAlex Deucher 
17075758255SAlex Deucher end:
17175758255SAlex Deucher 	if (use_bank) {
17275758255SAlex Deucher 		amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
17375758255SAlex Deucher 		mutex_unlock(&adev->grbm_idx_mutex);
174f7a9ee81SAndrey Grodzovsky 	} else if (use_ring) {
1750fa4246eSTom St Denis 		amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0);
176f7a9ee81SAndrey Grodzovsky 		mutex_unlock(&adev->srbm_mutex);
17775758255SAlex Deucher 	}
17875758255SAlex Deucher 
17975758255SAlex Deucher 	if (pm_pg_lock)
18075758255SAlex Deucher 		mutex_unlock(&adev->pm.mutex);
18175758255SAlex Deucher 
1824a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
1834a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
184a9ffe2a9SAlex Deucher 
18595a2f917SYintian Tao 	amdgpu_virt_disable_access_debugfs(adev);
18675758255SAlex Deucher 	return result;
18775758255SAlex Deucher }
18875758255SAlex Deucher 
18920ed491bSLee Jones /*
1907e4237dbSTom St Denis  * amdgpu_debugfs_regs_read - Callback for reading MMIO registers
1917e4237dbSTom St Denis  */
192f7a9ee81SAndrey Grodzovsky static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf,
193f7a9ee81SAndrey Grodzovsky 					size_t size, loff_t *pos)
194f7a9ee81SAndrey Grodzovsky {
195f7a9ee81SAndrey Grodzovsky 	return amdgpu_debugfs_process_reg_op(true, f, buf, size, pos);
196f7a9ee81SAndrey Grodzovsky }
197f7a9ee81SAndrey Grodzovsky 
19820ed491bSLee Jones /*
1997e4237dbSTom St Denis  * amdgpu_debugfs_regs_write - Callback for writing MMIO registers
2007e4237dbSTom St Denis  */
20175758255SAlex Deucher static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf,
20275758255SAlex Deucher 					 size_t size, loff_t *pos)
20375758255SAlex Deucher {
204f7a9ee81SAndrey Grodzovsky 	return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos);
20575758255SAlex Deucher }
20675758255SAlex Deucher 
20737df9560STom St Denis static int amdgpu_debugfs_regs2_open(struct inode *inode, struct file *file)
20837df9560STom St Denis {
20937df9560STom St Denis 	struct amdgpu_debugfs_regs2_data *rd;
21037df9560STom St Denis 
21137df9560STom St Denis 	rd = kzalloc(sizeof *rd, GFP_KERNEL);
21237df9560STom St Denis 	if (!rd)
21337df9560STom St Denis 		return -ENOMEM;
21437df9560STom St Denis 	rd->adev = file_inode(file)->i_private;
21537df9560STom St Denis 	file->private_data = rd;
21637df9560STom St Denis 	mutex_init(&rd->lock);
21737df9560STom St Denis 
21837df9560STom St Denis 	return 0;
21937df9560STom St Denis }
22037df9560STom St Denis 
22137df9560STom St Denis static int amdgpu_debugfs_regs2_release(struct inode *inode, struct file *file)
22237df9560STom St Denis {
22337df9560STom St Denis 	struct amdgpu_debugfs_regs2_data *rd = file->private_data;
22437df9560STom St Denis 	mutex_destroy(&rd->lock);
22537df9560STom St Denis 	kfree(file->private_data);
22637df9560STom St Denis 	return 0;
22737df9560STom St Denis }
22837df9560STom St Denis 
22937df9560STom St Denis static ssize_t amdgpu_debugfs_regs2_op(struct file *f, char __user *buf, u32 offset, size_t size, int write_en)
23037df9560STom St Denis {
23137df9560STom St Denis 	struct amdgpu_debugfs_regs2_data *rd = f->private_data;
23237df9560STom St Denis 	struct amdgpu_device *adev = rd->adev;
23337df9560STom St Denis 	ssize_t result = 0;
23437df9560STom St Denis 	int r;
23537df9560STom St Denis 	uint32_t value;
23637df9560STom St Denis 
23737df9560STom St Denis 	if (size & 0x3 || offset & 0x3)
23837df9560STom St Denis 		return -EINVAL;
23937df9560STom St Denis 
24037df9560STom St Denis 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
24137df9560STom St Denis 	if (r < 0) {
24237df9560STom St Denis 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
24337df9560STom St Denis 		return r;
24437df9560STom St Denis 	}
24537df9560STom St Denis 
24637df9560STom St Denis 	r = amdgpu_virt_enable_access_debugfs(adev);
24737df9560STom St Denis 	if (r < 0) {
24837df9560STom St Denis 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
24937df9560STom St Denis 		return r;
25037df9560STom St Denis 	}
25137df9560STom St Denis 
25237df9560STom St Denis 	mutex_lock(&rd->lock);
25337df9560STom St Denis 
25437df9560STom St Denis 	if (rd->id.use_grbm) {
25537df9560STom St Denis 		if ((rd->id.grbm.sh != 0xFFFFFFFF && rd->id.grbm.sh >= adev->gfx.config.max_sh_per_se) ||
25637df9560STom St Denis 		    (rd->id.grbm.se != 0xFFFFFFFF && rd->id.grbm.se >= adev->gfx.config.max_shader_engines)) {
25737df9560STom St Denis 			pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
25837df9560STom St Denis 			pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
25937df9560STom St Denis 			amdgpu_virt_disable_access_debugfs(adev);
26037df9560STom St Denis 			mutex_unlock(&rd->lock);
26137df9560STom St Denis 			return -EINVAL;
26237df9560STom St Denis 		}
26337df9560STom St Denis 		mutex_lock(&adev->grbm_idx_mutex);
26437df9560STom St Denis 		amdgpu_gfx_select_se_sh(adev, rd->id.grbm.se,
26537df9560STom St Denis 								rd->id.grbm.sh,
26637df9560STom St Denis 								rd->id.grbm.instance);
26737df9560STom St Denis 	}
26837df9560STom St Denis 
26937df9560STom St Denis 	if (rd->id.use_srbm) {
27037df9560STom St Denis 		mutex_lock(&adev->srbm_mutex);
27137df9560STom St Denis 		amdgpu_gfx_select_me_pipe_q(adev, rd->id.srbm.me, rd->id.srbm.pipe,
27237df9560STom St Denis 									rd->id.srbm.queue, rd->id.srbm.vmid);
27337df9560STom St Denis 	}
27437df9560STom St Denis 
27537df9560STom St Denis 	if (rd->id.pg_lock)
27637df9560STom St Denis 		mutex_lock(&adev->pm.mutex);
27737df9560STom St Denis 
27837df9560STom St Denis 	while (size) {
27937df9560STom St Denis 		if (!write_en) {
28037df9560STom St Denis 			value = RREG32(offset >> 2);
28137df9560STom St Denis 			r = put_user(value, (uint32_t *)buf);
28237df9560STom St Denis 		} else {
28337df9560STom St Denis 			r = get_user(value, (uint32_t *)buf);
28437df9560STom St Denis 			if (!r)
28537df9560STom St Denis 				amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, value);
28637df9560STom St Denis 		}
28737df9560STom St Denis 		if (r) {
28837df9560STom St Denis 			result = r;
28937df9560STom St Denis 			goto end;
29037df9560STom St Denis 		}
29137df9560STom St Denis 		offset += 4;
29237df9560STom St Denis 		size -= 4;
29337df9560STom St Denis 		result += 4;
29437df9560STom St Denis 		buf += 4;
29537df9560STom St Denis 	}
29637df9560STom St Denis end:
29737df9560STom St Denis 	if (rd->id.use_grbm) {
29837df9560STom St Denis 		amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
29937df9560STom St Denis 		mutex_unlock(&adev->grbm_idx_mutex);
30037df9560STom St Denis 	}
30137df9560STom St Denis 
30237df9560STom St Denis 	if (rd->id.use_srbm) {
30337df9560STom St Denis 		amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0);
30437df9560STom St Denis 		mutex_unlock(&adev->srbm_mutex);
30537df9560STom St Denis 	}
30637df9560STom St Denis 
30737df9560STom St Denis 	if (rd->id.pg_lock)
30837df9560STom St Denis 		mutex_unlock(&adev->pm.mutex);
30937df9560STom St Denis 
31037df9560STom St Denis 	mutex_unlock(&rd->lock);
31137df9560STom St Denis 
31237df9560STom St Denis 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
31337df9560STom St Denis 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
31437df9560STom St Denis 
31537df9560STom St Denis 	amdgpu_virt_disable_access_debugfs(adev);
31637df9560STom St Denis 	return result;
31737df9560STom St Denis }
31837df9560STom St Denis 
31937df9560STom St Denis static long amdgpu_debugfs_regs2_ioctl(struct file *f, unsigned int cmd, unsigned long data)
32037df9560STom St Denis {
32137df9560STom St Denis 	struct amdgpu_debugfs_regs2_data *rd = f->private_data;
32237df9560STom St Denis 	int r;
32337df9560STom St Denis 
32437df9560STom St Denis 	switch (cmd) {
32537df9560STom St Denis 	case AMDGPU_DEBUGFS_REGS2_IOC_SET_STATE:
32637df9560STom St Denis 		mutex_lock(&rd->lock);
32737df9560STom St Denis 		r = copy_from_user(&rd->id, (struct amdgpu_debugfs_regs2_iocdata *)data, sizeof rd->id);
32837df9560STom St Denis 		mutex_unlock(&rd->lock);
32937df9560STom St Denis 		return r ? -EINVAL : 0;
33037df9560STom St Denis 	default:
33137df9560STom St Denis 		return -EINVAL;
33237df9560STom St Denis 	}
33337df9560STom St Denis 	return 0;
33437df9560STom St Denis }
33537df9560STom St Denis 
33637df9560STom St Denis static ssize_t amdgpu_debugfs_regs2_read(struct file *f, char __user *buf, size_t size, loff_t *pos)
33737df9560STom St Denis {
33837df9560STom St Denis 	return amdgpu_debugfs_regs2_op(f, buf, *pos, size, 0);
33937df9560STom St Denis }
34037df9560STom St Denis 
34137df9560STom St Denis static ssize_t amdgpu_debugfs_regs2_write(struct file *f, const char __user *buf, size_t size, loff_t *pos)
34237df9560STom St Denis {
34337df9560STom St Denis 	return amdgpu_debugfs_regs2_op(f, (char __user *)buf, *pos, size, 1);
34437df9560STom St Denis }
34537df9560STom St Denis 
3467e4237dbSTom St Denis 
3477e4237dbSTom St Denis /**
3487e4237dbSTom St Denis  * amdgpu_debugfs_regs_pcie_read - Read from a PCIE register
3497e4237dbSTom St Denis  *
3507e4237dbSTom St Denis  * @f: open file handle
3517e4237dbSTom St Denis  * @buf: User buffer to store read data in
3527e4237dbSTom St Denis  * @size: Number of bytes to read
3537e4237dbSTom St Denis  * @pos:  Offset to seek to
3547e4237dbSTom St Denis  *
3557e4237dbSTom St Denis  * The lower bits are the BYTE offset of the register to read.  This
3567e4237dbSTom St Denis  * allows reading multiple registers in a single call and having
3577e4237dbSTom St Denis  * the returned size reflect that.
3587e4237dbSTom St Denis  */
35975758255SAlex Deucher static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf,
36075758255SAlex Deucher 					size_t size, loff_t *pos)
36175758255SAlex Deucher {
36275758255SAlex Deucher 	struct amdgpu_device *adev = file_inode(f)->i_private;
36375758255SAlex Deucher 	ssize_t result = 0;
36475758255SAlex Deucher 	int r;
36575758255SAlex Deucher 
36675758255SAlex Deucher 	if (size & 0x3 || *pos & 0x3)
36775758255SAlex Deucher 		return -EINVAL;
36875758255SAlex Deucher 
3694a580877SLuben Tuikov 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
3709eee152aSAlex Deucher 	if (r < 0) {
3714a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
372a9ffe2a9SAlex Deucher 		return r;
3739eee152aSAlex Deucher 	}
374a9ffe2a9SAlex Deucher 
37595a2f917SYintian Tao 	r = amdgpu_virt_enable_access_debugfs(adev);
3769eee152aSAlex Deucher 	if (r < 0) {
3774a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
37895a2f917SYintian Tao 		return r;
3799eee152aSAlex Deucher 	}
38095a2f917SYintian Tao 
38175758255SAlex Deucher 	while (size) {
38275758255SAlex Deucher 		uint32_t value;
38375758255SAlex Deucher 
38443fb6c19SKevin Wang 		value = RREG32_PCIE(*pos);
38575758255SAlex Deucher 		r = put_user(value, (uint32_t *)buf);
386edadd6fcSAndré Almeida 		if (r)
387edadd6fcSAndré Almeida 			goto out;
38875758255SAlex Deucher 
38975758255SAlex Deucher 		result += 4;
39075758255SAlex Deucher 		buf += 4;
39175758255SAlex Deucher 		*pos += 4;
39275758255SAlex Deucher 		size -= 4;
39375758255SAlex Deucher 	}
39475758255SAlex Deucher 
395edadd6fcSAndré Almeida 	r = result;
396edadd6fcSAndré Almeida out:
3974a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
3984a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
39995a2f917SYintian Tao 	amdgpu_virt_disable_access_debugfs(adev);
400edadd6fcSAndré Almeida 	return r;
40175758255SAlex Deucher }
40275758255SAlex Deucher 
4037e4237dbSTom St Denis /**
4047e4237dbSTom St Denis  * amdgpu_debugfs_regs_pcie_write - Write to a PCIE register
4057e4237dbSTom St Denis  *
4067e4237dbSTom St Denis  * @f: open file handle
4077e4237dbSTom St Denis  * @buf: User buffer to write data from
4087e4237dbSTom St Denis  * @size: Number of bytes to write
4097e4237dbSTom St Denis  * @pos:  Offset to seek to
4107e4237dbSTom St Denis  *
4117e4237dbSTom St Denis  * The lower bits are the BYTE offset of the register to write.  This
4127e4237dbSTom St Denis  * allows writing multiple registers in a single call and having
4137e4237dbSTom St Denis  * the returned size reflect that.
4147e4237dbSTom St Denis  */
41575758255SAlex Deucher static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user *buf,
41675758255SAlex Deucher 					 size_t size, loff_t *pos)
41775758255SAlex Deucher {
41875758255SAlex Deucher 	struct amdgpu_device *adev = file_inode(f)->i_private;
41975758255SAlex Deucher 	ssize_t result = 0;
42075758255SAlex Deucher 	int r;
42175758255SAlex Deucher 
42275758255SAlex Deucher 	if (size & 0x3 || *pos & 0x3)
42375758255SAlex Deucher 		return -EINVAL;
42475758255SAlex Deucher 
4254a580877SLuben Tuikov 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
4269eee152aSAlex Deucher 	if (r < 0) {
4274a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
428a9ffe2a9SAlex Deucher 		return r;
4299eee152aSAlex Deucher 	}
430a9ffe2a9SAlex Deucher 
43195a2f917SYintian Tao 	r = amdgpu_virt_enable_access_debugfs(adev);
4329eee152aSAlex Deucher 	if (r < 0) {
4334a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
43495a2f917SYintian Tao 		return r;
4359eee152aSAlex Deucher 	}
43695a2f917SYintian Tao 
43775758255SAlex Deucher 	while (size) {
43875758255SAlex Deucher 		uint32_t value;
43975758255SAlex Deucher 
44075758255SAlex Deucher 		r = get_user(value, (uint32_t *)buf);
441edadd6fcSAndré Almeida 		if (r)
442edadd6fcSAndré Almeida 			goto out;
44375758255SAlex Deucher 
44443fb6c19SKevin Wang 		WREG32_PCIE(*pos, value);
44575758255SAlex Deucher 
44675758255SAlex Deucher 		result += 4;
44775758255SAlex Deucher 		buf += 4;
44875758255SAlex Deucher 		*pos += 4;
44975758255SAlex Deucher 		size -= 4;
45075758255SAlex Deucher 	}
45175758255SAlex Deucher 
452edadd6fcSAndré Almeida 	r = result;
453edadd6fcSAndré Almeida out:
4544a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
4554a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
45695a2f917SYintian Tao 	amdgpu_virt_disable_access_debugfs(adev);
457edadd6fcSAndré Almeida 	return r;
45875758255SAlex Deucher }
45975758255SAlex Deucher 
4607e4237dbSTom St Denis /**
4617e4237dbSTom St Denis  * amdgpu_debugfs_regs_didt_read - Read from a DIDT register
4627e4237dbSTom St Denis  *
4637e4237dbSTom St Denis  * @f: open file handle
4647e4237dbSTom St Denis  * @buf: User buffer to store read data in
4657e4237dbSTom St Denis  * @size: Number of bytes to read
4667e4237dbSTom St Denis  * @pos:  Offset to seek to
4677e4237dbSTom St Denis  *
4687e4237dbSTom St Denis  * The lower bits are the BYTE offset of the register to read.  This
4697e4237dbSTom St Denis  * allows reading multiple registers in a single call and having
4707e4237dbSTom St Denis  * the returned size reflect that.
4717e4237dbSTom St Denis  */
47275758255SAlex Deucher static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf,
47375758255SAlex Deucher 					size_t size, loff_t *pos)
47475758255SAlex Deucher {
47575758255SAlex Deucher 	struct amdgpu_device *adev = file_inode(f)->i_private;
47675758255SAlex Deucher 	ssize_t result = 0;
47775758255SAlex Deucher 	int r;
47875758255SAlex Deucher 
47975758255SAlex Deucher 	if (size & 0x3 || *pos & 0x3)
48075758255SAlex Deucher 		return -EINVAL;
48175758255SAlex Deucher 
4824a580877SLuben Tuikov 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
4839eee152aSAlex Deucher 	if (r < 0) {
4844a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
485a9ffe2a9SAlex Deucher 		return r;
4869eee152aSAlex Deucher 	}
487a9ffe2a9SAlex Deucher 
48895a2f917SYintian Tao 	r = amdgpu_virt_enable_access_debugfs(adev);
4899eee152aSAlex Deucher 	if (r < 0) {
4904a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
49195a2f917SYintian Tao 		return r;
4929eee152aSAlex Deucher 	}
49395a2f917SYintian Tao 
49475758255SAlex Deucher 	while (size) {
49575758255SAlex Deucher 		uint32_t value;
49675758255SAlex Deucher 
49775758255SAlex Deucher 		value = RREG32_DIDT(*pos >> 2);
49875758255SAlex Deucher 		r = put_user(value, (uint32_t *)buf);
499edadd6fcSAndré Almeida 		if (r)
500edadd6fcSAndré Almeida 			goto out;
50175758255SAlex Deucher 
50275758255SAlex Deucher 		result += 4;
50375758255SAlex Deucher 		buf += 4;
50475758255SAlex Deucher 		*pos += 4;
50575758255SAlex Deucher 		size -= 4;
50675758255SAlex Deucher 	}
50775758255SAlex Deucher 
508edadd6fcSAndré Almeida 	r = result;
509edadd6fcSAndré Almeida out:
5104a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
5114a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
51295a2f917SYintian Tao 	amdgpu_virt_disable_access_debugfs(adev);
513edadd6fcSAndré Almeida 	return r;
51475758255SAlex Deucher }
51575758255SAlex Deucher 
5167e4237dbSTom St Denis /**
5177e4237dbSTom St Denis  * amdgpu_debugfs_regs_didt_write - Write to a DIDT register
5187e4237dbSTom St Denis  *
5197e4237dbSTom St Denis  * @f: open file handle
5207e4237dbSTom St Denis  * @buf: User buffer to write data from
5217e4237dbSTom St Denis  * @size: Number of bytes to write
5227e4237dbSTom St Denis  * @pos:  Offset to seek to
5237e4237dbSTom St Denis  *
5247e4237dbSTom St Denis  * The lower bits are the BYTE offset of the register to write.  This
5257e4237dbSTom St Denis  * allows writing multiple registers in a single call and having
5267e4237dbSTom St Denis  * the returned size reflect that.
5277e4237dbSTom St Denis  */
52875758255SAlex Deucher static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user *buf,
52975758255SAlex Deucher 					 size_t size, loff_t *pos)
53075758255SAlex Deucher {
53175758255SAlex Deucher 	struct amdgpu_device *adev = file_inode(f)->i_private;
53275758255SAlex Deucher 	ssize_t result = 0;
53375758255SAlex Deucher 	int r;
53475758255SAlex Deucher 
53575758255SAlex Deucher 	if (size & 0x3 || *pos & 0x3)
53675758255SAlex Deucher 		return -EINVAL;
53775758255SAlex Deucher 
5384a580877SLuben Tuikov 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
5399eee152aSAlex Deucher 	if (r < 0) {
5404a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
541a9ffe2a9SAlex Deucher 		return r;
5429eee152aSAlex Deucher 	}
543a9ffe2a9SAlex Deucher 
54495a2f917SYintian Tao 	r = amdgpu_virt_enable_access_debugfs(adev);
5459eee152aSAlex Deucher 	if (r < 0) {
5464a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
54795a2f917SYintian Tao 		return r;
5489eee152aSAlex Deucher 	}
54995a2f917SYintian Tao 
55075758255SAlex Deucher 	while (size) {
55175758255SAlex Deucher 		uint32_t value;
55275758255SAlex Deucher 
55375758255SAlex Deucher 		r = get_user(value, (uint32_t *)buf);
554edadd6fcSAndré Almeida 		if (r)
555edadd6fcSAndré Almeida 			goto out;
55675758255SAlex Deucher 
55775758255SAlex Deucher 		WREG32_DIDT(*pos >> 2, value);
55875758255SAlex Deucher 
55975758255SAlex Deucher 		result += 4;
56075758255SAlex Deucher 		buf += 4;
56175758255SAlex Deucher 		*pos += 4;
56275758255SAlex Deucher 		size -= 4;
56375758255SAlex Deucher 	}
56475758255SAlex Deucher 
565edadd6fcSAndré Almeida 	r = result;
566edadd6fcSAndré Almeida out:
5674a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
5684a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
56995a2f917SYintian Tao 	amdgpu_virt_disable_access_debugfs(adev);
570edadd6fcSAndré Almeida 	return r;
57175758255SAlex Deucher }
57275758255SAlex Deucher 
5737e4237dbSTom St Denis /**
5747e4237dbSTom St Denis  * amdgpu_debugfs_regs_smc_read - Read from a SMC register
5757e4237dbSTom St Denis  *
5767e4237dbSTom St Denis  * @f: open file handle
5777e4237dbSTom St Denis  * @buf: User buffer to store read data in
5787e4237dbSTom St Denis  * @size: Number of bytes to read
5797e4237dbSTom St Denis  * @pos:  Offset to seek to
5807e4237dbSTom St Denis  *
5817e4237dbSTom St Denis  * The lower bits are the BYTE offset of the register to read.  This
5827e4237dbSTom St Denis  * allows reading multiple registers in a single call and having
5837e4237dbSTom St Denis  * the returned size reflect that.
5847e4237dbSTom St Denis  */
58575758255SAlex Deucher static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
58675758255SAlex Deucher 					size_t size, loff_t *pos)
58775758255SAlex Deucher {
58875758255SAlex Deucher 	struct amdgpu_device *adev = file_inode(f)->i_private;
58975758255SAlex Deucher 	ssize_t result = 0;
59075758255SAlex Deucher 	int r;
59175758255SAlex Deucher 
59275758255SAlex Deucher 	if (size & 0x3 || *pos & 0x3)
59375758255SAlex Deucher 		return -EINVAL;
59475758255SAlex Deucher 
5954a580877SLuben Tuikov 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
5969eee152aSAlex Deucher 	if (r < 0) {
5974a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
598a9ffe2a9SAlex Deucher 		return r;
5999eee152aSAlex Deucher 	}
600a9ffe2a9SAlex Deucher 
60195a2f917SYintian Tao 	r = amdgpu_virt_enable_access_debugfs(adev);
6029eee152aSAlex Deucher 	if (r < 0) {
6034a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
60495a2f917SYintian Tao 		return r;
6059eee152aSAlex Deucher 	}
60695a2f917SYintian Tao 
60775758255SAlex Deucher 	while (size) {
60875758255SAlex Deucher 		uint32_t value;
60975758255SAlex Deucher 
61075758255SAlex Deucher 		value = RREG32_SMC(*pos);
61175758255SAlex Deucher 		r = put_user(value, (uint32_t *)buf);
612edadd6fcSAndré Almeida 		if (r)
613edadd6fcSAndré Almeida 			goto out;
61475758255SAlex Deucher 
61575758255SAlex Deucher 		result += 4;
61675758255SAlex Deucher 		buf += 4;
61775758255SAlex Deucher 		*pos += 4;
61875758255SAlex Deucher 		size -= 4;
61975758255SAlex Deucher 	}
62075758255SAlex Deucher 
621edadd6fcSAndré Almeida 	r = result;
622edadd6fcSAndré Almeida out:
6234a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
6244a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
62595a2f917SYintian Tao 	amdgpu_virt_disable_access_debugfs(adev);
626edadd6fcSAndré Almeida 	return r;
62775758255SAlex Deucher }
62875758255SAlex Deucher 
6297e4237dbSTom St Denis /**
6307e4237dbSTom St Denis  * amdgpu_debugfs_regs_smc_write - Write to a SMC register
6317e4237dbSTom St Denis  *
6327e4237dbSTom St Denis  * @f: open file handle
6337e4237dbSTom St Denis  * @buf: User buffer to write data from
6347e4237dbSTom St Denis  * @size: Number of bytes to write
6357e4237dbSTom St Denis  * @pos:  Offset to seek to
6367e4237dbSTom St Denis  *
6377e4237dbSTom St Denis  * The lower bits are the BYTE offset of the register to write.  This
6387e4237dbSTom St Denis  * allows writing multiple registers in a single call and having
6397e4237dbSTom St Denis  * the returned size reflect that.
6407e4237dbSTom St Denis  */
64175758255SAlex Deucher static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *buf,
64275758255SAlex Deucher 					 size_t size, loff_t *pos)
64375758255SAlex Deucher {
64475758255SAlex Deucher 	struct amdgpu_device *adev = file_inode(f)->i_private;
64575758255SAlex Deucher 	ssize_t result = 0;
64675758255SAlex Deucher 	int r;
64775758255SAlex Deucher 
64875758255SAlex Deucher 	if (size & 0x3 || *pos & 0x3)
64975758255SAlex Deucher 		return -EINVAL;
65075758255SAlex Deucher 
6514a580877SLuben Tuikov 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
6529eee152aSAlex Deucher 	if (r < 0) {
6534a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
654a9ffe2a9SAlex Deucher 		return r;
6559eee152aSAlex Deucher 	}
656a9ffe2a9SAlex Deucher 
65795a2f917SYintian Tao 	r = amdgpu_virt_enable_access_debugfs(adev);
6589eee152aSAlex Deucher 	if (r < 0) {
6594a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
66095a2f917SYintian Tao 		return r;
6619eee152aSAlex Deucher 	}
66295a2f917SYintian Tao 
66375758255SAlex Deucher 	while (size) {
66475758255SAlex Deucher 		uint32_t value;
66575758255SAlex Deucher 
66675758255SAlex Deucher 		r = get_user(value, (uint32_t *)buf);
667edadd6fcSAndré Almeida 		if (r)
668edadd6fcSAndré Almeida 			goto out;
66975758255SAlex Deucher 
67075758255SAlex Deucher 		WREG32_SMC(*pos, value);
67175758255SAlex Deucher 
67275758255SAlex Deucher 		result += 4;
67375758255SAlex Deucher 		buf += 4;
67475758255SAlex Deucher 		*pos += 4;
67575758255SAlex Deucher 		size -= 4;
67675758255SAlex Deucher 	}
67775758255SAlex Deucher 
678edadd6fcSAndré Almeida 	r = result;
679edadd6fcSAndré Almeida out:
6804a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
6814a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
68295a2f917SYintian Tao 	amdgpu_virt_disable_access_debugfs(adev);
683edadd6fcSAndré Almeida 	return r;
68475758255SAlex Deucher }
68575758255SAlex Deucher 
6867e4237dbSTom St Denis /**
6877e4237dbSTom St Denis  * amdgpu_debugfs_gca_config_read - Read from gfx config data
6887e4237dbSTom St Denis  *
6897e4237dbSTom St Denis  * @f: open file handle
6907e4237dbSTom St Denis  * @buf: User buffer to store read data in
6917e4237dbSTom St Denis  * @size: Number of bytes to read
6927e4237dbSTom St Denis  * @pos:  Offset to seek to
6937e4237dbSTom St Denis  *
6947e4237dbSTom St Denis  * This file is used to access configuration data in a somewhat
6957e4237dbSTom St Denis  * stable fashion.  The format is a series of DWORDs with the first
6967e4237dbSTom St Denis  * indicating which revision it is.  New content is appended to the
6977e4237dbSTom St Denis  * end so that older software can still read the data.
6987e4237dbSTom St Denis  */
6997e4237dbSTom St Denis 
70075758255SAlex Deucher static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf,
70175758255SAlex Deucher 					size_t size, loff_t *pos)
70275758255SAlex Deucher {
70375758255SAlex Deucher 	struct amdgpu_device *adev = file_inode(f)->i_private;
70475758255SAlex Deucher 	ssize_t result = 0;
70575758255SAlex Deucher 	int r;
70675758255SAlex Deucher 	uint32_t *config, no_regs = 0;
70775758255SAlex Deucher 
70875758255SAlex Deucher 	if (size & 0x3 || *pos & 0x3)
70975758255SAlex Deucher 		return -EINVAL;
71075758255SAlex Deucher 
71175758255SAlex Deucher 	config = kmalloc_array(256, sizeof(*config), GFP_KERNEL);
71275758255SAlex Deucher 	if (!config)
71375758255SAlex Deucher 		return -ENOMEM;
71475758255SAlex Deucher 
71575758255SAlex Deucher 	/* version, increment each time something is added */
716dc2947b3STom St Denis 	config[no_regs++] = 5;
71775758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.max_shader_engines;
71875758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.max_tile_pipes;
71975758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.max_cu_per_sh;
72075758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.max_sh_per_se;
72175758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.max_backends_per_se;
72275758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.max_texture_channel_caches;
72375758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.max_gprs;
72475758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.max_gs_threads;
72575758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.max_hw_contexts;
72675758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_frontend;
72775758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.sc_prim_fifo_size_backend;
72875758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.sc_hiz_tile_fifo_size;
72975758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.sc_earlyz_tile_fifo_size;
73075758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.num_tile_pipes;
73175758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.backend_enable_mask;
73275758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.mem_max_burst_length_bytes;
73375758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.mem_row_size_in_kb;
73475758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.shader_engine_tile_size;
73575758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.num_gpus;
73675758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.multi_gpu_tile_size;
73775758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.mc_arb_ramcfg;
73875758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.gb_addr_config;
73975758255SAlex Deucher 	config[no_regs++] = adev->gfx.config.num_rbs;
74075758255SAlex Deucher 
74175758255SAlex Deucher 	/* rev==1 */
74275758255SAlex Deucher 	config[no_regs++] = adev->rev_id;
743dc2947b3STom St Denis 	config[no_regs++] = lower_32_bits(adev->pg_flags);
74425faeddcSEvan Quan 	config[no_regs++] = lower_32_bits(adev->cg_flags);
74575758255SAlex Deucher 
74675758255SAlex Deucher 	/* rev==2 */
74775758255SAlex Deucher 	config[no_regs++] = adev->family;
74875758255SAlex Deucher 	config[no_regs++] = adev->external_rev_id;
74975758255SAlex Deucher 
75075758255SAlex Deucher 	/* rev==3 */
75175758255SAlex Deucher 	config[no_regs++] = adev->pdev->device;
75275758255SAlex Deucher 	config[no_regs++] = adev->pdev->revision;
75375758255SAlex Deucher 	config[no_regs++] = adev->pdev->subsystem_device;
75475758255SAlex Deucher 	config[no_regs++] = adev->pdev->subsystem_vendor;
75575758255SAlex Deucher 
7568f74f68dSTom St Denis 	/* rev==4 APU flag */
7578f74f68dSTom St Denis 	config[no_regs++] = adev->flags & AMD_IS_APU ? 1 : 0;
7588f74f68dSTom St Denis 
759dc2947b3STom St Denis 	/* rev==5 PG/CG flag upper 32bit */
760dc2947b3STom St Denis 	config[no_regs++] = upper_32_bits(adev->pg_flags);
76125faeddcSEvan Quan 	config[no_regs++] = upper_32_bits(adev->cg_flags);
76225faeddcSEvan Quan 
76375758255SAlex Deucher 	while (size && (*pos < no_regs * 4)) {
76475758255SAlex Deucher 		uint32_t value;
76575758255SAlex Deucher 
76675758255SAlex Deucher 		value = config[*pos >> 2];
76775758255SAlex Deucher 		r = put_user(value, (uint32_t *)buf);
76875758255SAlex Deucher 		if (r) {
76975758255SAlex Deucher 			kfree(config);
77075758255SAlex Deucher 			return r;
77175758255SAlex Deucher 		}
77275758255SAlex Deucher 
77375758255SAlex Deucher 		result += 4;
77475758255SAlex Deucher 		buf += 4;
77575758255SAlex Deucher 		*pos += 4;
77675758255SAlex Deucher 		size -= 4;
77775758255SAlex Deucher 	}
77875758255SAlex Deucher 
77975758255SAlex Deucher 	kfree(config);
78075758255SAlex Deucher 	return result;
78175758255SAlex Deucher }
78275758255SAlex Deucher 
7837e4237dbSTom St Denis /**
7847e4237dbSTom St Denis  * amdgpu_debugfs_sensor_read - Read from the powerplay sensors
7857e4237dbSTom St Denis  *
7867e4237dbSTom St Denis  * @f: open file handle
7877e4237dbSTom St Denis  * @buf: User buffer to store read data in
7887e4237dbSTom St Denis  * @size: Number of bytes to read
7897e4237dbSTom St Denis  * @pos:  Offset to seek to
7907e4237dbSTom St Denis  *
7917e4237dbSTom St Denis  * The offset is treated as the BYTE address of one of the sensors
7927e4237dbSTom St Denis  * enumerated in amd/include/kgd_pp_interface.h under the
7937e4237dbSTom St Denis  * 'amd_pp_sensors' enumeration.  For instance to read the UVD VCLK
7947e4237dbSTom St Denis  * you would use the offset 3 * 4 = 12.
7957e4237dbSTom St Denis  */
79675758255SAlex Deucher static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
79775758255SAlex Deucher 					size_t size, loff_t *pos)
79875758255SAlex Deucher {
79975758255SAlex Deucher 	struct amdgpu_device *adev = file_inode(f)->i_private;
80075758255SAlex Deucher 	int idx, x, outsize, r, valuesize;
80175758255SAlex Deucher 	uint32_t values[16];
80275758255SAlex Deucher 
80375758255SAlex Deucher 	if (size & 3 || *pos & 0x3)
80475758255SAlex Deucher 		return -EINVAL;
80575758255SAlex Deucher 
806b13aa109SRex Zhu 	if (!adev->pm.dpm_enabled)
80775758255SAlex Deucher 		return -EINVAL;
80875758255SAlex Deucher 
80975758255SAlex Deucher 	/* convert offset to sensor number */
81075758255SAlex Deucher 	idx = *pos >> 2;
81175758255SAlex Deucher 
81275758255SAlex Deucher 	valuesize = sizeof(values);
813a9ffe2a9SAlex Deucher 
8144a580877SLuben Tuikov 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
8159eee152aSAlex Deucher 	if (r < 0) {
8164a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
817a9ffe2a9SAlex Deucher 		return r;
8189eee152aSAlex Deucher 	}
819a9ffe2a9SAlex Deucher 
82095a2f917SYintian Tao 	r = amdgpu_virt_enable_access_debugfs(adev);
8219eee152aSAlex Deucher 	if (r < 0) {
8224a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
82395a2f917SYintian Tao 		return r;
8249eee152aSAlex Deucher 	}
82595a2f917SYintian Tao 
82675758255SAlex Deucher 	r = amdgpu_dpm_read_sensor(adev, idx, &values[0], &valuesize);
827a9ffe2a9SAlex Deucher 
8284a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
8294a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
830a9ffe2a9SAlex Deucher 
83195a2f917SYintian Tao 	if (r) {
83295a2f917SYintian Tao 		amdgpu_virt_disable_access_debugfs(adev);
8334a5a2de6SKevin Wang 		return r;
83495a2f917SYintian Tao 	}
83575758255SAlex Deucher 
83695a2f917SYintian Tao 	if (size > valuesize) {
83795a2f917SYintian Tao 		amdgpu_virt_disable_access_debugfs(adev);
83875758255SAlex Deucher 		return -EINVAL;
83995a2f917SYintian Tao 	}
84075758255SAlex Deucher 
84175758255SAlex Deucher 	outsize = 0;
84275758255SAlex Deucher 	x = 0;
84375758255SAlex Deucher 	if (!r) {
84475758255SAlex Deucher 		while (size) {
84575758255SAlex Deucher 			r = put_user(values[x++], (int32_t *)buf);
84675758255SAlex Deucher 			buf += 4;
84775758255SAlex Deucher 			size -= 4;
84875758255SAlex Deucher 			outsize += 4;
84975758255SAlex Deucher 		}
85075758255SAlex Deucher 	}
85175758255SAlex Deucher 
85295a2f917SYintian Tao 	amdgpu_virt_disable_access_debugfs(adev);
85375758255SAlex Deucher 	return !r ? outsize : r;
85475758255SAlex Deucher }
85575758255SAlex Deucher 
8567e4237dbSTom St Denis /** amdgpu_debugfs_wave_read - Read WAVE STATUS data
8577e4237dbSTom St Denis  *
8587e4237dbSTom St Denis  * @f: open file handle
8597e4237dbSTom St Denis  * @buf: User buffer to store read data in
8607e4237dbSTom St Denis  * @size: Number of bytes to read
8617e4237dbSTom St Denis  * @pos:  Offset to seek to
8627e4237dbSTom St Denis  *
8637e4237dbSTom St Denis  * The offset being sought changes which wave that the status data
8647e4237dbSTom St Denis  * will be returned for.  The bits are used as follows:
8657e4237dbSTom St Denis  *
8667e4237dbSTom St Denis  * Bits 0..6: 	Byte offset into data
8677e4237dbSTom St Denis  * Bits 7..14:	SE selector
8687e4237dbSTom St Denis  * Bits 15..22:	SH/SA selector
8697e4237dbSTom St Denis  * Bits 23..30: CU/{WGP+SIMD} selector
8707e4237dbSTom St Denis  * Bits 31..36: WAVE ID selector
8717e4237dbSTom St Denis  * Bits 37..44: SIMD ID selector
8727e4237dbSTom St Denis  *
8737e4237dbSTom St Denis  * The returned data begins with one DWORD of version information
8747e4237dbSTom St Denis  * Followed by WAVE STATUS registers relevant to the GFX IP version
8757e4237dbSTom St Denis  * being used.  See gfx_v8_0_read_wave_data() for an example output.
8767e4237dbSTom St Denis  */
87775758255SAlex Deucher static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
87875758255SAlex Deucher 					size_t size, loff_t *pos)
87975758255SAlex Deucher {
88075758255SAlex Deucher 	struct amdgpu_device *adev = f->f_inode->i_private;
88175758255SAlex Deucher 	int r, x;
88275758255SAlex Deucher 	ssize_t result = 0;
88375758255SAlex Deucher 	uint32_t offset, se, sh, cu, wave, simd, data[32];
88475758255SAlex Deucher 
88575758255SAlex Deucher 	if (size & 3 || *pos & 3)
88675758255SAlex Deucher 		return -EINVAL;
88775758255SAlex Deucher 
88875758255SAlex Deucher 	/* decode offset */
88975758255SAlex Deucher 	offset = (*pos & GENMASK_ULL(6, 0));
89075758255SAlex Deucher 	se = (*pos & GENMASK_ULL(14, 7)) >> 7;
89175758255SAlex Deucher 	sh = (*pos & GENMASK_ULL(22, 15)) >> 15;
89275758255SAlex Deucher 	cu = (*pos & GENMASK_ULL(30, 23)) >> 23;
89375758255SAlex Deucher 	wave = (*pos & GENMASK_ULL(36, 31)) >> 31;
89475758255SAlex Deucher 	simd = (*pos & GENMASK_ULL(44, 37)) >> 37;
89575758255SAlex Deucher 
8964a580877SLuben Tuikov 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
8979eee152aSAlex Deucher 	if (r < 0) {
8984a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
899a9ffe2a9SAlex Deucher 		return r;
9009eee152aSAlex Deucher 	}
901a9ffe2a9SAlex Deucher 
90295a2f917SYintian Tao 	r = amdgpu_virt_enable_access_debugfs(adev);
9039eee152aSAlex Deucher 	if (r < 0) {
9044a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
90595a2f917SYintian Tao 		return r;
9069eee152aSAlex Deucher 	}
90795a2f917SYintian Tao 
90875758255SAlex Deucher 	/* switch to the specific se/sh/cu */
90975758255SAlex Deucher 	mutex_lock(&adev->grbm_idx_mutex);
91075758255SAlex Deucher 	amdgpu_gfx_select_se_sh(adev, se, sh, cu);
91175758255SAlex Deucher 
91275758255SAlex Deucher 	x = 0;
91375758255SAlex Deucher 	if (adev->gfx.funcs->read_wave_data)
91475758255SAlex Deucher 		adev->gfx.funcs->read_wave_data(adev, simd, wave, data, &x);
91575758255SAlex Deucher 
91675758255SAlex Deucher 	amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
91775758255SAlex Deucher 	mutex_unlock(&adev->grbm_idx_mutex);
91875758255SAlex Deucher 
9194a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
9204a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
921a9ffe2a9SAlex Deucher 
92295a2f917SYintian Tao 	if (!x) {
92395a2f917SYintian Tao 		amdgpu_virt_disable_access_debugfs(adev);
92475758255SAlex Deucher 		return -EINVAL;
92595a2f917SYintian Tao 	}
92675758255SAlex Deucher 
92775758255SAlex Deucher 	while (size && (offset < x * 4)) {
92875758255SAlex Deucher 		uint32_t value;
92975758255SAlex Deucher 
93075758255SAlex Deucher 		value = data[offset >> 2];
93175758255SAlex Deucher 		r = put_user(value, (uint32_t *)buf);
93295a2f917SYintian Tao 		if (r) {
93395a2f917SYintian Tao 			amdgpu_virt_disable_access_debugfs(adev);
93475758255SAlex Deucher 			return r;
93595a2f917SYintian Tao 		}
93675758255SAlex Deucher 
93775758255SAlex Deucher 		result += 4;
93875758255SAlex Deucher 		buf += 4;
93975758255SAlex Deucher 		offset += 4;
94075758255SAlex Deucher 		size -= 4;
94175758255SAlex Deucher 	}
94275758255SAlex Deucher 
94395a2f917SYintian Tao 	amdgpu_virt_disable_access_debugfs(adev);
94475758255SAlex Deucher 	return result;
94575758255SAlex Deucher }
94675758255SAlex Deucher 
9477e4237dbSTom St Denis /** amdgpu_debugfs_gpr_read - Read wave gprs
9487e4237dbSTom St Denis  *
9497e4237dbSTom St Denis  * @f: open file handle
9507e4237dbSTom St Denis  * @buf: User buffer to store read data in
9517e4237dbSTom St Denis  * @size: Number of bytes to read
9527e4237dbSTom St Denis  * @pos:  Offset to seek to
9537e4237dbSTom St Denis  *
9547e4237dbSTom St Denis  * The offset being sought changes which wave that the status data
9557e4237dbSTom St Denis  * will be returned for.  The bits are used as follows:
9567e4237dbSTom St Denis  *
9577e4237dbSTom St Denis  * Bits 0..11:	Byte offset into data
9587e4237dbSTom St Denis  * Bits 12..19:	SE selector
9597e4237dbSTom St Denis  * Bits 20..27:	SH/SA selector
9607e4237dbSTom St Denis  * Bits 28..35: CU/{WGP+SIMD} selector
9617e4237dbSTom St Denis  * Bits 36..43: WAVE ID selector
9627e4237dbSTom St Denis  * Bits 37..44: SIMD ID selector
9637e4237dbSTom St Denis  * Bits 52..59: Thread selector
9647e4237dbSTom St Denis  * Bits 60..61: Bank selector (VGPR=0,SGPR=1)
9657e4237dbSTom St Denis  *
9667e4237dbSTom St Denis  * The return data comes from the SGPR or VGPR register bank for
9677e4237dbSTom St Denis  * the selected operational unit.
9687e4237dbSTom St Denis  */
96975758255SAlex Deucher static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
97075758255SAlex Deucher 					size_t size, loff_t *pos)
97175758255SAlex Deucher {
97275758255SAlex Deucher 	struct amdgpu_device *adev = f->f_inode->i_private;
97375758255SAlex Deucher 	int r;
97475758255SAlex Deucher 	ssize_t result = 0;
97575758255SAlex Deucher 	uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data;
97675758255SAlex Deucher 
9776397ec58STom St Denis 	if (size > 4096 || size & 3 || *pos & 3)
97875758255SAlex Deucher 		return -EINVAL;
97975758255SAlex Deucher 
98075758255SAlex Deucher 	/* decode offset */
9816397ec58STom St Denis 	offset = (*pos & GENMASK_ULL(11, 0)) >> 2;
98275758255SAlex Deucher 	se = (*pos & GENMASK_ULL(19, 12)) >> 12;
98375758255SAlex Deucher 	sh = (*pos & GENMASK_ULL(27, 20)) >> 20;
98475758255SAlex Deucher 	cu = (*pos & GENMASK_ULL(35, 28)) >> 28;
98575758255SAlex Deucher 	wave = (*pos & GENMASK_ULL(43, 36)) >> 36;
98675758255SAlex Deucher 	simd = (*pos & GENMASK_ULL(51, 44)) >> 44;
98775758255SAlex Deucher 	thread = (*pos & GENMASK_ULL(59, 52)) >> 52;
98875758255SAlex Deucher 	bank = (*pos & GENMASK_ULL(61, 60)) >> 60;
98975758255SAlex Deucher 
990929e571cSWang Xiayang 	data = kcalloc(1024, sizeof(*data), GFP_KERNEL);
99175758255SAlex Deucher 	if (!data)
99275758255SAlex Deucher 		return -ENOMEM;
99375758255SAlex Deucher 
9944a580877SLuben Tuikov 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
995a9ffe2a9SAlex Deucher 	if (r < 0)
9963e4aeff3SChen Tao 		goto err;
997a9ffe2a9SAlex Deucher 
99895a2f917SYintian Tao 	r = amdgpu_virt_enable_access_debugfs(adev);
99995a2f917SYintian Tao 	if (r < 0)
1000888e32d7SChen Tao 		goto err;
100195a2f917SYintian Tao 
100275758255SAlex Deucher 	/* switch to the specific se/sh/cu */
100375758255SAlex Deucher 	mutex_lock(&adev->grbm_idx_mutex);
100475758255SAlex Deucher 	amdgpu_gfx_select_se_sh(adev, se, sh, cu);
100575758255SAlex Deucher 
100675758255SAlex Deucher 	if (bank == 0) {
100775758255SAlex Deucher 		if (adev->gfx.funcs->read_wave_vgprs)
100875758255SAlex Deucher 			adev->gfx.funcs->read_wave_vgprs(adev, simd, wave, thread, offset, size>>2, data);
100975758255SAlex Deucher 	} else {
101075758255SAlex Deucher 		if (adev->gfx.funcs->read_wave_sgprs)
101175758255SAlex Deucher 			adev->gfx.funcs->read_wave_sgprs(adev, simd, wave, offset, size>>2, data);
101275758255SAlex Deucher 	}
101375758255SAlex Deucher 
101475758255SAlex Deucher 	amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
101575758255SAlex Deucher 	mutex_unlock(&adev->grbm_idx_mutex);
101675758255SAlex Deucher 
10174a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
10184a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
1019a9ffe2a9SAlex Deucher 
102075758255SAlex Deucher 	while (size) {
102175758255SAlex Deucher 		uint32_t value;
102275758255SAlex Deucher 
10236397ec58STom St Denis 		value = data[result >> 2];
102475758255SAlex Deucher 		r = put_user(value, (uint32_t *)buf);
102575758255SAlex Deucher 		if (r) {
10263e4aeff3SChen Tao 			amdgpu_virt_disable_access_debugfs(adev);
102775758255SAlex Deucher 			goto err;
102875758255SAlex Deucher 		}
102975758255SAlex Deucher 
103075758255SAlex Deucher 		result += 4;
103175758255SAlex Deucher 		buf += 4;
103275758255SAlex Deucher 		size -= 4;
103375758255SAlex Deucher 	}
103475758255SAlex Deucher 
103575758255SAlex Deucher 	kfree(data);
103695a2f917SYintian Tao 	amdgpu_virt_disable_access_debugfs(adev);
103775758255SAlex Deucher 	return result;
10383e4aeff3SChen Tao 
10393e4aeff3SChen Tao err:
10404a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
10413e4aeff3SChen Tao 	kfree(data);
10423e4aeff3SChen Tao 	return r;
104375758255SAlex Deucher }
104475758255SAlex Deucher 
1045669e2f91STom St Denis /**
1046e72d4a8bSLee Jones  * amdgpu_debugfs_gfxoff_write - Enable/disable GFXOFF
1047669e2f91STom St Denis  *
1048669e2f91STom St Denis  * @f: open file handle
1049669e2f91STom St Denis  * @buf: User buffer to write data from
1050669e2f91STom St Denis  * @size: Number of bytes to write
1051669e2f91STom St Denis  * @pos:  Offset to seek to
1052669e2f91STom St Denis  *
1053669e2f91STom St Denis  * Write a 32-bit zero to disable or a 32-bit non-zero to enable
1054669e2f91STom St Denis  */
1055669e2f91STom St Denis static ssize_t amdgpu_debugfs_gfxoff_write(struct file *f, const char __user *buf,
1056669e2f91STom St Denis 					 size_t size, loff_t *pos)
1057669e2f91STom St Denis {
1058669e2f91STom St Denis 	struct amdgpu_device *adev = file_inode(f)->i_private;
1059669e2f91STom St Denis 	ssize_t result = 0;
1060669e2f91STom St Denis 	int r;
1061669e2f91STom St Denis 
1062669e2f91STom St Denis 	if (size & 0x3 || *pos & 0x3)
1063669e2f91STom St Denis 		return -EINVAL;
1064669e2f91STom St Denis 
10654a580877SLuben Tuikov 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
10669eee152aSAlex Deucher 	if (r < 0) {
10674a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
1068669e2f91STom St Denis 		return r;
10699eee152aSAlex Deucher 	}
1070669e2f91STom St Denis 
1071669e2f91STom St Denis 	while (size) {
1072669e2f91STom St Denis 		uint32_t value;
1073669e2f91STom St Denis 
1074669e2f91STom St Denis 		r = get_user(value, (uint32_t *)buf);
1075edadd6fcSAndré Almeida 		if (r)
1076edadd6fcSAndré Almeida 			goto out;
1077669e2f91STom St Denis 
1078669e2f91STom St Denis 		amdgpu_gfx_off_ctrl(adev, value ? true : false);
1079669e2f91STom St Denis 
1080669e2f91STom St Denis 		result += 4;
1081669e2f91STom St Denis 		buf += 4;
1082669e2f91STom St Denis 		*pos += 4;
1083669e2f91STom St Denis 		size -= 4;
1084669e2f91STom St Denis 	}
1085669e2f91STom St Denis 
1086edadd6fcSAndré Almeida 	r = result;
1087edadd6fcSAndré Almeida out:
10884a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
10894a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
1090669e2f91STom St Denis 
1091edadd6fcSAndré Almeida 	return r;
1092669e2f91STom St Denis }
1093669e2f91STom St Denis 
1094669e2f91STom St Denis 
1095443c7f3cSJinzhou.Su /**
1096e72d4a8bSLee Jones  * amdgpu_debugfs_gfxoff_read - read gfxoff status
1097443c7f3cSJinzhou.Su  *
1098443c7f3cSJinzhou.Su  * @f: open file handle
1099443c7f3cSJinzhou.Su  * @buf: User buffer to store read data in
1100443c7f3cSJinzhou.Su  * @size: Number of bytes to read
1101443c7f3cSJinzhou.Su  * @pos:  Offset to seek to
1102443c7f3cSJinzhou.Su  */
1103443c7f3cSJinzhou.Su static ssize_t amdgpu_debugfs_gfxoff_read(struct file *f, char __user *buf,
1104443c7f3cSJinzhou.Su 					 size_t size, loff_t *pos)
1105443c7f3cSJinzhou.Su {
1106443c7f3cSJinzhou.Su 	struct amdgpu_device *adev = file_inode(f)->i_private;
1107443c7f3cSJinzhou.Su 	ssize_t result = 0;
1108443c7f3cSJinzhou.Su 	int r;
1109443c7f3cSJinzhou.Su 
1110443c7f3cSJinzhou.Su 	if (size & 0x3 || *pos & 0x3)
1111443c7f3cSJinzhou.Su 		return -EINVAL;
1112443c7f3cSJinzhou.Su 
11134a580877SLuben Tuikov 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
11144bd8dd0dSYongzhi Liu 	if (r < 0) {
11154bd8dd0dSYongzhi Liu 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
1116443c7f3cSJinzhou.Su 		return r;
11174bd8dd0dSYongzhi Liu 	}
1118443c7f3cSJinzhou.Su 
1119443c7f3cSJinzhou.Su 	while (size) {
11204686177fSAndré Almeida 		u32 value = adev->gfx.gfx_off_state;
11214686177fSAndré Almeida 
11224686177fSAndré Almeida 		r = put_user(value, (u32 *)buf);
11234686177fSAndré Almeida 		if (r)
11244686177fSAndré Almeida 			goto out;
11254686177fSAndré Almeida 
11264686177fSAndré Almeida 		result += 4;
11274686177fSAndré Almeida 		buf += 4;
11284686177fSAndré Almeida 		*pos += 4;
11294686177fSAndré Almeida 		size -= 4;
11304686177fSAndré Almeida 	}
11314686177fSAndré Almeida 
11324686177fSAndré Almeida 	r = result;
11334686177fSAndré Almeida out:
11344686177fSAndré Almeida 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
11354686177fSAndré Almeida 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
11364686177fSAndré Almeida 
11374686177fSAndré Almeida 	return r;
11384686177fSAndré Almeida }
11394686177fSAndré Almeida 
11404686177fSAndré Almeida static ssize_t amdgpu_debugfs_gfxoff_status_read(struct file *f, char __user *buf,
11414686177fSAndré Almeida 						 size_t size, loff_t *pos)
11424686177fSAndré Almeida {
11434686177fSAndré Almeida 	struct amdgpu_device *adev = file_inode(f)->i_private;
11444686177fSAndré Almeida 	ssize_t result = 0;
11454686177fSAndré Almeida 	int r;
11464686177fSAndré Almeida 
11474686177fSAndré Almeida 	if (size & 0x3 || *pos & 0x3)
11484686177fSAndré Almeida 		return -EINVAL;
11494686177fSAndré Almeida 
11504686177fSAndré Almeida 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
11514686177fSAndré Almeida 	if (r < 0) {
11524686177fSAndré Almeida 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
11534686177fSAndré Almeida 		return r;
11544686177fSAndré Almeida 	}
11554686177fSAndré Almeida 
11564686177fSAndré Almeida 	while (size) {
11574686177fSAndré Almeida 		u32 value;
1158443c7f3cSJinzhou.Su 
1159443c7f3cSJinzhou.Su 		r = amdgpu_get_gfx_off_status(adev, &value);
1160edadd6fcSAndré Almeida 		if (r)
1161edadd6fcSAndré Almeida 			goto out;
1162443c7f3cSJinzhou.Su 
11634686177fSAndré Almeida 		r = put_user(value, (u32 *)buf);
1164edadd6fcSAndré Almeida 		if (r)
1165edadd6fcSAndré Almeida 			goto out;
1166443c7f3cSJinzhou.Su 
1167443c7f3cSJinzhou.Su 		result += 4;
1168443c7f3cSJinzhou.Su 		buf += 4;
1169443c7f3cSJinzhou.Su 		*pos += 4;
1170443c7f3cSJinzhou.Su 		size -= 4;
1171443c7f3cSJinzhou.Su 	}
1172443c7f3cSJinzhou.Su 
1173edadd6fcSAndré Almeida 	r = result;
1174edadd6fcSAndré Almeida out:
11754a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
11764a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
1177443c7f3cSJinzhou.Su 
1178edadd6fcSAndré Almeida 	return r;
1179443c7f3cSJinzhou.Su }
1180443c7f3cSJinzhou.Su 
118137df9560STom St Denis static const struct file_operations amdgpu_debugfs_regs2_fops = {
118237df9560STom St Denis 	.owner = THIS_MODULE,
118337df9560STom St Denis 	.unlocked_ioctl = amdgpu_debugfs_regs2_ioctl,
118437df9560STom St Denis 	.read = amdgpu_debugfs_regs2_read,
118537df9560STom St Denis 	.write = amdgpu_debugfs_regs2_write,
118637df9560STom St Denis 	.open = amdgpu_debugfs_regs2_open,
118737df9560STom St Denis 	.release = amdgpu_debugfs_regs2_release,
118837df9560STom St Denis 	.llseek = default_llseek
118937df9560STom St Denis };
119037df9560STom St Denis 
119175758255SAlex Deucher static const struct file_operations amdgpu_debugfs_regs_fops = {
119275758255SAlex Deucher 	.owner = THIS_MODULE,
119375758255SAlex Deucher 	.read = amdgpu_debugfs_regs_read,
119475758255SAlex Deucher 	.write = amdgpu_debugfs_regs_write,
119575758255SAlex Deucher 	.llseek = default_llseek
119675758255SAlex Deucher };
119775758255SAlex Deucher static const struct file_operations amdgpu_debugfs_regs_didt_fops = {
119875758255SAlex Deucher 	.owner = THIS_MODULE,
119975758255SAlex Deucher 	.read = amdgpu_debugfs_regs_didt_read,
120075758255SAlex Deucher 	.write = amdgpu_debugfs_regs_didt_write,
120175758255SAlex Deucher 	.llseek = default_llseek
120275758255SAlex Deucher };
120375758255SAlex Deucher static const struct file_operations amdgpu_debugfs_regs_pcie_fops = {
120475758255SAlex Deucher 	.owner = THIS_MODULE,
120575758255SAlex Deucher 	.read = amdgpu_debugfs_regs_pcie_read,
120675758255SAlex Deucher 	.write = amdgpu_debugfs_regs_pcie_write,
120775758255SAlex Deucher 	.llseek = default_llseek
120875758255SAlex Deucher };
120975758255SAlex Deucher static const struct file_operations amdgpu_debugfs_regs_smc_fops = {
121075758255SAlex Deucher 	.owner = THIS_MODULE,
121175758255SAlex Deucher 	.read = amdgpu_debugfs_regs_smc_read,
121275758255SAlex Deucher 	.write = amdgpu_debugfs_regs_smc_write,
121375758255SAlex Deucher 	.llseek = default_llseek
121475758255SAlex Deucher };
121575758255SAlex Deucher 
121675758255SAlex Deucher static const struct file_operations amdgpu_debugfs_gca_config_fops = {
121775758255SAlex Deucher 	.owner = THIS_MODULE,
121875758255SAlex Deucher 	.read = amdgpu_debugfs_gca_config_read,
121975758255SAlex Deucher 	.llseek = default_llseek
122075758255SAlex Deucher };
122175758255SAlex Deucher 
122275758255SAlex Deucher static const struct file_operations amdgpu_debugfs_sensors_fops = {
122375758255SAlex Deucher 	.owner = THIS_MODULE,
122475758255SAlex Deucher 	.read = amdgpu_debugfs_sensor_read,
122575758255SAlex Deucher 	.llseek = default_llseek
122675758255SAlex Deucher };
122775758255SAlex Deucher 
122875758255SAlex Deucher static const struct file_operations amdgpu_debugfs_wave_fops = {
122975758255SAlex Deucher 	.owner = THIS_MODULE,
123075758255SAlex Deucher 	.read = amdgpu_debugfs_wave_read,
123175758255SAlex Deucher 	.llseek = default_llseek
123275758255SAlex Deucher };
123375758255SAlex Deucher static const struct file_operations amdgpu_debugfs_gpr_fops = {
123475758255SAlex Deucher 	.owner = THIS_MODULE,
123575758255SAlex Deucher 	.read = amdgpu_debugfs_gpr_read,
123675758255SAlex Deucher 	.llseek = default_llseek
123775758255SAlex Deucher };
123875758255SAlex Deucher 
1239669e2f91STom St Denis static const struct file_operations amdgpu_debugfs_gfxoff_fops = {
1240669e2f91STom St Denis 	.owner = THIS_MODULE,
1241443c7f3cSJinzhou.Su 	.read = amdgpu_debugfs_gfxoff_read,
1242669e2f91STom St Denis 	.write = amdgpu_debugfs_gfxoff_write,
1243443c7f3cSJinzhou.Su 	.llseek = default_llseek
1244669e2f91STom St Denis };
1245669e2f91STom St Denis 
12464686177fSAndré Almeida static const struct file_operations amdgpu_debugfs_gfxoff_status_fops = {
12474686177fSAndré Almeida 	.owner = THIS_MODULE,
12484686177fSAndré Almeida 	.read = amdgpu_debugfs_gfxoff_status_read,
12494686177fSAndré Almeida 	.llseek = default_llseek
12504686177fSAndré Almeida };
12514686177fSAndré Almeida 
125275758255SAlex Deucher static const struct file_operations *debugfs_regs[] = {
125375758255SAlex Deucher 	&amdgpu_debugfs_regs_fops,
125437df9560STom St Denis 	&amdgpu_debugfs_regs2_fops,
125575758255SAlex Deucher 	&amdgpu_debugfs_regs_didt_fops,
125675758255SAlex Deucher 	&amdgpu_debugfs_regs_pcie_fops,
125775758255SAlex Deucher 	&amdgpu_debugfs_regs_smc_fops,
125875758255SAlex Deucher 	&amdgpu_debugfs_gca_config_fops,
125975758255SAlex Deucher 	&amdgpu_debugfs_sensors_fops,
126075758255SAlex Deucher 	&amdgpu_debugfs_wave_fops,
126175758255SAlex Deucher 	&amdgpu_debugfs_gpr_fops,
1262669e2f91STom St Denis 	&amdgpu_debugfs_gfxoff_fops,
12634686177fSAndré Almeida 	&amdgpu_debugfs_gfxoff_status_fops,
126475758255SAlex Deucher };
126575758255SAlex Deucher 
126675758255SAlex Deucher static const char *debugfs_regs_names[] = {
126775758255SAlex Deucher 	"amdgpu_regs",
126837df9560STom St Denis 	"amdgpu_regs2",
126975758255SAlex Deucher 	"amdgpu_regs_didt",
127075758255SAlex Deucher 	"amdgpu_regs_pcie",
127175758255SAlex Deucher 	"amdgpu_regs_smc",
127275758255SAlex Deucher 	"amdgpu_gca_config",
127375758255SAlex Deucher 	"amdgpu_sensors",
127475758255SAlex Deucher 	"amdgpu_wave",
127575758255SAlex Deucher 	"amdgpu_gpr",
1276669e2f91STom St Denis 	"amdgpu_gfxoff",
12774686177fSAndré Almeida 	"amdgpu_gfxoff_status",
127875758255SAlex Deucher };
127975758255SAlex Deucher 
12807e4237dbSTom St Denis /**
12817e4237dbSTom St Denis  * amdgpu_debugfs_regs_init -	Initialize debugfs entries that provide
12827e4237dbSTom St Denis  * 				register access.
12837e4237dbSTom St Denis  *
12847e4237dbSTom St Denis  * @adev: The device to attach the debugfs entries to
12857e4237dbSTom St Denis  */
128675758255SAlex Deucher int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)
128775758255SAlex Deucher {
12884a580877SLuben Tuikov 	struct drm_minor *minor = adev_to_drm(adev)->primary;
128975758255SAlex Deucher 	struct dentry *ent, *root = minor->debugfs_root;
1290d344b21bSDan Carpenter 	unsigned int i;
129175758255SAlex Deucher 
129275758255SAlex Deucher 	for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) {
129375758255SAlex Deucher 		ent = debugfs_create_file(debugfs_regs_names[i],
129475758255SAlex Deucher 					  S_IFREG | S_IRUGO, root,
129575758255SAlex Deucher 					  adev, debugfs_regs[i]);
1296d344b21bSDan Carpenter 		if (!i && !IS_ERR_OR_NULL(ent))
129775758255SAlex Deucher 			i_size_write(ent->d_inode, adev->rmmio_size);
129875758255SAlex Deucher 	}
129975758255SAlex Deucher 
130075758255SAlex Deucher 	return 0;
130175758255SAlex Deucher }
130275758255SAlex Deucher 
130398d28ac2SNirmoy Das static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused)
130475758255SAlex Deucher {
130598d28ac2SNirmoy Das 	struct amdgpu_device *adev = (struct amdgpu_device *)m->private;
130698d28ac2SNirmoy Das 	struct drm_device *dev = adev_to_drm(adev);
130775758255SAlex Deucher 	int r = 0, i;
130875758255SAlex Deucher 
1309a9ffe2a9SAlex Deucher 	r = pm_runtime_get_sync(dev->dev);
13109eee152aSAlex Deucher 	if (r < 0) {
131198d28ac2SNirmoy Das 		pm_runtime_put_autosuspend(dev->dev);
1312a9ffe2a9SAlex Deucher 		return r;
13139eee152aSAlex Deucher 	}
1314a9ffe2a9SAlex Deucher 
1315a28fda31SAndrey Grodzovsky 	/* Avoid accidently unparking the sched thread during GPU reset */
1316d0fb18b5SAndrey Grodzovsky 	r = down_write_killable(&adev->reset_domain->sem);
13176049db43SDennis Li 	if (r)
13186049db43SDennis Li 		return r;
1319a28fda31SAndrey Grodzovsky 
132075758255SAlex Deucher 	/* hold on the scheduler */
132175758255SAlex Deucher 	for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
132275758255SAlex Deucher 		struct amdgpu_ring *ring = adev->rings[i];
132375758255SAlex Deucher 
132475758255SAlex Deucher 		if (!ring || !ring->sched.thread)
132575758255SAlex Deucher 			continue;
132675758255SAlex Deucher 		kthread_park(ring->sched.thread);
132775758255SAlex Deucher 	}
132875758255SAlex Deucher 
132975758255SAlex Deucher 	seq_printf(m, "run ib test:\n");
133075758255SAlex Deucher 	r = amdgpu_ib_ring_tests(adev);
133175758255SAlex Deucher 	if (r)
133275758255SAlex Deucher 		seq_printf(m, "ib ring tests failed (%d).\n", r);
133375758255SAlex Deucher 	else
133475758255SAlex Deucher 		seq_printf(m, "ib ring tests passed.\n");
133575758255SAlex Deucher 
133675758255SAlex Deucher 	/* go on the scheduler */
133775758255SAlex Deucher 	for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
133875758255SAlex Deucher 		struct amdgpu_ring *ring = adev->rings[i];
133975758255SAlex Deucher 
134075758255SAlex Deucher 		if (!ring || !ring->sched.thread)
134175758255SAlex Deucher 			continue;
134275758255SAlex Deucher 		kthread_unpark(ring->sched.thread);
134375758255SAlex Deucher 	}
134475758255SAlex Deucher 
1345d0fb18b5SAndrey Grodzovsky 	up_write(&adev->reset_domain->sem);
1346a28fda31SAndrey Grodzovsky 
1347a9ffe2a9SAlex Deucher 	pm_runtime_mark_last_busy(dev->dev);
1348a9ffe2a9SAlex Deucher 	pm_runtime_put_autosuspend(dev->dev);
1349a9ffe2a9SAlex Deucher 
135075758255SAlex Deucher 	return 0;
135175758255SAlex Deucher }
135275758255SAlex Deucher 
135398d28ac2SNirmoy Das static int amdgpu_debugfs_evict_vram(void *data, u64 *val)
135475758255SAlex Deucher {
135598d28ac2SNirmoy Das 	struct amdgpu_device *adev = (struct amdgpu_device *)data;
135698d28ac2SNirmoy Das 	struct drm_device *dev = adev_to_drm(adev);
1357a9ffe2a9SAlex Deucher 	int r;
1358a9ffe2a9SAlex Deucher 
1359a9ffe2a9SAlex Deucher 	r = pm_runtime_get_sync(dev->dev);
13609eee152aSAlex Deucher 	if (r < 0) {
136198d28ac2SNirmoy Das 		pm_runtime_put_autosuspend(dev->dev);
1362a9ffe2a9SAlex Deucher 		return r;
13639eee152aSAlex Deucher 	}
136475758255SAlex Deucher 
136558144d28SNirmoy Das 	*val = amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM);
1366a9ffe2a9SAlex Deucher 
1367a9ffe2a9SAlex Deucher 	pm_runtime_mark_last_busy(dev->dev);
1368a9ffe2a9SAlex Deucher 	pm_runtime_put_autosuspend(dev->dev);
1369a9ffe2a9SAlex Deucher 
137075758255SAlex Deucher 	return 0;
137175758255SAlex Deucher }
137275758255SAlex Deucher 
137398d28ac2SNirmoy Das 
137498d28ac2SNirmoy Das static int amdgpu_debugfs_evict_gtt(void *data, u64 *val)
137587e90c76SChristian König {
137698d28ac2SNirmoy Das 	struct amdgpu_device *adev = (struct amdgpu_device *)data;
137798d28ac2SNirmoy Das 	struct drm_device *dev = adev_to_drm(adev);
1378a9ffe2a9SAlex Deucher 	int r;
1379a9ffe2a9SAlex Deucher 
1380a9ffe2a9SAlex Deucher 	r = pm_runtime_get_sync(dev->dev);
13819eee152aSAlex Deucher 	if (r < 0) {
138258144d28SNirmoy Das 		pm_runtime_put_autosuspend(dev->dev);
1383a9ffe2a9SAlex Deucher 		return r;
13849eee152aSAlex Deucher 	}
138587e90c76SChristian König 
138658144d28SNirmoy Das 	*val = amdgpu_ttm_evict_resources(adev, TTM_PL_TT);
1387a9ffe2a9SAlex Deucher 
1388a9ffe2a9SAlex Deucher 	pm_runtime_mark_last_busy(dev->dev);
1389a9ffe2a9SAlex Deucher 	pm_runtime_put_autosuspend(dev->dev);
1390a9ffe2a9SAlex Deucher 
139187e90c76SChristian König 	return 0;
139287e90c76SChristian König }
139387e90c76SChristian König 
1394e7c47231SAlex Deucher static int amdgpu_debugfs_benchmark(void *data, u64 val)
1395e7c47231SAlex Deucher {
1396e7c47231SAlex Deucher 	struct amdgpu_device *adev = (struct amdgpu_device *)data;
1397e7c47231SAlex Deucher 	struct drm_device *dev = adev_to_drm(adev);
1398e7c47231SAlex Deucher 	int r;
1399e7c47231SAlex Deucher 
1400e7c47231SAlex Deucher 	r = pm_runtime_get_sync(dev->dev);
1401e7c47231SAlex Deucher 	if (r < 0) {
1402e7c47231SAlex Deucher 		pm_runtime_put_autosuspend(dev->dev);
1403e7c47231SAlex Deucher 		return r;
1404e7c47231SAlex Deucher 	}
1405e7c47231SAlex Deucher 
1406e7c47231SAlex Deucher 	r = amdgpu_benchmark(adev, val);
1407e7c47231SAlex Deucher 
1408e7c47231SAlex Deucher 	pm_runtime_mark_last_busy(dev->dev);
1409e7c47231SAlex Deucher 	pm_runtime_put_autosuspend(dev->dev);
1410e7c47231SAlex Deucher 
1411e7c47231SAlex Deucher 	return r;
1412e7c47231SAlex Deucher }
141398d28ac2SNirmoy Das 
141498d28ac2SNirmoy Das static int amdgpu_debugfs_vm_info_show(struct seq_file *m, void *unused)
1415ff72bc40SMihir Bhogilal Patel {
141698d28ac2SNirmoy Das 	struct amdgpu_device *adev = (struct amdgpu_device *)m->private;
141798d28ac2SNirmoy Das 	struct drm_device *dev = adev_to_drm(adev);
1418ff72bc40SMihir Bhogilal Patel 	struct drm_file *file;
1419ff72bc40SMihir Bhogilal Patel 	int r;
1420ff72bc40SMihir Bhogilal Patel 
1421ff72bc40SMihir Bhogilal Patel 	r = mutex_lock_interruptible(&dev->filelist_mutex);
1422ff72bc40SMihir Bhogilal Patel 	if (r)
1423ff72bc40SMihir Bhogilal Patel 		return r;
1424ff72bc40SMihir Bhogilal Patel 
1425ff72bc40SMihir Bhogilal Patel 	list_for_each_entry(file, &dev->filelist, lhead) {
1426ff72bc40SMihir Bhogilal Patel 		struct amdgpu_fpriv *fpriv = file->driver_priv;
1427ff72bc40SMihir Bhogilal Patel 		struct amdgpu_vm *vm = &fpriv->vm;
1428ff72bc40SMihir Bhogilal Patel 
1429ff72bc40SMihir Bhogilal Patel 		seq_printf(m, "pid:%d\tProcess:%s ----------\n",
1430ff72bc40SMihir Bhogilal Patel 				vm->task_info.pid, vm->task_info.process_name);
1431391629bdSNirmoy Das 		r = amdgpu_bo_reserve(vm->root.bo, true);
1432ff72bc40SMihir Bhogilal Patel 		if (r)
1433ff72bc40SMihir Bhogilal Patel 			break;
1434ff72bc40SMihir Bhogilal Patel 		amdgpu_debugfs_vm_bo_info(vm, m);
1435391629bdSNirmoy Das 		amdgpu_bo_unreserve(vm->root.bo);
1436ff72bc40SMihir Bhogilal Patel 	}
1437ff72bc40SMihir Bhogilal Patel 
1438ff72bc40SMihir Bhogilal Patel 	mutex_unlock(&dev->filelist_mutex);
1439ff72bc40SMihir Bhogilal Patel 
1440ff72bc40SMihir Bhogilal Patel 	return r;
1441ff72bc40SMihir Bhogilal Patel }
1442ff72bc40SMihir Bhogilal Patel 
144398d28ac2SNirmoy Das DEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_test_ib);
144498d28ac2SNirmoy Das DEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_vm_info);
144598d28ac2SNirmoy Das DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_evict_vram_fops, amdgpu_debugfs_evict_vram,
144698d28ac2SNirmoy Das 			 NULL, "%lld\n");
144798d28ac2SNirmoy Das DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_evict_gtt_fops, amdgpu_debugfs_evict_gtt,
144898d28ac2SNirmoy Das 			 NULL, "%lld\n");
1449e7c47231SAlex Deucher DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_benchmark_fops, NULL, amdgpu_debugfs_benchmark,
1450e7c47231SAlex Deucher 			 "%lld\n");
145175758255SAlex Deucher 
14526698a3d0SJack Xiao static void amdgpu_ib_preempt_fences_swap(struct amdgpu_ring *ring,
14536698a3d0SJack Xiao 					  struct dma_fence **fences)
14546698a3d0SJack Xiao {
14556698a3d0SJack Xiao 	struct amdgpu_fence_driver *drv = &ring->fence_drv;
14566698a3d0SJack Xiao 	uint32_t sync_seq, last_seq;
14576698a3d0SJack Xiao 
14586698a3d0SJack Xiao 	last_seq = atomic_read(&ring->fence_drv.last_seq);
14596698a3d0SJack Xiao 	sync_seq = ring->fence_drv.sync_seq;
14606698a3d0SJack Xiao 
14616698a3d0SJack Xiao 	last_seq &= drv->num_fences_mask;
14626698a3d0SJack Xiao 	sync_seq &= drv->num_fences_mask;
14636698a3d0SJack Xiao 
14646698a3d0SJack Xiao 	do {
14656698a3d0SJack Xiao 		struct dma_fence *fence, **ptr;
14666698a3d0SJack Xiao 
14676698a3d0SJack Xiao 		++last_seq;
14686698a3d0SJack Xiao 		last_seq &= drv->num_fences_mask;
14696698a3d0SJack Xiao 		ptr = &drv->fences[last_seq];
14706698a3d0SJack Xiao 
14716698a3d0SJack Xiao 		fence = rcu_dereference_protected(*ptr, 1);
14726698a3d0SJack Xiao 		RCU_INIT_POINTER(*ptr, NULL);
14736698a3d0SJack Xiao 
14746698a3d0SJack Xiao 		if (!fence)
14756698a3d0SJack Xiao 			continue;
14766698a3d0SJack Xiao 
14776698a3d0SJack Xiao 		fences[last_seq] = fence;
14786698a3d0SJack Xiao 
14796698a3d0SJack Xiao 	} while (last_seq != sync_seq);
14806698a3d0SJack Xiao }
14816698a3d0SJack Xiao 
14826698a3d0SJack Xiao static void amdgpu_ib_preempt_signal_fences(struct dma_fence **fences,
14836698a3d0SJack Xiao 					    int length)
14846698a3d0SJack Xiao {
14856698a3d0SJack Xiao 	int i;
14866698a3d0SJack Xiao 	struct dma_fence *fence;
14876698a3d0SJack Xiao 
14886698a3d0SJack Xiao 	for (i = 0; i < length; i++) {
14896698a3d0SJack Xiao 		fence = fences[i];
14906698a3d0SJack Xiao 		if (!fence)
14916698a3d0SJack Xiao 			continue;
14926698a3d0SJack Xiao 		dma_fence_signal(fence);
14936698a3d0SJack Xiao 		dma_fence_put(fence);
14946698a3d0SJack Xiao 	}
14956698a3d0SJack Xiao }
14966698a3d0SJack Xiao 
14976698a3d0SJack Xiao static void amdgpu_ib_preempt_job_recovery(struct drm_gpu_scheduler *sched)
14986698a3d0SJack Xiao {
14996698a3d0SJack Xiao 	struct drm_sched_job *s_job;
15006698a3d0SJack Xiao 	struct dma_fence *fence;
15016698a3d0SJack Xiao 
15026698a3d0SJack Xiao 	spin_lock(&sched->job_list_lock);
15036efa4b46SLuben Tuikov 	list_for_each_entry(s_job, &sched->pending_list, list) {
15046698a3d0SJack Xiao 		fence = sched->ops->run_job(s_job);
15056698a3d0SJack Xiao 		dma_fence_put(fence);
15066698a3d0SJack Xiao 	}
15076698a3d0SJack Xiao 	spin_unlock(&sched->job_list_lock);
15086698a3d0SJack Xiao }
15096698a3d0SJack Xiao 
151080f8fb91SJack Xiao static void amdgpu_ib_preempt_mark_partial_job(struct amdgpu_ring *ring)
151180f8fb91SJack Xiao {
151280f8fb91SJack Xiao 	struct amdgpu_job *job;
15137bdb0899SJack Xiao 	struct drm_sched_job *s_job, *tmp;
151480f8fb91SJack Xiao 	uint32_t preempt_seq;
151580f8fb91SJack Xiao 	struct dma_fence *fence, **ptr;
151680f8fb91SJack Xiao 	struct amdgpu_fence_driver *drv = &ring->fence_drv;
151780f8fb91SJack Xiao 	struct drm_gpu_scheduler *sched = &ring->sched;
15187bdb0899SJack Xiao 	bool preempted = true;
151980f8fb91SJack Xiao 
152080f8fb91SJack Xiao 	if (ring->funcs->type != AMDGPU_RING_TYPE_GFX)
152180f8fb91SJack Xiao 		return;
152280f8fb91SJack Xiao 
152380f8fb91SJack Xiao 	preempt_seq = le32_to_cpu(*(drv->cpu_addr + 2));
15247bdb0899SJack Xiao 	if (preempt_seq <= atomic_read(&drv->last_seq)) {
15257bdb0899SJack Xiao 		preempted = false;
15267bdb0899SJack Xiao 		goto no_preempt;
15277bdb0899SJack Xiao 	}
152880f8fb91SJack Xiao 
152980f8fb91SJack Xiao 	preempt_seq &= drv->num_fences_mask;
153080f8fb91SJack Xiao 	ptr = &drv->fences[preempt_seq];
153180f8fb91SJack Xiao 	fence = rcu_dereference_protected(*ptr, 1);
153280f8fb91SJack Xiao 
15337bdb0899SJack Xiao no_preempt:
153480f8fb91SJack Xiao 	spin_lock(&sched->job_list_lock);
15356efa4b46SLuben Tuikov 	list_for_each_entry_safe(s_job, tmp, &sched->pending_list, list) {
15367bdb0899SJack Xiao 		if (dma_fence_is_signaled(&s_job->s_fence->finished)) {
15377bdb0899SJack Xiao 			/* remove job from ring_mirror_list */
15388935ff00SLuben Tuikov 			list_del_init(&s_job->list);
15397bdb0899SJack Xiao 			sched->ops->free_job(s_job);
15407bdb0899SJack Xiao 			continue;
15417bdb0899SJack Xiao 		}
154280f8fb91SJack Xiao 		job = to_amdgpu_job(s_job);
1543c530b02fSJack Zhang 		if (preempted && (&job->hw_fence) == fence)
154480f8fb91SJack Xiao 			/* mark the job as preempted */
154580f8fb91SJack Xiao 			job->preemption_status |= AMDGPU_IB_PREEMPTED;
154680f8fb91SJack Xiao 	}
154780f8fb91SJack Xiao 	spin_unlock(&sched->job_list_lock);
154880f8fb91SJack Xiao }
154980f8fb91SJack Xiao 
15506698a3d0SJack Xiao static int amdgpu_debugfs_ib_preempt(void *data, u64 val)
15516698a3d0SJack Xiao {
15526698a3d0SJack Xiao 	int r, resched, length;
15536698a3d0SJack Xiao 	struct amdgpu_ring *ring;
15546698a3d0SJack Xiao 	struct dma_fence **fences = NULL;
15556698a3d0SJack Xiao 	struct amdgpu_device *adev = (struct amdgpu_device *)data;
15566698a3d0SJack Xiao 
15576698a3d0SJack Xiao 	if (val >= AMDGPU_MAX_RINGS)
15586698a3d0SJack Xiao 		return -EINVAL;
15596698a3d0SJack Xiao 
15606698a3d0SJack Xiao 	ring = adev->rings[val];
15616698a3d0SJack Xiao 
15626698a3d0SJack Xiao 	if (!ring || !ring->funcs->preempt_ib || !ring->sched.thread)
15636698a3d0SJack Xiao 		return -EINVAL;
15646698a3d0SJack Xiao 
15656698a3d0SJack Xiao 	/* the last preemption failed */
15666698a3d0SJack Xiao 	if (ring->trail_seq != le32_to_cpu(*ring->trail_fence_cpu_addr))
15676698a3d0SJack Xiao 		return -EBUSY;
15686698a3d0SJack Xiao 
15696698a3d0SJack Xiao 	length = ring->fence_drv.num_fences_mask + 1;
15706698a3d0SJack Xiao 	fences = kcalloc(length, sizeof(void *), GFP_KERNEL);
15716698a3d0SJack Xiao 	if (!fences)
15726698a3d0SJack Xiao 		return -ENOMEM;
15736698a3d0SJack Xiao 
1574a28fda31SAndrey Grodzovsky 	/* Avoid accidently unparking the sched thread during GPU reset */
1575d0fb18b5SAndrey Grodzovsky 	r = down_read_killable(&adev->reset_domain->sem);
15766049db43SDennis Li 	if (r)
15776049db43SDennis Li 		goto pro_end;
1578a28fda31SAndrey Grodzovsky 
15796698a3d0SJack Xiao 	/* stop the scheduler */
15806698a3d0SJack Xiao 	kthread_park(ring->sched.thread);
15816698a3d0SJack Xiao 
15826698a3d0SJack Xiao 	resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
15836698a3d0SJack Xiao 
15846698a3d0SJack Xiao 	/* preempt the IB */
15856698a3d0SJack Xiao 	r = amdgpu_ring_preempt_ib(ring);
15866698a3d0SJack Xiao 	if (r) {
15876698a3d0SJack Xiao 		DRM_WARN("failed to preempt ring %d\n", ring->idx);
15886698a3d0SJack Xiao 		goto failure;
15896698a3d0SJack Xiao 	}
15906698a3d0SJack Xiao 
15916698a3d0SJack Xiao 	amdgpu_fence_process(ring);
15926698a3d0SJack Xiao 
15936698a3d0SJack Xiao 	if (atomic_read(&ring->fence_drv.last_seq) !=
15946698a3d0SJack Xiao 	    ring->fence_drv.sync_seq) {
15956698a3d0SJack Xiao 		DRM_INFO("ring %d was preempted\n", ring->idx);
15966698a3d0SJack Xiao 
159780f8fb91SJack Xiao 		amdgpu_ib_preempt_mark_partial_job(ring);
159880f8fb91SJack Xiao 
15996698a3d0SJack Xiao 		/* swap out the old fences */
16006698a3d0SJack Xiao 		amdgpu_ib_preempt_fences_swap(ring, fences);
16016698a3d0SJack Xiao 
16026698a3d0SJack Xiao 		amdgpu_fence_driver_force_completion(ring);
16036698a3d0SJack Xiao 
16046698a3d0SJack Xiao 		/* resubmit unfinished jobs */
16056698a3d0SJack Xiao 		amdgpu_ib_preempt_job_recovery(&ring->sched);
16066698a3d0SJack Xiao 
16076698a3d0SJack Xiao 		/* wait for jobs finished */
16086698a3d0SJack Xiao 		amdgpu_fence_wait_empty(ring);
16096698a3d0SJack Xiao 
16106698a3d0SJack Xiao 		/* signal the old fences */
16116698a3d0SJack Xiao 		amdgpu_ib_preempt_signal_fences(fences, length);
16126698a3d0SJack Xiao 	}
16136698a3d0SJack Xiao 
16146698a3d0SJack Xiao failure:
16156698a3d0SJack Xiao 	/* restart the scheduler */
16166698a3d0SJack Xiao 	kthread_unpark(ring->sched.thread);
16176698a3d0SJack Xiao 
1618d0fb18b5SAndrey Grodzovsky 	up_read(&adev->reset_domain->sem);
1619a28fda31SAndrey Grodzovsky 
16206698a3d0SJack Xiao 	ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched);
16216698a3d0SJack Xiao 
16226049db43SDennis Li pro_end:
16236698a3d0SJack Xiao 	kfree(fences);
16246698a3d0SJack Xiao 
16256049db43SDennis Li 	return r;
16266698a3d0SJack Xiao }
16276698a3d0SJack Xiao 
16280cf64555SChengming Gui static int amdgpu_debugfs_sclk_set(void *data, u64 val)
16290cf64555SChengming Gui {
16300cf64555SChengming Gui 	int ret = 0;
16310cf64555SChengming Gui 	uint32_t max_freq, min_freq;
16320cf64555SChengming Gui 	struct amdgpu_device *adev = (struct amdgpu_device *)data;
16330cf64555SChengming Gui 
16340cf64555SChengming Gui 	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev))
16350cf64555SChengming Gui 		return -EINVAL;
16360cf64555SChengming Gui 
16374a580877SLuben Tuikov 	ret = pm_runtime_get_sync(adev_to_drm(adev)->dev);
16389eee152aSAlex Deucher 	if (ret < 0) {
16394a580877SLuben Tuikov 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
16400cf64555SChengming Gui 		return ret;
16419eee152aSAlex Deucher 	}
16420cf64555SChengming Gui 
1643bc143d8bSEvan Quan 	ret = amdgpu_dpm_get_dpm_freq_range(adev, PP_SCLK, &min_freq, &max_freq);
1644bc143d8bSEvan Quan 	if (ret == -EOPNOTSUPP) {
1645bc143d8bSEvan Quan 		ret = 0;
1646bc143d8bSEvan Quan 		goto out;
1647bc143d8bSEvan Quan 	}
1648bc143d8bSEvan Quan 	if (ret || val > max_freq || val < min_freq) {
1649bc143d8bSEvan Quan 		ret = -EINVAL;
1650bc143d8bSEvan Quan 		goto out;
16510cf64555SChengming Gui 	}
16520cf64555SChengming Gui 
1653bc143d8bSEvan Quan 	ret = amdgpu_dpm_set_soft_freq_range(adev, PP_SCLK, (uint32_t)val, (uint32_t)val);
1654bc143d8bSEvan Quan 	if (ret)
1655bc143d8bSEvan Quan 		ret = -EINVAL;
1656bc143d8bSEvan Quan 
1657bc143d8bSEvan Quan out:
16584a580877SLuben Tuikov 	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev);
16594a580877SLuben Tuikov 	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
16600cf64555SChengming Gui 
1661bc143d8bSEvan Quan 	return ret;
16620cf64555SChengming Gui }
16630cf64555SChengming Gui 
16647271a5c2SYang Li DEFINE_DEBUGFS_ATTRIBUTE(fops_ib_preempt, NULL,
16656698a3d0SJack Xiao 			amdgpu_debugfs_ib_preempt, "%llu\n");
16666698a3d0SJack Xiao 
16677271a5c2SYang Li DEFINE_DEBUGFS_ATTRIBUTE(fops_sclk_set, NULL,
16680cf64555SChengming Gui 			amdgpu_debugfs_sclk_set, "%llu\n");
16690cf64555SChengming Gui 
16705ce5a584SSomalapuram Amaranath static ssize_t amdgpu_reset_dump_register_list_read(struct file *f,
16715ce5a584SSomalapuram Amaranath 				char __user *buf, size_t size, loff_t *pos)
16725ce5a584SSomalapuram Amaranath {
16735ce5a584SSomalapuram Amaranath 	struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
16745ce5a584SSomalapuram Amaranath 	char reg_offset[12];
16755ce5a584SSomalapuram Amaranath 	int i, ret, len = 0;
16765ce5a584SSomalapuram Amaranath 
16775ce5a584SSomalapuram Amaranath 	if (*pos)
16785ce5a584SSomalapuram Amaranath 		return 0;
16795ce5a584SSomalapuram Amaranath 
16805ce5a584SSomalapuram Amaranath 	memset(reg_offset, 0, 12);
168138a15ad9SDave Airlie 	ret = down_read_killable(&adev->reset_domain->sem);
16825ce5a584SSomalapuram Amaranath 	if (ret)
16835ce5a584SSomalapuram Amaranath 		return ret;
16845ce5a584SSomalapuram Amaranath 
16855ce5a584SSomalapuram Amaranath 	for (i = 0; i < adev->num_regs; i++) {
16865ce5a584SSomalapuram Amaranath 		sprintf(reg_offset, "0x%x\n", adev->reset_dump_reg_list[i]);
168738a15ad9SDave Airlie 		up_read(&adev->reset_domain->sem);
16885ce5a584SSomalapuram Amaranath 		if (copy_to_user(buf + len, reg_offset, strlen(reg_offset)))
16895ce5a584SSomalapuram Amaranath 			return -EFAULT;
16905ce5a584SSomalapuram Amaranath 
16915ce5a584SSomalapuram Amaranath 		len += strlen(reg_offset);
169238a15ad9SDave Airlie 		ret = down_read_killable(&adev->reset_domain->sem);
16935ce5a584SSomalapuram Amaranath 		if (ret)
16945ce5a584SSomalapuram Amaranath 			return ret;
16955ce5a584SSomalapuram Amaranath 	}
16965ce5a584SSomalapuram Amaranath 
169738a15ad9SDave Airlie 	up_read(&adev->reset_domain->sem);
16985ce5a584SSomalapuram Amaranath 	*pos += len;
16995ce5a584SSomalapuram Amaranath 
17005ce5a584SSomalapuram Amaranath 	return len;
17015ce5a584SSomalapuram Amaranath }
17025ce5a584SSomalapuram Amaranath 
17035ce5a584SSomalapuram Amaranath static ssize_t amdgpu_reset_dump_register_list_write(struct file *f,
17045ce5a584SSomalapuram Amaranath 			const char __user *buf, size_t size, loff_t *pos)
17055ce5a584SSomalapuram Amaranath {
17065ce5a584SSomalapuram Amaranath 	struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
17075ce5a584SSomalapuram Amaranath 	char reg_offset[11];
1708*ad2feebdSSebin Sebastian 	uint32_t *new = NULL, *tmp = NULL;
17095ce5a584SSomalapuram Amaranath 	int ret, i = 0, len = 0;
17105ce5a584SSomalapuram Amaranath 
17115ce5a584SSomalapuram Amaranath 	do {
17125ce5a584SSomalapuram Amaranath 		memset(reg_offset, 0, 11);
17135ce5a584SSomalapuram Amaranath 		if (copy_from_user(reg_offset, buf + len,
17145ce5a584SSomalapuram Amaranath 					min(10, ((int)size-len)))) {
17155ce5a584SSomalapuram Amaranath 			ret = -EFAULT;
17165ce5a584SSomalapuram Amaranath 			goto error_free;
17175ce5a584SSomalapuram Amaranath 		}
17185ce5a584SSomalapuram Amaranath 
1719ca6fcfa8STom Rix 		new = krealloc_array(tmp, i + 1, sizeof(uint32_t), GFP_KERNEL);
1720ca6fcfa8STom Rix 		if (!new) {
1721ca6fcfa8STom Rix 			ret = -ENOMEM;
1722ca6fcfa8STom Rix 			goto error_free;
1723ca6fcfa8STom Rix 		}
1724ca6fcfa8STom Rix 		tmp = new;
17255ce5a584SSomalapuram Amaranath 		if (sscanf(reg_offset, "%X %n", &tmp[i], &ret) != 1) {
17265ce5a584SSomalapuram Amaranath 			ret = -EINVAL;
17275ce5a584SSomalapuram Amaranath 			goto error_free;
17285ce5a584SSomalapuram Amaranath 		}
17295ce5a584SSomalapuram Amaranath 
17305ce5a584SSomalapuram Amaranath 		len += ret;
17315ce5a584SSomalapuram Amaranath 		i++;
17325ce5a584SSomalapuram Amaranath 	} while (len < size);
17335ce5a584SSomalapuram Amaranath 
1734651d7ee6SSomalapuram Amaranath 	new = kmalloc_array(i, sizeof(uint32_t), GFP_KERNEL);
1735651d7ee6SSomalapuram Amaranath 	if (!new) {
1736651d7ee6SSomalapuram Amaranath 		ret = -ENOMEM;
1737651d7ee6SSomalapuram Amaranath 		goto error_free;
1738651d7ee6SSomalapuram Amaranath 	}
173938a15ad9SDave Airlie 	ret = down_write_killable(&adev->reset_domain->sem);
17405ce5a584SSomalapuram Amaranath 	if (ret)
17415ce5a584SSomalapuram Amaranath 		goto error_free;
17425ce5a584SSomalapuram Amaranath 
17435ce5a584SSomalapuram Amaranath 	swap(adev->reset_dump_reg_list, tmp);
1744651d7ee6SSomalapuram Amaranath 	swap(adev->reset_dump_reg_value, new);
17455ce5a584SSomalapuram Amaranath 	adev->num_regs = i;
174638a15ad9SDave Airlie 	up_write(&adev->reset_domain->sem);
17475ce5a584SSomalapuram Amaranath 	ret = size;
17485ce5a584SSomalapuram Amaranath 
17495ce5a584SSomalapuram Amaranath error_free:
1750*ad2feebdSSebin Sebastian 	if (tmp != new)
17515ce5a584SSomalapuram Amaranath 		kfree(tmp);
1752651d7ee6SSomalapuram Amaranath 	kfree(new);
17535ce5a584SSomalapuram Amaranath 	return ret;
17545ce5a584SSomalapuram Amaranath }
17555ce5a584SSomalapuram Amaranath 
17565ce5a584SSomalapuram Amaranath static const struct file_operations amdgpu_reset_dump_register_list = {
17575ce5a584SSomalapuram Amaranath 	.owner = THIS_MODULE,
17585ce5a584SSomalapuram Amaranath 	.read = amdgpu_reset_dump_register_list_read,
17595ce5a584SSomalapuram Amaranath 	.write = amdgpu_reset_dump_register_list_write,
17605ce5a584SSomalapuram Amaranath 	.llseek = default_llseek
17615ce5a584SSomalapuram Amaranath };
17625ce5a584SSomalapuram Amaranath 
176375758255SAlex Deucher int amdgpu_debugfs_init(struct amdgpu_device *adev)
176475758255SAlex Deucher {
176598d28ac2SNirmoy Das 	struct dentry *root = adev_to_drm(adev)->primary->debugfs_root;
176688293c03SNirmoy Das 	struct dentry *ent;
1767fd23cfccSAlex Deucher 	int r, i;
1768c5820361SAlex Deucher 
17695b9581dfSNirmoy Das 	if (!debugfs_initialized())
17705b9581dfSNirmoy Das 		return 0;
17715b9581dfSNirmoy Das 
17726ff7fddbSLang Yu 	debugfs_create_x32("amdgpu_smu_debug", 0600, root,
17737e31a858SEvan Quan 			   &adev->pm.smu_debug_mask);
17746ff7fddbSLang Yu 
177598d28ac2SNirmoy Das 	ent = debugfs_create_file("amdgpu_preempt_ib", 0600, root, adev,
177644b582b3SGeert Uytterhoeven 				  &fops_ib_preempt);
177759715cffSNirmoy Das 	if (IS_ERR(ent)) {
17786698a3d0SJack Xiao 		DRM_ERROR("unable to create amdgpu_preempt_ib debugsfs file\n");
177959715cffSNirmoy Das 		return PTR_ERR(ent);
17806698a3d0SJack Xiao 	}
17816698a3d0SJack Xiao 
178298d28ac2SNirmoy Das 	ent = debugfs_create_file("amdgpu_force_sclk", 0200, root, adev,
17830cf64555SChengming Gui 				  &fops_sclk_set);
178459715cffSNirmoy Das 	if (IS_ERR(ent)) {
17850cf64555SChengming Gui 		DRM_ERROR("unable to create amdgpu_set_sclk debugsfs file\n");
178659715cffSNirmoy Das 		return PTR_ERR(ent);
17870cf64555SChengming Gui 	}
17880cf64555SChengming Gui 
1789c5820361SAlex Deucher 	/* Register debugfs entries for amdgpu_ttm */
179098d28ac2SNirmoy Das 	amdgpu_ttm_debugfs_init(adev);
1791373720f7SNirmoy Das 	amdgpu_debugfs_pm_init(adev);
179298d28ac2SNirmoy Das 	amdgpu_debugfs_sa_init(adev);
179398d28ac2SNirmoy Das 	amdgpu_debugfs_fence_init(adev);
179498d28ac2SNirmoy Das 	amdgpu_debugfs_gem_init(adev);
17953f5cea67SAlex Deucher 
1796f9d64e6cSAlex Deucher 	r = amdgpu_debugfs_regs_init(adev);
1797f9d64e6cSAlex Deucher 	if (r)
1798f9d64e6cSAlex Deucher 		DRM_ERROR("registering register debugfs failed (%d).\n", r);
1799f9d64e6cSAlex Deucher 
180098d28ac2SNirmoy Das 	amdgpu_debugfs_firmware_init(adev);
1801e50d9ba0SCandice Li 	amdgpu_ta_if_debugfs_init(adev);
1802cd9e29e7SAlex Deucher 
1803d090e7dbSAlex Deucher #if defined(CONFIG_DRM_AMD_DC)
1804afd3a359SNirmoy Das 	if (amdgpu_device_has_dc_support(adev))
1805afd3a359SNirmoy Das 		dtn_debugfs_init(adev);
1806d090e7dbSAlex Deucher #endif
1807d090e7dbSAlex Deucher 
1808fd23cfccSAlex Deucher 	for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
1809fd23cfccSAlex Deucher 		struct amdgpu_ring *ring = adev->rings[i];
1810fd23cfccSAlex Deucher 
1811fd23cfccSAlex Deucher 		if (!ring)
1812fd23cfccSAlex Deucher 			continue;
1813fd23cfccSAlex Deucher 
181462d266b2SNirmoy Das 		amdgpu_debugfs_ring_init(adev, ring);
1815fd23cfccSAlex Deucher 	}
1816fd23cfccSAlex Deucher 
181711eb648dSRuijing Dong 	for ( i = 0; i < adev->vcn.num_vcn_inst; i++) {
181811eb648dSRuijing Dong 		if (!amdgpu_vcnfw_log)
181911eb648dSRuijing Dong 			break;
182011eb648dSRuijing Dong 
182111eb648dSRuijing Dong 		if (adev->vcn.harvest_config & (1 << i))
182211eb648dSRuijing Dong 			continue;
182311eb648dSRuijing Dong 
182411eb648dSRuijing Dong 		amdgpu_debugfs_vcn_fwlog_init(adev, i, &adev->vcn.inst[i]);
182511eb648dSRuijing Dong 	}
182611eb648dSRuijing Dong 
1827204eaac6STao Zhou 	amdgpu_ras_debugfs_create_all(adev);
1828a4322e18SWenhui Sheng 	amdgpu_rap_debugfs_init(adev);
1829ecaafb7bSJinzhou Su 	amdgpu_securedisplay_debugfs_init(adev);
183019ae3330SJohn Clements 	amdgpu_fw_attestation_debugfs_init(adev);
183119ae3330SJohn Clements 
183298d28ac2SNirmoy Das 	debugfs_create_file("amdgpu_evict_vram", 0444, root, adev,
183398d28ac2SNirmoy Das 			    &amdgpu_evict_vram_fops);
183498d28ac2SNirmoy Das 	debugfs_create_file("amdgpu_evict_gtt", 0444, root, adev,
183598d28ac2SNirmoy Das 			    &amdgpu_evict_gtt_fops);
183698d28ac2SNirmoy Das 	debugfs_create_file("amdgpu_test_ib", 0444, root, adev,
183798d28ac2SNirmoy Das 			    &amdgpu_debugfs_test_ib_fops);
183898d28ac2SNirmoy Das 	debugfs_create_file("amdgpu_vm_info", 0444, root, adev,
183998d28ac2SNirmoy Das 			    &amdgpu_debugfs_vm_info_fops);
1840e7c47231SAlex Deucher 	debugfs_create_file("amdgpu_benchmark", 0200, root, adev,
1841e7c47231SAlex Deucher 			    &amdgpu_benchmark_fops);
18425ce5a584SSomalapuram Amaranath 	debugfs_create_file("amdgpu_reset_dump_register_list", 0644, root, adev,
18435ce5a584SSomalapuram Amaranath 			    &amdgpu_reset_dump_register_list);
184498d28ac2SNirmoy Das 
184598d28ac2SNirmoy Das 	adev->debugfs_vbios_blob.data = adev->bios;
184698d28ac2SNirmoy Das 	adev->debugfs_vbios_blob.size = adev->bios_size;
184798d28ac2SNirmoy Das 	debugfs_create_blob("amdgpu_vbios", 0444, root,
184898d28ac2SNirmoy Das 			    &adev->debugfs_vbios_blob);
184998d28ac2SNirmoy Das 
185081d1bf01SAlex Deucher 	adev->debugfs_discovery_blob.data = adev->mman.discovery_bin;
185181d1bf01SAlex Deucher 	adev->debugfs_discovery_blob.size = adev->mman.discovery_tmr_size;
185281d1bf01SAlex Deucher 	debugfs_create_blob("amdgpu_discovery", 0444, root,
185381d1bf01SAlex Deucher 			    &adev->debugfs_discovery_blob);
185481d1bf01SAlex Deucher 
185598d28ac2SNirmoy Das 	return 0;
185675758255SAlex Deucher }
185775758255SAlex Deucher 
185875758255SAlex Deucher #else
185975758255SAlex Deucher int amdgpu_debugfs_init(struct amdgpu_device *adev)
186075758255SAlex Deucher {
186175758255SAlex Deucher 	return 0;
186275758255SAlex Deucher }
186375758255SAlex Deucher int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)
186475758255SAlex Deucher {
186575758255SAlex Deucher 	return 0;
186675758255SAlex Deucher }
186775758255SAlex Deucher #endif
1868