diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 53539ceeda16..019581577603 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -609,6 +609,13 @@ void amdgpu_device_detect_runtime_pm_mode(struct amdgpu_device *adev) int bamaco_support; adev->pm.rpm_mode = AMDGPU_RUNPM_NONE; + if (pci_is_thunderbolt_attached(adev->pdev) || + dev_is_removable(&adev->pdev->dev)) { + dev_info(adev->dev, + "Runtime PM disabled for externally attached device\n"); + return; + } + bamaco_support = amdgpu_device_supports_baco(adev); switch (amdgpu_runtime_pm) { @@ -2523,7 +2530,11 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) if (r) goto init_failed; - amdgpu_ttm_enable_buffer_funcs(adev); + /* If SDMA is not brought up during hwini, the ttm buffer funcs enablement + * is delayed after reset-on-init completes. + */ + if (amdgpu_ip_member_of_hwini(adev, AMD_IP_BLOCK_TYPE_SDMA)) + amdgpu_ttm_enable_buffer_funcs(adev); /* Don't init kfd if whole hive need to be reset during init */ if (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) { @@ -3733,6 +3744,14 @@ static void amdgpu_device_sys_interface_fini(struct amdgpu_device *adev) amdgpu_ptl_sysfs_fini(adev); } +static bool +amdgpu_device_should_register_switcheroo(struct amdgpu_device *adev, bool px) +{ + return !pci_is_thunderbolt_attached(adev->pdev) && + (px || (!dev_is_removable(&adev->pdev->dev) && + apple_gmux_detect(NULL, NULL))); +} + /** * amdgpu_device_init - initialize the driver * @@ -4183,8 +4202,7 @@ fence_driver_init: px = amdgpu_device_supports_px(adev); - if (px || (!dev_is_removable(&adev->pdev->dev) && - apple_gmux_detect(NULL, NULL))) + if (amdgpu_device_should_register_switcheroo(adev, px)) vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, px); @@ -4349,8 +4367,7 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev) px = amdgpu_device_supports_px(adev); - if (px || (!dev_is_removable(&adev->pdev->dev) && - apple_gmux_detect(NULL, NULL))) + if (amdgpu_device_should_register_switcheroo(adev, px)) vga_switcheroo_unregister_client(adev->pdev); if (px) @@ -5037,6 +5054,31 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, amdgpu_fence_driver_force_completion(ring, fence); } + /* + * MES scheduler rings have no drm scheduler, so they are missed by the + * loop above. Realign their polling fence too (one per XCC), otherwise the + * first post-reset submission polls forever on a stale seq. sched.ready is + * only set while the driver owns the ring. + */ + for (i = 0; i < AMDGPU_MAX_MES_INST_PIPES; i++) { + struct amdgpu_ring *mes_ring = &adev->mes.ring[i]; + + if (mes_ring->fence_drv.initialized && mes_ring->sched.ready) + amdgpu_fence_driver_force_completion(mes_ring, fence); + } + + /* + * KIQ rings are polling-fence/no_scheduler like MES, so realign their + * fence too (one ring per XCC), otherwise the first post-reset KIQ + * submission polls forever on a stale seq. + */ + for (i = 0; i < AMDGPU_MAX_GC_INSTANCES; i++) { + struct amdgpu_ring *kiq_ring = &adev->gfx.kiq[i].ring; + + if (kiq_ring->fence_drv.initialized && kiq_ring->sched.ready) + amdgpu_fence_driver_force_completion(kiq_ring, fence); + } + amdgpu_fence_driver_isr_toggle(adev, false); r = amdgpu_reset_prepare_hwcontext(adev, reset_context); @@ -5137,8 +5179,6 @@ int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context) if (r) goto out; - amdgpu_ttm_enable_buffer_funcs(tmp_adev); - r = amdgpu_device_ip_resume_phase3(tmp_adev); if (r) goto out; |
