|
@@ -2374,6 +2374,8 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
|
|
/* Set the chip into the appropriate suspend mode (we use D2,
|
|
/* Set the chip into the appropriate suspend mode (we use D2,
|
|
* D3 would require a complete re-initialisation of the chip,
|
|
* D3 would require a complete re-initialisation of the chip,
|
|
* including PCI config registers, clocks, AGP configuration, ...)
|
|
* including PCI config registers, clocks, AGP configuration, ...)
|
|
|
|
+ *
|
|
|
|
+ * For resume, the core will have already brought us back to D0
|
|
*/
|
|
*/
|
|
if (suspend) {
|
|
if (suspend) {
|
|
/* Make sure CRTC2 is reset. Remove that the day we decide to
|
|
/* Make sure CRTC2 is reset. Remove that the day we decide to
|
|
@@ -2391,17 +2393,9 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
|
|
aty_st_le32(BUS_CNTL1, 0x00000010);
|
|
aty_st_le32(BUS_CNTL1, 0x00000010);
|
|
aty_st_le32(MEM_POWER_MISC, 0x0c830000);
|
|
aty_st_le32(MEM_POWER_MISC, 0x0c830000);
|
|
mdelay(100);
|
|
mdelay(100);
|
|
- pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
|
|
|
|
|
|
+
|
|
/* Switch PCI power management to D2 */
|
|
/* Switch PCI power management to D2 */
|
|
- pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL,
|
|
|
|
- (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2);
|
|
|
|
- pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
|
|
|
|
- } else {
|
|
|
|
- /* Switch back PCI power management to D0 */
|
|
|
|
- mdelay(100);
|
|
|
|
- pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0);
|
|
|
|
- pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
|
|
|
|
- mdelay(100);
|
|
|
|
|
|
+ pci_set_power_state(pdev, PCI_D2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2410,6 +2404,12 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
|
struct fb_info *info = pci_get_drvdata(pdev);
|
|
struct fb_info *info = pci_get_drvdata(pdev);
|
|
struct aty128fb_par *par = info->par;
|
|
struct aty128fb_par *par = info->par;
|
|
|
|
|
|
|
|
+ /* Because we may change PCI D state ourselves, we need to
|
|
|
|
+ * first save the config space content so the core can
|
|
|
|
+ * restore it properly on resume.
|
|
|
|
+ */
|
|
|
|
+ pci_save_state(pdev);
|
|
|
|
+
|
|
/* We don't do anything but D2, for now we return 0, but
|
|
/* We don't do anything but D2, for now we return 0, but
|
|
* we may want to change that. How do we know if the BIOS
|
|
* we may want to change that. How do we know if the BIOS
|
|
* can properly take care of D3 ? Also, with swsusp, we
|
|
* can properly take care of D3 ? Also, with swsusp, we
|
|
@@ -2476,6 +2476,11 @@ static int aty128_do_resume(struct pci_dev *pdev)
|
|
if (pdev->dev.power.power_state.event == PM_EVENT_ON)
|
|
if (pdev->dev.power.power_state.event == PM_EVENT_ON)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
+ /* PCI state will have been restored by the core, so
|
|
|
|
+ * we should be in D0 now with our config space fully
|
|
|
|
+ * restored
|
|
|
|
+ */
|
|
|
|
+
|
|
/* Wakeup chip */
|
|
/* Wakeup chip */
|
|
aty128_set_suspend(par, 0);
|
|
aty128_set_suspend(par, 0);
|
|
par->asleep = 0;
|
|
par->asleep = 0;
|