diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 195 | 
1 files changed, 190 insertions, 5 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index 448d69fe3756..f5fb93795a69 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | |||
| @@ -28,8 +28,13 @@ | |||
| 28 | #include <linux/debugfs.h> | 28 | #include <linux/debugfs.h> | 
| 29 | #include "amdgpu.h" | 29 | #include "amdgpu.h" | 
| 30 | 30 | ||
| 31 | /* | 31 | /** | 
| 32 | * Debugfs | 32 | * amdgpu_debugfs_add_files - Add simple debugfs entries | 
| 33 | * | ||
| 34 | * @adev: Device to attach debugfs entries to | ||
| 35 | * @files: Array of function callbacks that respond to reads | ||
| 36 | * @nfiles: Number of callbacks to register | ||
| 37 | * | ||
| 33 | */ | 38 | */ | 
| 34 | int amdgpu_debugfs_add_files(struct amdgpu_device *adev, | 39 | int amdgpu_debugfs_add_files(struct amdgpu_device *adev, | 
| 35 | const struct drm_info_list *files, | 40 | const struct drm_info_list *files, | 
| @@ -64,7 +69,33 @@ int amdgpu_debugfs_add_files(struct amdgpu_device *adev, | |||
| 64 | 69 | ||
| 65 | #if defined(CONFIG_DEBUG_FS) | 70 | #if defined(CONFIG_DEBUG_FS) | 
| 66 | 71 | ||
| 67 | 72 | /** | |
| 73 | * amdgpu_debugfs_process_reg_op - Handle MMIO register reads/writes | ||
| 74 | * | ||
| 75 | * @read: True if reading | ||
| 76 | * @f: open file handle | ||
| 77 | * @buf: User buffer to write/read to | ||
| 78 | * @size: Number of bytes to write/read | ||
| 79 | * @pos: Offset to seek to | ||
| 80 | * | ||
| 81 | * This debugfs entry has special meaning on the offset being sought. | ||
| 82 | * Various bits have different meanings: | ||
| 83 | * | ||
| 84 | * Bit 62: Indicates a GRBM bank switch is needed | ||
| 85 | * Bit 61: Indicates a SRBM bank switch is needed (implies bit 62 is | ||
| 86 | * zero) | ||
| 87 | * Bits 24..33: The SE or ME selector if needed | ||
| 88 | * Bits 34..43: The SH (or SA) or PIPE selector if needed | ||
| 89 | * Bits 44..53: The INSTANCE (or CU/WGP) or QUEUE selector if needed | ||
| 90 | * | ||
| 91 | * Bit 23: Indicates that the PM power gating lock should be held | ||
| 92 | * This is necessary to read registers that might be | ||
| 93 | * unreliable during a power gating transistion. | ||
| 94 | * | ||
| 95 | * The lower bits are the BYTE offset of the register to read. This | ||
| 96 | * allows reading multiple registers in a single call and having | ||
| 97 | * the returned size reflect that. | ||
| 98 | */ | ||
| 68 | static int amdgpu_debugfs_process_reg_op(bool read, struct file *f, | 99 | static int amdgpu_debugfs_process_reg_op(bool read, struct file *f, | 
| 69 | char __user *buf, size_t size, loff_t *pos) | 100 | char __user *buf, size_t size, loff_t *pos) | 
| 70 | { | 101 | { | 
| @@ -164,19 +195,37 @@ end: | |||
| 164 | return result; | 195 | return result; | 
| 165 | } | 196 | } | 
| 166 | 197 | ||
| 167 | 198 | /** | |
| 199 | * amdgpu_debugfs_regs_read - Callback for reading MMIO registers | ||
| 200 | */ | ||
| 168 | static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, | 201 | static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, | 
| 169 | size_t size, loff_t *pos) | 202 | size_t size, loff_t *pos) | 
| 170 | { | 203 | { | 
| 171 | return amdgpu_debugfs_process_reg_op(true, f, buf, size, pos); | 204 | return amdgpu_debugfs_process_reg_op(true, f, buf, size, pos); | 
| 172 | } | 205 | } | 
| 173 | 206 | ||
| 207 | /** | ||
| 208 | * amdgpu_debugfs_regs_write - Callback for writing MMIO registers | ||
| 209 | */ | ||
| 174 | static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf, | 210 | static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf, | 
| 175 | size_t size, loff_t *pos) | 211 | size_t size, loff_t *pos) | 
| 176 | { | 212 | { | 
| 177 | return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos); | 213 | return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos); | 
| 178 | } | 214 | } | 
| 179 | 215 | ||
| 216 | |||
| 217 | /** | ||
| 218 | * amdgpu_debugfs_regs_pcie_read - Read from a PCIE register | ||
| 219 | * | ||
| 220 | * @f: open file handle | ||
| 221 | * @buf: User buffer to store read data in | ||
| 222 | * @size: Number of bytes to read | ||
| 223 | * @pos: Offset to seek to | ||
| 224 | * | ||
| 225 | * The lower bits are the BYTE offset of the register to read. This | ||
| 226 | * allows reading multiple registers in a single call and having | ||
| 227 | * the returned size reflect that. | ||
| 228 | */ | ||
| 180 | static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf, | 229 | static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf, | 
| 181 | size_t size, loff_t *pos) | 230 | size_t size, loff_t *pos) | 
| 182 | { | 231 | { | 
| @@ -204,6 +253,18 @@ static ssize_t amdgpu_debugfs_regs_pcie_read(struct file *f, char __user *buf, | |||
| 204 | return result; | 253 | return result; | 
| 205 | } | 254 | } | 
| 206 | 255 | ||
| 256 | /** | ||
| 257 | * amdgpu_debugfs_regs_pcie_write - Write to a PCIE register | ||
| 258 | * | ||
| 259 | * @f: open file handle | ||
| 260 | * @buf: User buffer to write data from | ||
| 261 | * @size: Number of bytes to write | ||
| 262 | * @pos: Offset to seek to | ||
| 263 | * | ||
| 264 | * The lower bits are the BYTE offset of the register to write. This | ||
| 265 | * allows writing multiple registers in a single call and having | ||
| 266 | * the returned size reflect that. | ||
| 267 | */ | ||
| 207 | static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user *buf, | 268 | static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user *buf, | 
| 208 | size_t size, loff_t *pos) | 269 | size_t size, loff_t *pos) | 
| 209 | { | 270 | { | 
| @@ -232,6 +293,18 @@ static ssize_t amdgpu_debugfs_regs_pcie_write(struct file *f, const char __user | |||
| 232 | return result; | 293 | return result; | 
| 233 | } | 294 | } | 
| 234 | 295 | ||
| 296 | /** | ||
| 297 | * amdgpu_debugfs_regs_didt_read - Read from a DIDT register | ||
| 298 | * | ||
| 299 | * @f: open file handle | ||
| 300 | * @buf: User buffer to store read data in | ||
| 301 | * @size: Number of bytes to read | ||
| 302 | * @pos: Offset to seek to | ||
| 303 | * | ||
| 304 | * The lower bits are the BYTE offset of the register to read. This | ||
| 305 | * allows reading multiple registers in a single call and having | ||
| 306 | * the returned size reflect that. | ||
| 307 | */ | ||
| 235 | static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf, | 308 | static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf, | 
| 236 | size_t size, loff_t *pos) | 309 | size_t size, loff_t *pos) | 
| 237 | { | 310 | { | 
| @@ -259,6 +332,18 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf, | |||
| 259 | return result; | 332 | return result; | 
| 260 | } | 333 | } | 
| 261 | 334 | ||
| 335 | /** | ||
| 336 | * amdgpu_debugfs_regs_didt_write - Write to a DIDT register | ||
| 337 | * | ||
| 338 | * @f: open file handle | ||
| 339 | * @buf: User buffer to write data from | ||
| 340 | * @size: Number of bytes to write | ||
| 341 | * @pos: Offset to seek to | ||
| 342 | * | ||
| 343 | * The lower bits are the BYTE offset of the register to write. This | ||
| 344 | * allows writing multiple registers in a single call and having | ||
| 345 | * the returned size reflect that. | ||
| 346 | */ | ||
| 262 | static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user *buf, | 347 | static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user *buf, | 
| 263 | size_t size, loff_t *pos) | 348 | size_t size, loff_t *pos) | 
| 264 | { | 349 | { | 
| @@ -287,6 +372,18 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user | |||
| 287 | return result; | 372 | return result; | 
| 288 | } | 373 | } | 
| 289 | 374 | ||
| 375 | /** | ||
| 376 | * amdgpu_debugfs_regs_smc_read - Read from a SMC register | ||
| 377 | * | ||
| 378 | * @f: open file handle | ||
| 379 | * @buf: User buffer to store read data in | ||
| 380 | * @size: Number of bytes to read | ||
| 381 | * @pos: Offset to seek to | ||
| 382 | * | ||
| 383 | * The lower bits are the BYTE offset of the register to read. This | ||
| 384 | * allows reading multiple registers in a single call and having | ||
| 385 | * the returned size reflect that. | ||
| 386 | */ | ||
| 290 | static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, | 387 | static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, | 
| 291 | size_t size, loff_t *pos) | 388 | size_t size, loff_t *pos) | 
| 292 | { | 389 | { | 
| @@ -314,6 +411,18 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf, | |||
| 314 | return result; | 411 | return result; | 
| 315 | } | 412 | } | 
| 316 | 413 | ||
| 414 | /** | ||
| 415 | * amdgpu_debugfs_regs_smc_write - Write to a SMC register | ||
| 416 | * | ||
| 417 | * @f: open file handle | ||
| 418 | * @buf: User buffer to write data from | ||
| 419 | * @size: Number of bytes to write | ||
| 420 | * @pos: Offset to seek to | ||
| 421 | * | ||
| 422 | * The lower bits are the BYTE offset of the register to write. This | ||
| 423 | * allows writing multiple registers in a single call and having | ||
| 424 | * the returned size reflect that. | ||
| 425 | */ | ||
| 317 | static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *buf, | 426 | static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *buf, | 
| 318 | size_t size, loff_t *pos) | 427 | size_t size, loff_t *pos) | 
| 319 | { | 428 | { | 
| @@ -342,6 +451,20 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user * | |||
| 342 | return result; | 451 | return result; | 
| 343 | } | 452 | } | 
| 344 | 453 | ||
| 454 | /** | ||
| 455 | * amdgpu_debugfs_gca_config_read - Read from gfx config data | ||
| 456 | * | ||
| 457 | * @f: open file handle | ||
| 458 | * @buf: User buffer to store read data in | ||
| 459 | * @size: Number of bytes to read | ||
| 460 | * @pos: Offset to seek to | ||
| 461 | * | ||
| 462 | * This file is used to access configuration data in a somewhat | ||
| 463 | * stable fashion. The format is a series of DWORDs with the first | ||
| 464 | * indicating which revision it is. New content is appended to the | ||
| 465 | * end so that older software can still read the data. | ||
| 466 | */ | ||
| 467 | |||
| 345 | static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, | 468 | static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, | 
| 346 | size_t size, loff_t *pos) | 469 | size_t size, loff_t *pos) | 
| 347 | { | 470 | { | 
| @@ -418,6 +541,19 @@ static ssize_t amdgpu_debugfs_gca_config_read(struct file *f, char __user *buf, | |||
| 418 | return result; | 541 | return result; | 
| 419 | } | 542 | } | 
| 420 | 543 | ||
| 544 | /** | ||
| 545 | * amdgpu_debugfs_sensor_read - Read from the powerplay sensors | ||
| 546 | * | ||
| 547 | * @f: open file handle | ||
| 548 | * @buf: User buffer to store read data in | ||
| 549 | * @size: Number of bytes to read | ||
| 550 | * @pos: Offset to seek to | ||
| 551 | * | ||
| 552 | * The offset is treated as the BYTE address of one of the sensors | ||
| 553 | * enumerated in amd/include/kgd_pp_interface.h under the | ||
| 554 | * 'amd_pp_sensors' enumeration. For instance to read the UVD VCLK | ||
| 555 | * you would use the offset 3 * 4 = 12. | ||
| 556 | */ | ||
| 421 | static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf, | 557 | static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf, | 
| 422 | size_t size, loff_t *pos) | 558 | size_t size, loff_t *pos) | 
| 423 | { | 559 | { | 
| @@ -428,7 +564,7 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf, | |||
| 428 | if (size & 3 || *pos & 0x3) | 564 | if (size & 3 || *pos & 0x3) | 
| 429 | return -EINVAL; | 565 | return -EINVAL; | 
| 430 | 566 | ||
| 431 | if (amdgpu_dpm == 0) | 567 | if (!adev->pm.dpm_enabled) | 
| 432 | return -EINVAL; | 568 | return -EINVAL; | 
| 433 | 569 | ||
| 434 | /* convert offset to sensor number */ | 570 | /* convert offset to sensor number */ | 
| @@ -457,6 +593,27 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf, | |||
| 457 | return !r ? outsize : r; | 593 | return !r ? outsize : r; | 
| 458 | } | 594 | } | 
| 459 | 595 | ||
| 596 | /** amdgpu_debugfs_wave_read - Read WAVE STATUS data | ||
| 597 | * | ||
| 598 | * @f: open file handle | ||
| 599 | * @buf: User buffer to store read data in | ||
| 600 | * @size: Number of bytes to read | ||
| 601 | * @pos: Offset to seek to | ||
| 602 | * | ||
| 603 | * The offset being sought changes which wave that the status data | ||
| 604 | * will be returned for. The bits are used as follows: | ||
| 605 | * | ||
| 606 | * Bits 0..6: Byte offset into data | ||
| 607 | * Bits 7..14: SE selector | ||
| 608 | * Bits 15..22: SH/SA selector | ||
| 609 | * Bits 23..30: CU/{WGP+SIMD} selector | ||
| 610 | * Bits 31..36: WAVE ID selector | ||
| 611 | * Bits 37..44: SIMD ID selector | ||
| 612 | * | ||
| 613 | * The returned data begins with one DWORD of version information | ||
| 614 | * Followed by WAVE STATUS registers relevant to the GFX IP version | ||
| 615 | * being used. See gfx_v8_0_read_wave_data() for an example output. | ||
| 616 | */ | ||
| 460 | static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf, | 617 | static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf, | 
| 461 | size_t size, loff_t *pos) | 618 | size_t size, loff_t *pos) | 
| 462 | { | 619 | { | 
| @@ -507,6 +664,28 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf, | |||
| 507 | return result; | 664 | return result; | 
| 508 | } | 665 | } | 
| 509 | 666 | ||
| 667 | /** amdgpu_debugfs_gpr_read - Read wave gprs | ||
| 668 | * | ||
| 669 | * @f: open file handle | ||
| 670 | * @buf: User buffer to store read data in | ||
| 671 | * @size: Number of bytes to read | ||
| 672 | * @pos: Offset to seek to | ||
| 673 | * | ||
| 674 | * The offset being sought changes which wave that the status data | ||
| 675 | * will be returned for. The bits are used as follows: | ||
| 676 | * | ||
| 677 | * Bits 0..11: Byte offset into data | ||
| 678 | * Bits 12..19: SE selector | ||
| 679 | * Bits 20..27: SH/SA selector | ||
| 680 | * Bits 28..35: CU/{WGP+SIMD} selector | ||
| 681 | * Bits 36..43: WAVE ID selector | ||
| 682 | * Bits 37..44: SIMD ID selector | ||
| 683 | * Bits 52..59: Thread selector | ||
| 684 | * Bits 60..61: Bank selector (VGPR=0,SGPR=1) | ||
| 685 | * | ||
| 686 | * The return data comes from the SGPR or VGPR register bank for | ||
| 687 | * the selected operational unit. | ||
| 688 | */ | ||
| 510 | static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, | 689 | static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, | 
| 511 | size_t size, loff_t *pos) | 690 | size_t size, loff_t *pos) | 
| 512 | { | 691 | { | 
| @@ -637,6 +816,12 @@ static const char *debugfs_regs_names[] = { | |||
| 637 | "amdgpu_gpr", | 816 | "amdgpu_gpr", | 
| 638 | }; | 817 | }; | 
| 639 | 818 | ||
| 819 | /** | ||
| 820 | * amdgpu_debugfs_regs_init - Initialize debugfs entries that provide | ||
| 821 | * register access. | ||
| 822 | * | ||
| 823 | * @adev: The device to attach the debugfs entries to | ||
| 824 | */ | ||
| 640 | int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) | 825 | int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) | 
| 641 | { | 826 | { | 
| 642 | struct drm_minor *minor = adev->ddev->primary; | 827 | struct drm_minor *minor = adev->ddev->primary; | 
