aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2014-04-14 05:34:48 -0400
committerDave Airlie <airlied@redhat.com>2014-04-17 23:31:49 -0400
commit2f1e800799bf478494cec3573cd63eb34ca89c9d (patch)
treeae2a647ada73c577de93d23d7ec4cc1d1105f84c
parent8d754544202c0e4ef02e9c1abdf379bcf7ef9384 (diff)
drm: cirrus: add power management support
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>
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.c42
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_mode.c3
2 files changed, 45 insertions, 0 deletions
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index 953fc8aea69c..08ce520f61a5 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -11,6 +11,7 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/console.h> 12#include <linux/console.h>
13#include <drm/drmP.h> 13#include <drm/drmP.h>
14#include <drm/drm_crtc_helper.h>
14 15
15#include "cirrus_drv.h" 16#include "cirrus_drv.h"
16 17
@@ -75,6 +76,41 @@ static void cirrus_pci_remove(struct pci_dev *pdev)
75 drm_put_dev(dev); 76 drm_put_dev(dev);
76} 77}
77 78
79static int cirrus_pm_suspend(struct device *dev)
80{
81 struct pci_dev *pdev = to_pci_dev(dev);
82 struct drm_device *drm_dev = pci_get_drvdata(pdev);
83 struct cirrus_device *cdev = drm_dev->dev_private;
84
85 drm_kms_helper_poll_disable(drm_dev);
86
87 if (cdev->mode_info.gfbdev) {
88 console_lock();
89 fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 1);
90 console_unlock();
91 }
92
93 return 0;
94}
95
96static int cirrus_pm_resume(struct device *dev)
97{
98 struct pci_dev *pdev = to_pci_dev(dev);
99 struct drm_device *drm_dev = pci_get_drvdata(pdev);
100 struct cirrus_device *cdev = drm_dev->dev_private;
101
102 drm_helper_resume_force_mode(drm_dev);
103
104 if (cdev->mode_info.gfbdev) {
105 console_lock();
106 fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0);
107 console_unlock();
108 }
109
110 drm_kms_helper_poll_enable(drm_dev);
111 return 0;
112}
113
78static const struct file_operations cirrus_driver_fops = { 114static const struct file_operations cirrus_driver_fops = {
79 .owner = THIS_MODULE, 115 .owner = THIS_MODULE,
80 .open = drm_open, 116 .open = drm_open,
@@ -103,11 +139,17 @@ static struct drm_driver driver = {
103 .dumb_destroy = drm_gem_dumb_destroy, 139 .dumb_destroy = drm_gem_dumb_destroy,
104}; 140};
105 141
142static const struct dev_pm_ops cirrus_pm_ops = {
143 SET_SYSTEM_SLEEP_PM_OPS(cirrus_pm_suspend,
144 cirrus_pm_resume)
145};
146
106static struct pci_driver cirrus_pci_driver = { 147static struct pci_driver cirrus_pci_driver = {
107 .name = DRIVER_NAME, 148 .name = DRIVER_NAME,
108 .id_table = pciidlist, 149 .id_table = pciidlist,
109 .probe = cirrus_pci_probe, 150 .probe = cirrus_pci_probe,
110 .remove = cirrus_pci_remove, 151 .remove = cirrus_pci_remove,
152 .driver.pm = &cirrus_pm_ops,
111}; 153};
112 154
113static int __init cirrus_init(void) 155static int __init cirrus_init(void)
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 2d64aea83df2..f59433b7610c 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -308,6 +308,9 @@ static int cirrus_crtc_mode_set(struct drm_crtc *crtc,
308 308
309 WREG_HDR(hdr); 309 WREG_HDR(hdr);
310 cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0); 310 cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0);
311
312 /* Unblank (needed on S3 resume, vgabios doesn't do it then) */
313 outb(0x20, 0x3c0);
311 return 0; 314 return 0;
312} 315}
313 316