Commit 274ad65c authored by Jérome Glisse's avatar Jérome Glisse Committed by Alex Deucher

drm/radeon: hard reset r600 and newer GPU when hibernating.

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: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarJérôme Glisse <jglisse@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 71fe2899
...@@ -2835,7 +2835,8 @@ extern bool radeon_ttm_tt_is_readonly(struct ttm_tt *ttm); ...@@ -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_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 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_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_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size);
extern void radeon_program_register_sequence(struct radeon_device *rdev, extern void radeon_program_register_sequence(struct radeon_device *rdev,
const u32 *registers, const u32 *registers,
......
...@@ -1236,7 +1236,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero ...@@ -1236,7 +1236,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
printk(KERN_INFO "radeon: switched off\n"); printk(KERN_INFO "radeon: switched off\n");
drm_kms_helper_poll_disable(dev); drm_kms_helper_poll_disable(dev);
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 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; dev->switch_power_state = DRM_SWITCH_POWER_OFF;
} }
} }
...@@ -1561,7 +1561,8 @@ void radeon_device_fini(struct radeon_device *rdev) ...@@ -1561,7 +1561,8 @@ void radeon_device_fini(struct radeon_device *rdev)
* Returns 0 for success or an error on failure. * Returns 0 for success or an error on failure.
* Called at driver suspend. * 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 radeon_device *rdev;
struct drm_crtc *crtc; struct drm_crtc *crtc;
...@@ -1636,7 +1637,10 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon) ...@@ -1636,7 +1637,10 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
radeon_agp_suspend(rdev); radeon_agp_suspend(rdev);
pci_save_state(dev->pdev); 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 */ /* Shut down the device */
pci_disable_device(dev->pdev); pci_disable_device(dev->pdev);
pci_set_power_state(dev->pdev, PCI_D3hot); pci_set_power_state(dev->pdev, PCI_D3hot);
......
...@@ -105,7 +105,8 @@ void radeon_driver_postclose_kms(struct drm_device *dev, ...@@ -105,7 +105,8 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
struct drm_file *file_priv); struct drm_file *file_priv);
void radeon_driver_preclose_kms(struct drm_device *dev, void radeon_driver_preclose_kms(struct drm_device *dev,
struct drm_file *file_priv); 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); 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); 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); int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe);
...@@ -366,7 +367,7 @@ static int radeon_pmops_suspend(struct device *dev) ...@@ -366,7 +367,7 @@ static int radeon_pmops_suspend(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev); 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) static int radeon_pmops_resume(struct device *dev)
...@@ -380,7 +381,7 @@ static int radeon_pmops_freeze(struct device *dev) ...@@ -380,7 +381,7 @@ static int radeon_pmops_freeze(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev); 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) static int radeon_pmops_thaw(struct device *dev)
...@@ -405,7 +406,7 @@ static int radeon_pmops_runtime_suspend(struct device *dev) ...@@ -405,7 +406,7 @@ static int radeon_pmops_runtime_suspend(struct device *dev)
drm_kms_helper_poll_disable(drm_dev); drm_kms_helper_poll_disable(drm_dev);
vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); 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_save_state(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
pci_ignore_hotplug(pdev); pci_ignore_hotplug(pdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment