aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_drv.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/gpu/drm/i915/i915_drv.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/gpu/drm/i915/i915_drv.c')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c299
1 files changed, 255 insertions, 44 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 7f436ec075f6..cc03537bb883 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -33,7 +33,6 @@
33#include "i915_drm.h" 33#include "i915_drm.h"
34#include "i915_drv.h" 34#include "i915_drv.h"
35 35
36#include "drm_pciids.h"
37#include <linux/console.h> 36#include <linux/console.h>
38#include "drm_crtc_helper.h" 37#include "drm_crtc_helper.h"
39 38
@@ -46,36 +45,163 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
46unsigned int i915_powersave = 1; 45unsigned int i915_powersave = 1;
47module_param_named(powersave, i915_powersave, int, 0400); 46module_param_named(powersave, i915_powersave, int, 0400);
48 47
48unsigned int i915_lvds_downclock = 0;
49module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
50
49static struct drm_driver driver; 51static struct drm_driver driver;
52extern int intel_agp_enabled;
53
54#define INTEL_VGA_DEVICE(id, info) { \
55 .class = PCI_CLASS_DISPLAY_VGA << 8, \
56 .class_mask = 0xffff00, \
57 .vendor = 0x8086, \
58 .device = id, \
59 .subvendor = PCI_ANY_ID, \
60 .subdevice = PCI_ANY_ID, \
61 .driver_data = (unsigned long) info }
62
63const static struct intel_device_info intel_i830_info = {
64 .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
65};
66
67const static struct intel_device_info intel_845g_info = {
68 .is_i8xx = 1,
69};
70
71const static struct intel_device_info intel_i85x_info = {
72 .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1,
73 .cursor_needs_physical = 1,
74};
75
76const static struct intel_device_info intel_i865g_info = {
77 .is_i8xx = 1,
78};
79
80const static struct intel_device_info intel_i915g_info = {
81 .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
82};
83const static struct intel_device_info intel_i915gm_info = {
84 .is_i9xx = 1, .is_mobile = 1,
85 .cursor_needs_physical = 1,
86};
87const static struct intel_device_info intel_i945g_info = {
88 .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
89};
90const static struct intel_device_info intel_i945gm_info = {
91 .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,
92 .has_hotplug = 1, .cursor_needs_physical = 1,
93};
94
95const static struct intel_device_info intel_i965g_info = {
96 .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1,
97};
98
99const static struct intel_device_info intel_i965gm_info = {
100 .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1,
101 .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1,
102 .has_hotplug = 1,
103};
104
105const static struct intel_device_info intel_g33_info = {
106 .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1,
107 .has_hotplug = 1,
108};
109
110const static struct intel_device_info intel_g45_info = {
111 .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1,
112 .has_pipe_cxsr = 1,
113 .has_hotplug = 1,
114};
115
116const static struct intel_device_info intel_gm45_info = {
117 .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1,
118 .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
119 .has_pipe_cxsr = 1,
120 .has_hotplug = 1,
121};
122
123const static struct intel_device_info intel_pineview_info = {
124 .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1,
125 .need_gfx_hws = 1,
126 .has_hotplug = 1,
127};
128
129const static struct intel_device_info intel_ironlake_d_info = {
130 .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
131 .has_pipe_cxsr = 1,
132 .has_hotplug = 1,
133};
50 134
51static struct pci_device_id pciidlist[] = { 135const static struct intel_device_info intel_ironlake_m_info = {
52 i915_PCI_IDS 136 .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1,
137 .need_gfx_hws = 1, .has_rc6 = 1,
138 .has_hotplug = 1,
139};
140
141const static struct intel_device_info intel_sandybridge_d_info = {
142 .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1,
143 .has_hotplug = 1, .is_gen6 = 1,
144};
145
146const static struct intel_device_info intel_sandybridge_m_info = {
147 .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1,
148 .has_hotplug = 1, .is_gen6 = 1,
149};
150
151const static struct pci_device_id pciidlist[] = {
152 INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
153 INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
154 INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
155 INTEL_VGA_DEVICE(0x358e, &intel_i85x_info),
156 INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),
157 INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),
158 INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),
159 INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info),
160 INTEL_VGA_DEVICE(0x2772, &intel_i945g_info),
161 INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info),
162 INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info),
163 INTEL_VGA_DEVICE(0x2972, &intel_i965g_info),
164 INTEL_VGA_DEVICE(0x2982, &intel_i965g_info),
165 INTEL_VGA_DEVICE(0x2992, &intel_i965g_info),
166 INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info),
167 INTEL_VGA_DEVICE(0x29b2, &intel_g33_info),
168 INTEL_VGA_DEVICE(0x29c2, &intel_g33_info),
169 INTEL_VGA_DEVICE(0x29d2, &intel_g33_info),
170 INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info),
171 INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info),
172 INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info),
173 INTEL_VGA_DEVICE(0x2e02, &intel_g45_info),
174 INTEL_VGA_DEVICE(0x2e12, &intel_g45_info),
175 INTEL_VGA_DEVICE(0x2e22, &intel_g45_info),
176 INTEL_VGA_DEVICE(0x2e32, &intel_g45_info),
177 INTEL_VGA_DEVICE(0x2e42, &intel_g45_info),
178 INTEL_VGA_DEVICE(0xa001, &intel_pineview_info),
179 INTEL_VGA_DEVICE(0xa011, &intel_pineview_info),
180 INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
181 INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info),
182 INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info),
183 INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info),
184 {0, 0, 0}
53}; 185};
54 186
55#if defined(CONFIG_DRM_I915_KMS) 187#if defined(CONFIG_DRM_I915_KMS)
56MODULE_DEVICE_TABLE(pci, pciidlist); 188MODULE_DEVICE_TABLE(pci, pciidlist);
57#endif 189#endif
58 190
59static int i915_suspend(struct drm_device *dev, pm_message_t state) 191static int i915_drm_freeze(struct drm_device *dev)
60{ 192{
61 struct drm_i915_private *dev_priv = dev->dev_private; 193 struct drm_i915_private *dev_priv = dev->dev_private;
62 194
63 if (!dev || !dev_priv) {
64 DRM_ERROR("dev: %p, dev_priv: %p\n", dev, dev_priv);
65 DRM_ERROR("DRM not initialized, aborting suspend.\n");
66 return -ENODEV;
67 }
68
69 if (state.event == PM_EVENT_PRETHAW)
70 return 0;
71
72 pci_save_state(dev->pdev); 195 pci_save_state(dev->pdev);
73 196
74 /* If KMS is active, we do the leavevt stuff here */ 197 /* If KMS is active, we do the leavevt stuff here */
75 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 198 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
76 if (i915_gem_idle(dev)) 199 int error = i915_gem_idle(dev);
200 if (error) {
77 dev_err(&dev->pdev->dev, 201 dev_err(&dev->pdev->dev,
78 "GEM idle failed, resume may fail\n"); 202 "GEM idle failed, resume might fail\n");
203 return error;
204 }
79 drm_irq_uninstall(dev); 205 drm_irq_uninstall(dev);
80 } 206 }
81 207
@@ -83,26 +209,42 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
83 209
84 intel_opregion_free(dev, 1); 210 intel_opregion_free(dev, 1);
85 211
212 /* Modeset on resume, not lid events */
213 dev_priv->modeset_on_lid = 0;
214
215 return 0;
216}
217
218int i915_suspend(struct drm_device *dev, pm_message_t state)
219{
220 int error;
221
222 if (!dev || !dev->dev_private) {
223 DRM_ERROR("dev: %p\n", dev);
224 DRM_ERROR("DRM not initialized, aborting suspend.\n");
225 return -ENODEV;
226 }
227
228 if (state.event == PM_EVENT_PRETHAW)
229 return 0;
230
231 error = i915_drm_freeze(dev);
232 if (error)
233 return error;
234
86 if (state.event == PM_EVENT_SUSPEND) { 235 if (state.event == PM_EVENT_SUSPEND) {
87 /* Shut down the device */ 236 /* Shut down the device */
88 pci_disable_device(dev->pdev); 237 pci_disable_device(dev->pdev);
89 pci_set_power_state(dev->pdev, PCI_D3hot); 238 pci_set_power_state(dev->pdev, PCI_D3hot);
90 } 239 }
91 240
92 /* Modeset on resume, not lid events */
93 dev_priv->modeset_on_lid = 0;
94
95 return 0; 241 return 0;
96} 242}
97 243
98static int i915_resume(struct drm_device *dev) 244static int i915_drm_thaw(struct drm_device *dev)
99{ 245{
100 struct drm_i915_private *dev_priv = dev->dev_private; 246 struct drm_i915_private *dev_priv = dev->dev_private;
101 int ret = 0; 247 int error = 0;
102
103 if (pci_enable_device(dev->pdev))
104 return -1;
105 pci_set_master(dev->pdev);
106 248
107 i915_restore_state(dev); 249 i915_restore_state(dev);
108 250
@@ -113,21 +255,28 @@ static int i915_resume(struct drm_device *dev)
113 mutex_lock(&dev->struct_mutex); 255 mutex_lock(&dev->struct_mutex);
114 dev_priv->mm.suspended = 0; 256 dev_priv->mm.suspended = 0;
115 257
116 ret = i915_gem_init_ringbuffer(dev); 258 error = i915_gem_init_ringbuffer(dev);
117 if (ret != 0)
118 ret = -1;
119 mutex_unlock(&dev->struct_mutex); 259 mutex_unlock(&dev->struct_mutex);
120 260
121 drm_irq_install(dev); 261 drm_irq_install(dev);
122 } 262
123 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
124 /* Resume the modeset for every activated CRTC */ 263 /* Resume the modeset for every activated CRTC */
125 drm_helper_resume_force_mode(dev); 264 drm_helper_resume_force_mode(dev);
126 } 265 }
127 266
128 dev_priv->modeset_on_lid = 0; 267 dev_priv->modeset_on_lid = 0;
129 268
130 return ret; 269 return error;
270}
271
272int i915_resume(struct drm_device *dev)
273{
274 if (pci_enable_device(dev->pdev))
275 return -EIO;
276
277 pci_set_master(dev->pdev);
278
279 return i915_drm_thaw(dev);
131} 280}
132 281
133/** 282/**
@@ -213,7 +362,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
213 !dev_priv->mm.suspended) { 362 !dev_priv->mm.suspended) {
214 drm_i915_ring_buffer_t *ring = &dev_priv->ring; 363 drm_i915_ring_buffer_t *ring = &dev_priv->ring;
215 struct drm_gem_object *obj = ring->ring_obj; 364 struct drm_gem_object *obj = ring->ring_obj;
216 struct drm_i915_gem_object *obj_priv = obj->driver_private; 365 struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
217 dev_priv->mm.suspended = 0; 366 dev_priv->mm.suspended = 0;
218 367
219 /* Stop the ring if it's running. */ 368 /* Stop the ring if it's running. */
@@ -268,22 +417,73 @@ i915_pci_remove(struct pci_dev *pdev)
268 drm_put_dev(dev); 417 drm_put_dev(dev);
269} 418}
270 419
271static int 420static int i915_pm_suspend(struct device *dev)
272i915_pci_suspend(struct pci_dev *pdev, pm_message_t state)
273{ 421{
274 struct drm_device *dev = pci_get_drvdata(pdev); 422 struct pci_dev *pdev = to_pci_dev(dev);
423 struct drm_device *drm_dev = pci_get_drvdata(pdev);
424 int error;
275 425
276 return i915_suspend(dev, state); 426 if (!drm_dev || !drm_dev->dev_private) {
427 dev_err(dev, "DRM not initialized, aborting suspend.\n");
428 return -ENODEV;
429 }
430
431 error = i915_drm_freeze(drm_dev);
432 if (error)
433 return error;
434
435 pci_disable_device(pdev);
436 pci_set_power_state(pdev, PCI_D3hot);
437
438 return 0;
277} 439}
278 440
279static int 441static int i915_pm_resume(struct device *dev)
280i915_pci_resume(struct pci_dev *pdev)
281{ 442{
282 struct drm_device *dev = pci_get_drvdata(pdev); 443 struct pci_dev *pdev = to_pci_dev(dev);
444 struct drm_device *drm_dev = pci_get_drvdata(pdev);
445
446 return i915_resume(drm_dev);
447}
448
449static int i915_pm_freeze(struct device *dev)
450{
451 struct pci_dev *pdev = to_pci_dev(dev);
452 struct drm_device *drm_dev = pci_get_drvdata(pdev);
453
454 if (!drm_dev || !drm_dev->dev_private) {
455 dev_err(dev, "DRM not initialized, aborting suspend.\n");
456 return -ENODEV;
457 }
458
459 return i915_drm_freeze(drm_dev);
460}
461
462static int i915_pm_thaw(struct device *dev)
463{
464 struct pci_dev *pdev = to_pci_dev(dev);
465 struct drm_device *drm_dev = pci_get_drvdata(pdev);
466
467 return i915_drm_thaw(drm_dev);
468}
469
470static int i915_pm_poweroff(struct device *dev)
471{
472 struct pci_dev *pdev = to_pci_dev(dev);
473 struct drm_device *drm_dev = pci_get_drvdata(pdev);
283 474
284 return i915_resume(dev); 475 return i915_drm_freeze(drm_dev);
285} 476}
286 477
478const struct dev_pm_ops i915_pm_ops = {
479 .suspend = i915_pm_suspend,
480 .resume = i915_pm_resume,
481 .freeze = i915_pm_freeze,
482 .thaw = i915_pm_thaw,
483 .poweroff = i915_pm_poweroff,
484 .restore = i915_pm_resume,
485};
486
287static struct vm_operations_struct i915_gem_vm_ops = { 487static struct vm_operations_struct i915_gem_vm_ops = {
288 .fault = i915_gem_fault, 488 .fault = i915_gem_fault,
289 .open = drm_gem_vm_open, 489 .open = drm_gem_vm_open,
@@ -303,8 +503,11 @@ static struct drm_driver driver = {
303 .lastclose = i915_driver_lastclose, 503 .lastclose = i915_driver_lastclose,
304 .preclose = i915_driver_preclose, 504 .preclose = i915_driver_preclose,
305 .postclose = i915_driver_postclose, 505 .postclose = i915_driver_postclose,
506
507 /* Used in place of i915_pm_ops for non-DRIVER_MODESET */
306 .suspend = i915_suspend, 508 .suspend = i915_suspend,
307 .resume = i915_resume, 509 .resume = i915_resume,
510
308 .device_is_agp = i915_driver_device_is_agp, 511 .device_is_agp = i915_driver_device_is_agp,
309 .enable_vblank = i915_enable_vblank, 512 .enable_vblank = i915_enable_vblank,
310 .disable_vblank = i915_disable_vblank, 513 .disable_vblank = i915_disable_vblank,
@@ -329,10 +532,11 @@ static struct drm_driver driver = {
329 .owner = THIS_MODULE, 532 .owner = THIS_MODULE,
330 .open = drm_open, 533 .open = drm_open,
331 .release = drm_release, 534 .release = drm_release,
332 .ioctl = drm_ioctl, 535 .unlocked_ioctl = drm_ioctl,
333 .mmap = drm_gem_mmap, 536 .mmap = drm_gem_mmap,
334 .poll = drm_poll, 537 .poll = drm_poll,
335 .fasync = drm_fasync, 538 .fasync = drm_fasync,
539 .read = drm_read,
336#ifdef CONFIG_COMPAT 540#ifdef CONFIG_COMPAT
337 .compat_ioctl = i915_compat_ioctl, 541 .compat_ioctl = i915_compat_ioctl,
338#endif 542#endif
@@ -343,10 +547,7 @@ static struct drm_driver driver = {
343 .id_table = pciidlist, 547 .id_table = pciidlist,
344 .probe = i915_pci_probe, 548 .probe = i915_pci_probe,
345 .remove = i915_pci_remove, 549 .remove = i915_pci_remove,
346#ifdef CONFIG_PM 550 .driver.pm = &i915_pm_ops,
347 .resume = i915_pci_resume,
348 .suspend = i915_pci_suspend,
349#endif
350 }, 551 },
351 552
352 .name = DRIVER_NAME, 553 .name = DRIVER_NAME,
@@ -359,6 +560,11 @@ static struct drm_driver driver = {
359 560
360static int __init i915_init(void) 561static int __init i915_init(void)
361{ 562{
563 if (!intel_agp_enabled) {
564 DRM_ERROR("drm/i915 can't work without intel_agp module!\n");
565 return -ENODEV;
566 }
567
362 driver.num_ioctls = i915_max_ioctl; 568 driver.num_ioctls = i915_max_ioctl;
363 569
364 i915_gem_shrinker_init(); 570 i915_gem_shrinker_init();
@@ -384,6 +590,11 @@ static int __init i915_init(void)
384 driver.driver_features &= ~DRIVER_MODESET; 590 driver.driver_features &= ~DRIVER_MODESET;
385#endif 591#endif
386 592
593 if (!(driver.driver_features & DRIVER_MODESET)) {
594 driver.suspend = i915_suspend;
595 driver.resume = i915_resume;
596 }
597
387 return drm_init(&driver); 598 return drm_init(&driver);
388} 599}
389 600