diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 170 | 
1 files changed, 170 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index cb00c7d6f50b..6066aebf491c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -1043,6 +1043,157 @@ err:  }  /** + * amdgpu_debugfs_gfxoff_residency_read - Read GFXOFF residency + * + * @f: open file handle + * @buf: User buffer to store read data in + * @size: Number of bytes to read + * @pos:  Offset to seek to + * + * Read the last residency value logged. It doesn't auto update, one needs to + * stop logging before getting the current value. + */ +static ssize_t amdgpu_debugfs_gfxoff_residency_read(struct file *f, char __user *buf, +						    size_t size, loff_t *pos) +{ +	struct amdgpu_device *adev = file_inode(f)->i_private; +	ssize_t result = 0; +	int r; + +	if (size & 0x3 || *pos & 0x3) +		return -EINVAL; + +	r = pm_runtime_get_sync(adev_to_drm(adev)->dev); +	if (r < 0) { +		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); +		return r; +	} + +	while (size) { +		uint32_t value; + +		r = amdgpu_get_gfx_off_residency(adev, &value); +		if (r) +			goto out; + +		r = put_user(value, (uint32_t *)buf); +		if (r) +			goto out; + +		result += 4; +		buf += 4; +		*pos += 4; +		size -= 4; +	} + +	r = result; +out: +	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); +	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + +	return r; +} + +/** + * amdgpu_debugfs_gfxoff_residency_write - Log GFXOFF Residency + * + * @f: open file handle + * @buf: User buffer to write data from + * @size: Number of bytes to write + * @pos:  Offset to seek to + * + * Write a 32-bit non-zero to start logging; write a 32-bit zero to stop + */ +static ssize_t amdgpu_debugfs_gfxoff_residency_write(struct file *f, const char __user *buf, +						     size_t size, loff_t *pos) +{ +	struct amdgpu_device *adev = file_inode(f)->i_private; +	ssize_t result = 0; +	int r; + +	if (size & 0x3 || *pos & 0x3) +		return -EINVAL; + +	r = pm_runtime_get_sync(adev_to_drm(adev)->dev); +	if (r < 0) { +		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); +		return r; +	} + +	while (size) { +		u32 value; + +		r = get_user(value, (uint32_t *)buf); +		if (r) +			goto out; + +		amdgpu_set_gfx_off_residency(adev, value ? true : false); + +		result += 4; +		buf += 4; +		*pos += 4; +		size -= 4; +	} + +	r = result; +out: +	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); +	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + +	return r; +} + + +/** + * amdgpu_debugfs_gfxoff_count_read - Read GFXOFF entry count + * + * @f: open file handle + * @buf: User buffer to store read data in + * @size: Number of bytes to read + * @pos:  Offset to seek to + */ +static ssize_t amdgpu_debugfs_gfxoff_count_read(struct file *f, char __user *buf, +						size_t size, loff_t *pos) +{ +	struct amdgpu_device *adev = file_inode(f)->i_private; +	ssize_t result = 0; +	int r; + +	if (size & 0x3 || *pos & 0x3) +		return -EINVAL; + +	r = pm_runtime_get_sync(adev_to_drm(adev)->dev); +	if (r < 0) { +		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); +		return r; +	} + +	while (size) { +		u64 value = 0; + +		r = amdgpu_get_gfx_off_entrycount(adev, &value); +		if (r) +			goto out; + +		r = put_user(value, (u64 *)buf); +		if (r) +			goto out; + +		result += 4; +		buf += 4; +		*pos += 4; +		size -= 4; +	} + +	r = result; +out: +	pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); +	pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + +	return r; +} + +/**   * amdgpu_debugfs_gfxoff_write - Enable/disable GFXOFF   *   * @f: open file handle @@ -1249,6 +1400,19 @@ static const struct file_operations amdgpu_debugfs_gfxoff_status_fops = {  	.llseek = default_llseek  }; +static const struct file_operations amdgpu_debugfs_gfxoff_count_fops = { +	.owner = THIS_MODULE, +	.read = amdgpu_debugfs_gfxoff_count_read, +	.llseek = default_llseek +}; + +static const struct file_operations amdgpu_debugfs_gfxoff_residency_fops = { +	.owner = THIS_MODULE, +	.read = amdgpu_debugfs_gfxoff_residency_read, +	.write = amdgpu_debugfs_gfxoff_residency_write, +	.llseek = default_llseek +}; +  static const struct file_operations *debugfs_regs[] = {  	&amdgpu_debugfs_regs_fops,  	&amdgpu_debugfs_regs2_fops, @@ -1261,6 +1425,8 @@ static const struct file_operations *debugfs_regs[] = {  	&amdgpu_debugfs_gpr_fops,  	&amdgpu_debugfs_gfxoff_fops,  	&amdgpu_debugfs_gfxoff_status_fops, +	&amdgpu_debugfs_gfxoff_count_fops, +	&amdgpu_debugfs_gfxoff_residency_fops,  };  static const char *debugfs_regs_names[] = { @@ -1275,6 +1441,8 @@ static const char *debugfs_regs_names[] = {  	"amdgpu_gpr",  	"amdgpu_gfxoff",  	"amdgpu_gfxoff_status", +	"amdgpu_gfxoff_count", +	"amdgpu_gfxoff_residency",  };  /** @@ -1786,6 +1954,8 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)  		return PTR_ERR(ent);  	} +	debugfs_create_u32("amdgpu_reset_level", 0600, root, &adev->amdgpu_reset_level_mask); +  	/* Register debugfs entries for amdgpu_ttm */  	amdgpu_ttm_debugfs_init(adev);  	amdgpu_debugfs_pm_init(adev);  |