Loading drivers/gpu/drm/nouveau/nouveau_drm.c +127 −121 Original line number Diff line number Diff line Loading @@ -613,27 +613,6 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime) return ret; } int nouveau_pmops_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF || drm_dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF) return 0; ret = nouveau_do_suspend(drm_dev, false); if (ret) return ret; pci_save_state(pdev); pci_disable_device(pdev); pci_ignore_hotplug(pdev); pci_set_power_state(pdev, PCI_D3hot); return 0; } static int nouveau_do_resume(struct drm_device *dev, bool runtime) { Loading Loading @@ -668,7 +647,30 @@ nouveau_do_resume(struct drm_device *dev, bool runtime) return 0; } int nouveau_pmops_resume(struct device *dev) int nouveau_pmops_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF || drm_dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF) return 0; ret = nouveau_do_suspend(drm_dev, false); if (ret) return ret; pci_save_state(pdev); pci_disable_device(pdev); pci_ignore_hotplug(pdev); pci_set_power_state(pdev, PCI_D3hot); return 0; } int nouveau_pmops_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); Loading @@ -688,20 +690,121 @@ int nouveau_pmops_resume(struct device *dev) return nouveau_do_resume(drm_dev, false); } static int nouveau_pmops_freeze(struct device *dev) static int nouveau_pmops_freeze(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); return nouveau_do_suspend(drm_dev, false); } static int nouveau_pmops_thaw(struct device *dev) static int nouveau_pmops_thaw(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); return nouveau_do_resume(drm_dev, false); } static int nouveau_pmops_runtime_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; if (nouveau_runtime_pm == 0) { pm_runtime_forbid(dev); return -EBUSY; } /* are we optimus enabled? */ if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); pm_runtime_forbid(dev); return -EBUSY; } nv_debug_level(SILENT); drm_kms_helper_poll_disable(drm_dev); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); nouveau_switcheroo_optimus_dsm(); ret = nouveau_do_suspend(drm_dev, true); pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3cold); drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; return ret; } static int nouveau_pmops_runtime_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); struct nvif_device *device = &nouveau_drm(drm_dev)->device; int ret; if (nouveau_runtime_pm == 0) return -EINVAL; pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); ret = pci_enable_device(pdev); if (ret) return ret; pci_set_master(pdev); ret = nouveau_do_resume(drm_dev, true); drm_kms_helper_poll_enable(drm_dev); /* do magic */ nvif_mask(device, 0x88488, (1 << 25), (1 << 25)); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON); drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; nv_debug_level(NORMAL); return ret; } static int nouveau_pmops_runtime_idle(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); struct nouveau_drm *drm = nouveau_drm(drm_dev); struct drm_crtc *crtc; if (nouveau_runtime_pm == 0) { pm_runtime_forbid(dev); return -EBUSY; } /* are we optimus enabled? */ if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); pm_runtime_forbid(dev); return -EBUSY; } /* if we have a hdmi audio device - make sure it has a driver loaded */ if (drm->hdmi_device) { if (!drm->hdmi_device->driver) { DRM_DEBUG_DRIVER("failing to power off - no HDMI audio driver loaded\n"); pm_runtime_mark_last_busy(dev); return -EBUSY; } } list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) { if (crtc->enabled) { DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); return -EBUSY; } } pm_runtime_mark_last_busy(dev); pm_runtime_autosuspend(dev); /* we don't want the main rpm_idle to call suspend - we want to autosuspend */ return 1; } static int nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) Loading Loading @@ -908,103 +1011,6 @@ nouveau_drm_pci_table[] = { {} }; static int nouveau_pmops_runtime_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; if (nouveau_runtime_pm == 0) { pm_runtime_forbid(dev); return -EBUSY; } /* are we optimus enabled? */ if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); pm_runtime_forbid(dev); return -EBUSY; } nv_debug_level(SILENT); drm_kms_helper_poll_disable(drm_dev); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); nouveau_switcheroo_optimus_dsm(); ret = nouveau_do_suspend(drm_dev, true); pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3cold); drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; return ret; } static int nouveau_pmops_runtime_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); struct nvif_device *device = &nouveau_drm(drm_dev)->device; int ret; if (nouveau_runtime_pm == 0) return -EINVAL; pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); ret = pci_enable_device(pdev); if (ret) return ret; pci_set_master(pdev); ret = nouveau_do_resume(drm_dev, true); drm_kms_helper_poll_enable(drm_dev); /* do magic */ nvif_mask(device, 0x88488, (1 << 25), (1 << 25)); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON); drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; nv_debug_level(NORMAL); return ret; } static int nouveau_pmops_runtime_idle(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); struct nouveau_drm *drm = nouveau_drm(drm_dev); struct drm_crtc *crtc; if (nouveau_runtime_pm == 0) { pm_runtime_forbid(dev); return -EBUSY; } /* are we optimus enabled? */ if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); pm_runtime_forbid(dev); return -EBUSY; } /* if we have a hdmi audio device - make sure it has a driver loaded */ if (drm->hdmi_device) { if (!drm->hdmi_device->driver) { DRM_DEBUG_DRIVER("failing to power off - no HDMI audio driver loaded\n"); pm_runtime_mark_last_busy(dev); return -EBUSY; } } list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) { if (crtc->enabled) { DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); return -EBUSY; } } pm_runtime_mark_last_busy(dev); pm_runtime_autosuspend(dev); /* we don't want the main rpm_idle to call suspend - we want to autosuspend */ return 1; } static void nouveau_display_options(void) { DRM_DEBUG_DRIVER("Loading Nouveau with parameters:\n"); Loading drivers/gpu/drm/nouveau/nouveau_fbcon.c +17 −17 Original line number Diff line number Diff line Loading @@ -498,6 +498,23 @@ nouveau_fbcon_set_suspend_work(struct work_struct *work) console_unlock(); } void nouveau_fbcon_set_suspend(struct drm_device *dev, int state) { struct nouveau_drm *drm = nouveau_drm(dev); if (drm->fbcon) { if (state == FBINFO_STATE_RUNNING) { schedule_work(&drm->fbcon->work); return; } flush_work(&drm->fbcon->work); console_lock(); fb_set_suspend(drm->fbcon->helper.fbdev, state); nouveau_fbcon_accel_save_disable(dev); console_unlock(); } } int nouveau_fbcon_init(struct drm_device *dev) { Loading Loading @@ -557,20 +574,3 @@ nouveau_fbcon_fini(struct drm_device *dev) kfree(drm->fbcon); drm->fbcon = NULL; } void nouveau_fbcon_set_suspend(struct drm_device *dev, int state) { struct nouveau_drm *drm = nouveau_drm(dev); if (drm->fbcon) { if (state == FBINFO_STATE_RUNNING) { schedule_work(&drm->fbcon->work); return; } flush_work(&drm->fbcon->work); console_lock(); fb_set_suspend(drm->fbcon->helper.fbdev, state); nouveau_fbcon_accel_save_disable(dev); console_unlock(); } } Loading
drivers/gpu/drm/nouveau/nouveau_drm.c +127 −121 Original line number Diff line number Diff line Loading @@ -613,27 +613,6 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime) return ret; } int nouveau_pmops_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF || drm_dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF) return 0; ret = nouveau_do_suspend(drm_dev, false); if (ret) return ret; pci_save_state(pdev); pci_disable_device(pdev); pci_ignore_hotplug(pdev); pci_set_power_state(pdev, PCI_D3hot); return 0; } static int nouveau_do_resume(struct drm_device *dev, bool runtime) { Loading Loading @@ -668,7 +647,30 @@ nouveau_do_resume(struct drm_device *dev, bool runtime) return 0; } int nouveau_pmops_resume(struct device *dev) int nouveau_pmops_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF || drm_dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF) return 0; ret = nouveau_do_suspend(drm_dev, false); if (ret) return ret; pci_save_state(pdev); pci_disable_device(pdev); pci_ignore_hotplug(pdev); pci_set_power_state(pdev, PCI_D3hot); return 0; } int nouveau_pmops_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); Loading @@ -688,20 +690,121 @@ int nouveau_pmops_resume(struct device *dev) return nouveau_do_resume(drm_dev, false); } static int nouveau_pmops_freeze(struct device *dev) static int nouveau_pmops_freeze(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); return nouveau_do_suspend(drm_dev, false); } static int nouveau_pmops_thaw(struct device *dev) static int nouveau_pmops_thaw(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); return nouveau_do_resume(drm_dev, false); } static int nouveau_pmops_runtime_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; if (nouveau_runtime_pm == 0) { pm_runtime_forbid(dev); return -EBUSY; } /* are we optimus enabled? */ if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); pm_runtime_forbid(dev); return -EBUSY; } nv_debug_level(SILENT); drm_kms_helper_poll_disable(drm_dev); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); nouveau_switcheroo_optimus_dsm(); ret = nouveau_do_suspend(drm_dev, true); pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3cold); drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; return ret; } static int nouveau_pmops_runtime_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); struct nvif_device *device = &nouveau_drm(drm_dev)->device; int ret; if (nouveau_runtime_pm == 0) return -EINVAL; pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); ret = pci_enable_device(pdev); if (ret) return ret; pci_set_master(pdev); ret = nouveau_do_resume(drm_dev, true); drm_kms_helper_poll_enable(drm_dev); /* do magic */ nvif_mask(device, 0x88488, (1 << 25), (1 << 25)); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON); drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; nv_debug_level(NORMAL); return ret; } static int nouveau_pmops_runtime_idle(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); struct nouveau_drm *drm = nouveau_drm(drm_dev); struct drm_crtc *crtc; if (nouveau_runtime_pm == 0) { pm_runtime_forbid(dev); return -EBUSY; } /* are we optimus enabled? */ if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); pm_runtime_forbid(dev); return -EBUSY; } /* if we have a hdmi audio device - make sure it has a driver loaded */ if (drm->hdmi_device) { if (!drm->hdmi_device->driver) { DRM_DEBUG_DRIVER("failing to power off - no HDMI audio driver loaded\n"); pm_runtime_mark_last_busy(dev); return -EBUSY; } } list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) { if (crtc->enabled) { DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); return -EBUSY; } } pm_runtime_mark_last_busy(dev); pm_runtime_autosuspend(dev); /* we don't want the main rpm_idle to call suspend - we want to autosuspend */ return 1; } static int nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) Loading Loading @@ -908,103 +1011,6 @@ nouveau_drm_pci_table[] = { {} }; static int nouveau_pmops_runtime_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; if (nouveau_runtime_pm == 0) { pm_runtime_forbid(dev); return -EBUSY; } /* are we optimus enabled? */ if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); pm_runtime_forbid(dev); return -EBUSY; } nv_debug_level(SILENT); drm_kms_helper_poll_disable(drm_dev); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); nouveau_switcheroo_optimus_dsm(); ret = nouveau_do_suspend(drm_dev, true); pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3cold); drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; return ret; } static int nouveau_pmops_runtime_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); struct nvif_device *device = &nouveau_drm(drm_dev)->device; int ret; if (nouveau_runtime_pm == 0) return -EINVAL; pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); ret = pci_enable_device(pdev); if (ret) return ret; pci_set_master(pdev); ret = nouveau_do_resume(drm_dev, true); drm_kms_helper_poll_enable(drm_dev); /* do magic */ nvif_mask(device, 0x88488, (1 << 25), (1 << 25)); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON); drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; nv_debug_level(NORMAL); return ret; } static int nouveau_pmops_runtime_idle(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); struct nouveau_drm *drm = nouveau_drm(drm_dev); struct drm_crtc *crtc; if (nouveau_runtime_pm == 0) { pm_runtime_forbid(dev); return -EBUSY; } /* are we optimus enabled? */ if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); pm_runtime_forbid(dev); return -EBUSY; } /* if we have a hdmi audio device - make sure it has a driver loaded */ if (drm->hdmi_device) { if (!drm->hdmi_device->driver) { DRM_DEBUG_DRIVER("failing to power off - no HDMI audio driver loaded\n"); pm_runtime_mark_last_busy(dev); return -EBUSY; } } list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) { if (crtc->enabled) { DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); return -EBUSY; } } pm_runtime_mark_last_busy(dev); pm_runtime_autosuspend(dev); /* we don't want the main rpm_idle to call suspend - we want to autosuspend */ return 1; } static void nouveau_display_options(void) { DRM_DEBUG_DRIVER("Loading Nouveau with parameters:\n"); Loading
drivers/gpu/drm/nouveau/nouveau_fbcon.c +17 −17 Original line number Diff line number Diff line Loading @@ -498,6 +498,23 @@ nouveau_fbcon_set_suspend_work(struct work_struct *work) console_unlock(); } void nouveau_fbcon_set_suspend(struct drm_device *dev, int state) { struct nouveau_drm *drm = nouveau_drm(dev); if (drm->fbcon) { if (state == FBINFO_STATE_RUNNING) { schedule_work(&drm->fbcon->work); return; } flush_work(&drm->fbcon->work); console_lock(); fb_set_suspend(drm->fbcon->helper.fbdev, state); nouveau_fbcon_accel_save_disable(dev); console_unlock(); } } int nouveau_fbcon_init(struct drm_device *dev) { Loading Loading @@ -557,20 +574,3 @@ nouveau_fbcon_fini(struct drm_device *dev) kfree(drm->fbcon); drm->fbcon = NULL; } void nouveau_fbcon_set_suspend(struct drm_device *dev, int state) { struct nouveau_drm *drm = nouveau_drm(dev); if (drm->fbcon) { if (state == FBINFO_STATE_RUNNING) { schedule_work(&drm->fbcon->work); return; } flush_work(&drm->fbcon->work); console_lock(); fb_set_suspend(drm->fbcon->helper.fbdev, state); nouveau_fbcon_accel_save_disable(dev); console_unlock(); } }