Skip to content

Commit

Permalink
drm: cirrus: add power management support
Browse files Browse the repository at this point in the history
cirrus kms driver lacks power management support, thus
the vga display doesn't work any more after S3 resume.

Fix this by adding suspend and resume functions.
Also make the mode_set function unblank the screen.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Gerd Hoffmann authored and Dave Airlie committed Apr 18, 2014
1 parent 8d75454 commit 2f1e800
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
42 changes: 42 additions & 0 deletions drivers/gpu/drm/cirrus/cirrus_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/console.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>

#include "cirrus_drv.h"

Expand Down Expand Up @@ -75,6 +76,41 @@ static void cirrus_pci_remove(struct pci_dev *pdev)
drm_put_dev(dev);
}

static int cirrus_pm_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct cirrus_device *cdev = drm_dev->dev_private;

drm_kms_helper_poll_disable(drm_dev);

if (cdev->mode_info.gfbdev) {
console_lock();
fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 1);
console_unlock();
}

return 0;
}

static int cirrus_pm_resume(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct cirrus_device *cdev = drm_dev->dev_private;

drm_helper_resume_force_mode(drm_dev);

if (cdev->mode_info.gfbdev) {
console_lock();
fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0);
console_unlock();
}

drm_kms_helper_poll_enable(drm_dev);
return 0;
}

static const struct file_operations cirrus_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
Expand Down Expand Up @@ -103,11 +139,17 @@ static struct drm_driver driver = {
.dumb_destroy = drm_gem_dumb_destroy,
};

static const struct dev_pm_ops cirrus_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(cirrus_pm_suspend,
cirrus_pm_resume)
};

static struct pci_driver cirrus_pci_driver = {
.name = DRIVER_NAME,
.id_table = pciidlist,
.probe = cirrus_pci_probe,
.remove = cirrus_pci_remove,
.driver.pm = &cirrus_pm_ops,
};

static int __init cirrus_init(void)
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/cirrus/cirrus_mode.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,9 @@ static int cirrus_crtc_mode_set(struct drm_crtc *crtc,

WREG_HDR(hdr);
cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0);

/* Unblank (needed on S3 resume, vgabios doesn't do it then) */
outb(0x20, 0x3c0);
return 0;
}

Expand Down

0 comments on commit 2f1e800

Please sign in to comment.