Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 345447
b: refs/heads/master
c: 2d8b9cc
h: refs/heads/master
i:
  345445: 412f97b
  345443: 627f5f6
  345439: 69dfccc
v: v3
  • Loading branch information
Dave Airlie authored and Ben Skeggs committed Nov 28, 2012
1 parent 59c4463 commit 8c9b232
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c839d748bdaa4f373368abeef3efc18e21e78313
refs/heads/master: 2d8b9ccbcee694c9ce681ec596df642e52ddcb15
93 changes: 67 additions & 26 deletions trunk/drivers/gpu/drm/nouveau/nouveau_drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,17 +395,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);
Expand Down Expand Up @@ -436,13 +431,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:
Expand All @@ -457,24 +445,33 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state)
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);

Expand All @@ -500,6 +497,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)
{
Expand Down Expand Up @@ -652,14 +685,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
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/gpu/drm/nouveau/nouveau_drm.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ nouveau_dev(struct drm_device *dev)
return nv_device(nouveau_drm(dev)->device);
}

int nouveau_drm_suspend(struct pci_dev *, pm_message_t);
int nouveau_drm_resume(struct pci_dev *);
int nouveau_pmops_suspend(struct device *);
int nouveau_pmops_resume(struct device *);

#define NV_FATAL(cli, fmt, args...) nv_fatal((cli), fmt, ##args)
#define NV_ERROR(cli, fmt, args...) nv_error((cli), fmt, ##args)
Expand Down
5 changes: 2 additions & 3 deletions trunk/drivers/gpu/drm/nouveau/nouveau_vga.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,19 @@ nouveau_switcheroo_set_state(struct pci_dev *pdev,
enum vga_switcheroo_state state)
{
struct drm_device *dev = pci_get_drvdata(pdev);
pm_message_t pmm = { .event = PM_EVENT_SUSPEND };

if (state == VGA_SWITCHEROO_ON) {
printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
nouveau_drm_resume(pdev);
nouveau_pmops_resume(&pdev->dev);
drm_kms_helper_poll_enable(dev);
dev->switch_power_state = DRM_SWITCH_POWER_ON;
} else {
printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
drm_kms_helper_poll_disable(dev);
nouveau_switcheroo_optimus_dsm();
nouveau_drm_suspend(pdev, pmm);
nouveau_pmops_suspend(&pdev->dev);
dev->switch_power_state = DRM_SWITCH_POWER_OFF;
}
}
Expand Down

0 comments on commit 8c9b232

Please sign in to comment.