Skip to content

Commit

Permalink
drm/radeon: hard reset r600 and newer GPU when hibernating.
Browse files Browse the repository at this point in the history
Some GPU block like UVD and VCE require hard reset to be properly
resume if there is no real powerdown of the asic like during various
hibernation step. This patch perform such hard reset.

Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Jérôme Glisse <jglisse@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  • Loading branch information
Jérome Glisse authored and Alex Deucher committed May 2, 2016
1 parent 71fe289 commit 274ad65
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 8 deletions.
3 changes: 2 additions & 1 deletion drivers/gpu/drm/radeon/radeon.h
Original file line number Diff line number Diff line change
Expand Up @@ -2835,7 +2835,8 @@ extern bool radeon_ttm_tt_is_readonly(struct ttm_tt *ttm);
extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base);
extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
extern int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon);
extern int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon);
extern int radeon_suspend_kms(struct drm_device *dev, bool suspend,
bool fbcon, bool freeze);
extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size);
extern void radeon_program_register_sequence(struct radeon_device *rdev,
const u32 *registers,
Expand Down
10 changes: 7 additions & 3 deletions drivers/gpu/drm/radeon/radeon_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,7 +1236,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
printk(KERN_INFO "radeon: switched off\n");
drm_kms_helper_poll_disable(dev);
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
radeon_suspend_kms(dev, true, true);
radeon_suspend_kms(dev, true, true, false);
dev->switch_power_state = DRM_SWITCH_POWER_OFF;
}
}
Expand Down Expand Up @@ -1561,7 +1561,8 @@ void radeon_device_fini(struct radeon_device *rdev)
* Returns 0 for success or an error on failure.
* Called at driver suspend.
*/
int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
int radeon_suspend_kms(struct drm_device *dev, bool suspend,
bool fbcon, bool freeze)
{
struct radeon_device *rdev;
struct drm_crtc *crtc;
Expand Down Expand Up @@ -1636,7 +1637,10 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
radeon_agp_suspend(rdev);

pci_save_state(dev->pdev);
if (suspend) {
if (freeze && rdev->family >= CHIP_R600) {
rdev->asic->asic_reset(rdev, true);
pci_restore_state(dev->pdev);
} else if (suspend) {
/* Shut down the device */
pci_disable_device(dev->pdev);
pci_set_power_state(dev->pdev, PCI_D3hot);
Expand Down
9 changes: 5 additions & 4 deletions drivers/gpu/drm/radeon/radeon_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
struct drm_file *file_priv);
void radeon_driver_preclose_kms(struct drm_device *dev,
struct drm_file *file_priv);
int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon);
int radeon_suspend_kms(struct drm_device *dev, bool suspend,
bool fbcon, bool freeze);
int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon);
u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe);
int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe);
Expand Down Expand Up @@ -366,7 +367,7 @@ static int radeon_pmops_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
return radeon_suspend_kms(drm_dev, true, true);
return radeon_suspend_kms(drm_dev, true, true, false);
}

static int radeon_pmops_resume(struct device *dev)
Expand All @@ -380,7 +381,7 @@ static int radeon_pmops_freeze(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
return radeon_suspend_kms(drm_dev, false, true);
return radeon_suspend_kms(drm_dev, false, true, true);
}

static int radeon_pmops_thaw(struct device *dev)
Expand All @@ -405,7 +406,7 @@ static int radeon_pmops_runtime_suspend(struct device *dev)
drm_kms_helper_poll_disable(drm_dev);
vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);

ret = radeon_suspend_kms(drm_dev, false, false);
ret = radeon_suspend_kms(drm_dev, false, false, false);
pci_save_state(pdev);
pci_disable_device(pdev);
pci_ignore_hotplug(pdev);
Expand Down

0 comments on commit 274ad65

Please sign in to comment.