diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_drm.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drm.c | 98 |
1 files changed, 69 insertions, 29 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 8503b2ea570..01c403ddb99 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -49,8 +49,6 @@ #include "nouveau_fbcon.h" #include "nouveau_fence.h" -#include "nouveau_ttm.h" - MODULE_PARM_DESC(config, "option string to pass to driver core"); static char *nouveau_config; module_param_named(config, nouveau_config, charp, 0400); @@ -149,7 +147,7 @@ nouveau_accel_init(struct nouveau_drm *drm) NV_ERROR(drm, "failed to create ce channel, %d\n", ret); arg0 = NVE0_CHANNEL_IND_ENGINE_GR; - arg1 = 0; + arg1 = 1; } else { arg0 = NvDmaFB; arg1 = NvDmaTT; @@ -224,6 +222,7 @@ nouveau_drm_probe(struct pci_dev *pdev, const struct pci_device_id *pent) boot = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif remove_conflicting_framebuffers(aper, "nouveaufb", boot); + kfree(aper); ret = nouveau_device_create(pdev, nouveau_name(pdev), pci_name(pdev), nouveau_config, nouveau_debug, &device); @@ -395,17 +394,12 @@ nouveau_drm_remove(struct pci_dev *pdev) } int -nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) +nouveau_do_suspend(struct drm_device *dev) { - struct drm_device *dev = pci_get_drvdata(pdev); struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_cli *cli; int ret; - if (dev->switch_power_state == DRM_SWITCH_POWER_OFF || - pm_state.event == PM_EVENT_PRETHAW) - return 0; - if (dev->mode_config.num_crtc) { NV_INFO(drm, "suspending fbcon...\n"); nouveau_fbcon_set_suspend(dev, 1); @@ -436,13 +430,6 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) goto fail_client; nouveau_agp_fini(drm); - - pci_save_state(pdev); - if (pm_state.event == PM_EVENT_SUSPEND) { - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - } - return 0; fail_client: @@ -457,24 +444,33 @@ fail_client: return ret; } -int -nouveau_drm_resume(struct pci_dev *pdev) +int nouveau_pmops_suspend(struct device *dev) { - struct drm_device *dev = pci_get_drvdata(pdev); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_cli *cli; + struct pci_dev *pdev = to_pci_dev(dev); + struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; - if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) + if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - NV_INFO(drm, "re-enabling device...\n"); - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - ret = pci_enable_device(pdev); + ret = nouveau_do_suspend(drm_dev); if (ret) return ret; - pci_set_master(pdev); + + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + + return 0; +} + +int +nouveau_do_resume(struct drm_device *dev) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_cli *cli; + + NV_INFO(drm, "re-enabling device...\n"); nouveau_agp_reset(drm); @@ -500,6 +496,42 @@ nouveau_drm_resume(struct pci_dev *pdev) 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); + int ret; + + if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + ret = pci_enable_device(pdev); + if (ret) + return ret; + pci_set_master(pdev); + + return nouveau_do_resume(drm_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); +} + +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); +} + + static int nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) { @@ -652,14 +684,22 @@ nouveau_drm_pci_table[] = { {} }; +static const struct dev_pm_ops nouveau_pm_ops = { + .suspend = nouveau_pmops_suspend, + .resume = nouveau_pmops_resume, + .freeze = nouveau_pmops_freeze, + .thaw = nouveau_pmops_thaw, + .poweroff = nouveau_pmops_freeze, + .restore = nouveau_pmops_resume, +}; + static struct pci_driver nouveau_drm_pci_driver = { .name = "nouveau", .id_table = nouveau_drm_pci_table, .probe = nouveau_drm_probe, .remove = nouveau_drm_remove, - .suspend = nouveau_drm_suspend, - .resume = nouveau_drm_resume, + .driver.pm = &nouveau_pm_ops, }; static int __init |