diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 124 |
1 files changed, 89 insertions, 35 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 9e16e975f31a..f6394b5793c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -636,12 +636,10 @@ static bool amdgpu_vpost_needed(struct amdgpu_device *adev) return false; if (amdgpu_passthrough(adev)) { - /* for FIJI: In whole GPU pass-through virtualization case - * old smc fw won't clear some registers (e.g. MEM_SIZE, BIOS_SCRATCH) - * so amdgpu_card_posted return false and driver will incorrectly skip vPost. - * but if we force vPost do in pass-through case, the driver reload will hang. - * whether doing vPost depends on amdgpu_card_posted if smc version is above - * 00160e00 for FIJI. + /* for FIJI: In whole GPU pass-through virtualization case, after VM reboot + * some old smc fw still need driver do vPost otherwise gpu hang, while + * those smc fw version above 22.15 doesn't have this flaw, so we force + * vpost executed for smc version below 22.15 */ if (adev->asic_type == CHIP_FIJI) { int err; @@ -652,22 +650,11 @@ static bool amdgpu_vpost_needed(struct amdgpu_device *adev) return true; fw_ver = *((uint32_t *)adev->pm.fw->data + 69); - if (fw_ver >= 0x00160e00) - return !amdgpu_card_posted(adev); + if (fw_ver < 0x00160e00) + return true; } - } else { - /* in bare-metal case, amdgpu_card_posted return false - * after system reboot/boot, and return true if driver - * reloaded. - * we shouldn't do vPost after driver reload otherwise GPU - * could hang. - */ - if (amdgpu_card_posted(adev)) - return false; } - - /* we assume vPost is neede for all other cases */ - return true; + return !amdgpu_card_posted(adev); } /** @@ -1030,8 +1017,8 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev) amdgpu_vm_block_size = 9; } - if ((amdgpu_vram_page_split != -1 && amdgpu_vram_page_split < 16) || - !amdgpu_check_pot_argument(amdgpu_vram_page_split)) { + if (amdgpu_vram_page_split != -1 && (amdgpu_vram_page_split < 16 || + !amdgpu_check_pot_argument(amdgpu_vram_page_split))) { dev_warn(adev->dev, "invalid VRAM page split (%d)\n", amdgpu_vram_page_split); amdgpu_vram_page_split = 1024; @@ -1483,20 +1470,26 @@ static int amdgpu_fini(struct amdgpu_device *adev) amdgpu_wb_fini(adev); amdgpu_vram_scratch_fini(adev); } - /* ungate blocks before hw fini so that we can shutdown the blocks safely */ - r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, - AMD_CG_STATE_UNGATE); - if (r) { - DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n", - adev->ip_blocks[i].version->funcs->name, r); - return r; + + if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && + adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE) { + /* ungate blocks before hw fini so that we can shutdown the blocks safely */ + r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, + AMD_CG_STATE_UNGATE); + if (r) { + DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n", + adev->ip_blocks[i].version->funcs->name, r); + return r; + } } + r = adev->ip_blocks[i].version->funcs->hw_fini((void *)adev); /* XXX handle errors */ if (r) { DRM_DEBUG("hw_fini of IP block <%s> failed %d\n", adev->ip_blocks[i].version->funcs->name, r); } + adev->ip_blocks[i].status.hw = false; } @@ -2506,9 +2499,6 @@ int amdgpu_debugfs_add_files(struct amdgpu_device *adev, adev->debugfs_count = i; #if defined(CONFIG_DEBUG_FS) drm_debugfs_create_files(files, nfiles, - adev->ddev->control->debugfs_root, - adev->ddev->control); - drm_debugfs_create_files(files, nfiles, adev->ddev->primary->debugfs_root, adev->ddev->primary); #endif @@ -2523,9 +2513,6 @@ static void amdgpu_debugfs_remove_files(struct amdgpu_device *adev) for (i = 0; i < adev->debugfs_count; i++) { drm_debugfs_remove_files(adev->debugfs[i].files, adev->debugfs[i].num_files, - adev->ddev->control); - drm_debugfs_remove_files(adev->debugfs[i].files, - adev->debugfs[i].num_files, adev->ddev->primary); } #endif @@ -2992,6 +2979,66 @@ static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf, return result; } +static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, + size_t size, loff_t *pos) +{ + struct amdgpu_device *adev = f->f_inode->i_private; + int r; + ssize_t result = 0; + uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data; + + if (size & 3 || *pos & 3) + return -EINVAL; + + /* decode offset */ + offset = (*pos & 0xFFF); /* in dwords */ + se = ((*pos >> 12) & 0xFF); + sh = ((*pos >> 20) & 0xFF); + cu = ((*pos >> 28) & 0xFF); + wave = ((*pos >> 36) & 0xFF); + simd = ((*pos >> 44) & 0xFF); + thread = ((*pos >> 52) & 0xFF); + bank = ((*pos >> 60) & 1); + + data = kmalloc_array(1024, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* switch to the specific se/sh/cu */ + mutex_lock(&adev->grbm_idx_mutex); + amdgpu_gfx_select_se_sh(adev, se, sh, cu); + + if (bank == 0) { + if (adev->gfx.funcs->read_wave_vgprs) + adev->gfx.funcs->read_wave_vgprs(adev, simd, wave, thread, offset, size>>2, data); + } else { + if (adev->gfx.funcs->read_wave_sgprs) + adev->gfx.funcs->read_wave_sgprs(adev, simd, wave, offset, size>>2, data); + } + + amdgpu_gfx_select_se_sh(adev, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); + mutex_unlock(&adev->grbm_idx_mutex); + + while (size) { + uint32_t value; + + value = data[offset++]; + r = put_user(value, (uint32_t *)buf); + if (r) { + result = r; + goto err; + } + + result += 4; + buf += 4; + size -= 4; + } + +err: + kfree(data); + return result; +} + static const struct file_operations amdgpu_debugfs_regs_fops = { .owner = THIS_MODULE, .read = amdgpu_debugfs_regs_read, @@ -3034,6 +3081,11 @@ static const struct file_operations amdgpu_debugfs_wave_fops = { .read = amdgpu_debugfs_wave_read, .llseek = default_llseek }; +static const struct file_operations amdgpu_debugfs_gpr_fops = { + .owner = THIS_MODULE, + .read = amdgpu_debugfs_gpr_read, + .llseek = default_llseek +}; static const struct file_operations *debugfs_regs[] = { &amdgpu_debugfs_regs_fops, @@ -3043,6 +3095,7 @@ static const struct file_operations *debugfs_regs[] = { &amdgpu_debugfs_gca_config_fops, &amdgpu_debugfs_sensors_fops, &amdgpu_debugfs_wave_fops, + &amdgpu_debugfs_gpr_fops, }; static const char *debugfs_regs_names[] = { @@ -3053,6 +3106,7 @@ static const char *debugfs_regs_names[] = { "amdgpu_gca_config", "amdgpu_sensors", "amdgpu_wave", + "amdgpu_gpr", }; static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) |