aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_drv.c')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c214
1 files changed, 149 insertions, 65 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 895ab896e336..3467dd420760 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -32,6 +32,7 @@
32#include "drm.h" 32#include "drm.h"
33#include "i915_drm.h" 33#include "i915_drm.h"
34#include "i915_drv.h" 34#include "i915_drv.h"
35#include "intel_drv.h"
35 36
36#include <linux/console.h> 37#include <linux/console.h>
37#include "drm_crtc_helper.h" 38#include "drm_crtc_helper.h"
@@ -61,86 +62,110 @@ extern int intel_agp_enabled;
61 .driver_data = (unsigned long) info } 62 .driver_data = (unsigned long) info }
62 63
63static const struct intel_device_info intel_i830_info = { 64static const struct intel_device_info intel_i830_info = {
64 .gen = 2, .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, 65 .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1,
66 .has_overlay = 1, .overlay_needs_physical = 1,
65}; 67};
66 68
67static const struct intel_device_info intel_845g_info = { 69static const struct intel_device_info intel_845g_info = {
68 .gen = 2, .is_i8xx = 1, 70 .gen = 2,
71 .has_overlay = 1, .overlay_needs_physical = 1,
69}; 72};
70 73
71static const struct intel_device_info intel_i85x_info = { 74static const struct intel_device_info intel_i85x_info = {
72 .gen = 2, .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, 75 .gen = 2, .is_i85x = 1, .is_mobile = 1,
73 .cursor_needs_physical = 1, 76 .cursor_needs_physical = 1,
77 .has_overlay = 1, .overlay_needs_physical = 1,
74}; 78};
75 79
76static const struct intel_device_info intel_i865g_info = { 80static const struct intel_device_info intel_i865g_info = {
77 .gen = 2, .is_i8xx = 1, 81 .gen = 2,
82 .has_overlay = 1, .overlay_needs_physical = 1,
78}; 83};
79 84
80static const struct intel_device_info intel_i915g_info = { 85static const struct intel_device_info intel_i915g_info = {
81 .gen = 3, .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, 86 .gen = 3, .is_i915g = 1, .cursor_needs_physical = 1,
87 .has_overlay = 1, .overlay_needs_physical = 1,
82}; 88};
83static const struct intel_device_info intel_i915gm_info = { 89static const struct intel_device_info intel_i915gm_info = {
84 .gen = 3, .is_i9xx = 1, .is_mobile = 1, 90 .gen = 3, .is_mobile = 1,
85 .cursor_needs_physical = 1, 91 .cursor_needs_physical = 1,
92 .has_overlay = 1, .overlay_needs_physical = 1,
93 .supports_tv = 1,
86}; 94};
87static const struct intel_device_info intel_i945g_info = { 95static const struct intel_device_info intel_i945g_info = {
88 .gen = 3, .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, 96 .gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1,
97 .has_overlay = 1, .overlay_needs_physical = 1,
89}; 98};
90static const struct intel_device_info intel_i945gm_info = { 99static const struct intel_device_info intel_i945gm_info = {
91 .gen = 3, .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, 100 .gen = 3, .is_i945gm = 1, .is_mobile = 1,
92 .has_hotplug = 1, .cursor_needs_physical = 1, 101 .has_hotplug = 1, .cursor_needs_physical = 1,
102 .has_overlay = 1, .overlay_needs_physical = 1,
103 .supports_tv = 1,
93}; 104};
94 105
95static const struct intel_device_info intel_i965g_info = { 106static const struct intel_device_info intel_i965g_info = {
96 .gen = 4, .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, 107 .gen = 4, .is_broadwater = 1,
97 .has_hotplug = 1, 108 .has_hotplug = 1,
109 .has_overlay = 1,
98}; 110};
99 111
100static const struct intel_device_info intel_i965gm_info = { 112static const struct intel_device_info intel_i965gm_info = {
101 .gen = 4, .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, 113 .gen = 4, .is_crestline = 1,
102 .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, 114 .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1,
115 .has_overlay = 1,
116 .supports_tv = 1,
103}; 117};
104 118
105static const struct intel_device_info intel_g33_info = { 119static const struct intel_device_info intel_g33_info = {
106 .gen = 3, .is_g33 = 1, .is_i9xx = 1, 120 .gen = 3, .is_g33 = 1,
107 .need_gfx_hws = 1, .has_hotplug = 1, 121 .need_gfx_hws = 1, .has_hotplug = 1,
122 .has_overlay = 1,
108}; 123};
109 124
110static const struct intel_device_info intel_g45_info = { 125static const struct intel_device_info intel_g45_info = {
111 .gen = 4, .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, 126 .gen = 4, .is_g4x = 1, .need_gfx_hws = 1,
112 .has_pipe_cxsr = 1, .has_hotplug = 1, 127 .has_pipe_cxsr = 1, .has_hotplug = 1,
128 .has_bsd_ring = 1,
113}; 129};
114 130
115static const struct intel_device_info intel_gm45_info = { 131static const struct intel_device_info intel_gm45_info = {
116 .gen = 4, .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, 132 .gen = 4, .is_g4x = 1,
117 .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, 133 .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
118 .has_pipe_cxsr = 1, .has_hotplug = 1, 134 .has_pipe_cxsr = 1, .has_hotplug = 1,
135 .supports_tv = 1,
136 .has_bsd_ring = 1,
119}; 137};
120 138
121static const struct intel_device_info intel_pineview_info = { 139static const struct intel_device_info intel_pineview_info = {
122 .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, 140 .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1,
123 .need_gfx_hws = 1, .has_hotplug = 1, 141 .need_gfx_hws = 1, .has_hotplug = 1,
142 .has_overlay = 1,
124}; 143};
125 144
126static const struct intel_device_info intel_ironlake_d_info = { 145static const struct intel_device_info intel_ironlake_d_info = {
127 .gen = 5, .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, 146 .gen = 5,
128 .need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1, 147 .need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1,
148 .has_bsd_ring = 1,
129}; 149};
130 150
131static const struct intel_device_info intel_ironlake_m_info = { 151static const struct intel_device_info intel_ironlake_m_info = {
132 .gen = 5, .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, 152 .gen = 5, .is_mobile = 1,
133 .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, 153 .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1,
154 .has_bsd_ring = 1,
134}; 155};
135 156
136static const struct intel_device_info intel_sandybridge_d_info = { 157static const struct intel_device_info intel_sandybridge_d_info = {
137 .gen = 6, .is_i965g = 1, .is_i9xx = 1, 158 .gen = 6,
138 .need_gfx_hws = 1, .has_hotplug = 1, 159 .need_gfx_hws = 1, .has_hotplug = 1,
160 .has_bsd_ring = 1,
161 .has_blt_ring = 1,
139}; 162};
140 163
141static const struct intel_device_info intel_sandybridge_m_info = { 164static const struct intel_device_info intel_sandybridge_m_info = {
142 .gen = 6, .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, 165 .gen = 6, .is_mobile = 1,
143 .need_gfx_hws = 1, .has_hotplug = 1, 166 .need_gfx_hws = 1, .has_hotplug = 1,
167 .has_bsd_ring = 1,
168 .has_blt_ring = 1,
144}; 169};
145 170
146static const struct pci_device_id pciidlist[] = { /* aka */ 171static const struct pci_device_id pciidlist[] = { /* aka */
@@ -237,7 +262,7 @@ static int i915_drm_freeze(struct drm_device *dev)
237 262
238 i915_save_state(dev); 263 i915_save_state(dev);
239 264
240 intel_opregion_free(dev, 1); 265 intel_opregion_fini(dev);
241 266
242 /* Modeset on resume, not lid events */ 267 /* Modeset on resume, not lid events */
243 dev_priv->modeset_on_lid = 0; 268 dev_priv->modeset_on_lid = 0;
@@ -258,6 +283,8 @@ int i915_suspend(struct drm_device *dev, pm_message_t state)
258 if (state.event == PM_EVENT_PRETHAW) 283 if (state.event == PM_EVENT_PRETHAW)
259 return 0; 284 return 0;
260 285
286 drm_kms_helper_poll_disable(dev);
287
261 error = i915_drm_freeze(dev); 288 error = i915_drm_freeze(dev);
262 if (error) 289 if (error)
263 return error; 290 return error;
@@ -277,8 +304,7 @@ static int i915_drm_thaw(struct drm_device *dev)
277 int error = 0; 304 int error = 0;
278 305
279 i915_restore_state(dev); 306 i915_restore_state(dev);
280 307 intel_opregion_setup(dev);
281 intel_opregion_init(dev, 1);
282 308
283 /* KMS EnterVT equivalent */ 309 /* KMS EnterVT equivalent */
284 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 310 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
@@ -294,6 +320,8 @@ static int i915_drm_thaw(struct drm_device *dev)
294 drm_helper_resume_force_mode(dev); 320 drm_helper_resume_force_mode(dev);
295 } 321 }
296 322
323 intel_opregion_init(dev);
324
297 dev_priv->modeset_on_lid = 0; 325 dev_priv->modeset_on_lid = 0;
298 326
299 return error; 327 return error;
@@ -301,12 +329,79 @@ static int i915_drm_thaw(struct drm_device *dev)
301 329
302int i915_resume(struct drm_device *dev) 330int i915_resume(struct drm_device *dev)
303{ 331{
332 int ret;
333
304 if (pci_enable_device(dev->pdev)) 334 if (pci_enable_device(dev->pdev))
305 return -EIO; 335 return -EIO;
306 336
307 pci_set_master(dev->pdev); 337 pci_set_master(dev->pdev);
308 338
309 return i915_drm_thaw(dev); 339 ret = i915_drm_thaw(dev);
340 if (ret)
341 return ret;
342
343 drm_kms_helper_poll_enable(dev);
344 return 0;
345}
346
347static int i8xx_do_reset(struct drm_device *dev, u8 flags)
348{
349 struct drm_i915_private *dev_priv = dev->dev_private;
350
351 if (IS_I85X(dev))
352 return -ENODEV;
353
354 I915_WRITE(D_STATE, I915_READ(D_STATE) | DSTATE_GFX_RESET_I830);
355 POSTING_READ(D_STATE);
356
357 if (IS_I830(dev) || IS_845G(dev)) {
358 I915_WRITE(DEBUG_RESET_I830,
359 DEBUG_RESET_DISPLAY |
360 DEBUG_RESET_RENDER |
361 DEBUG_RESET_FULL);
362 POSTING_READ(DEBUG_RESET_I830);
363 msleep(1);
364
365 I915_WRITE(DEBUG_RESET_I830, 0);
366 POSTING_READ(DEBUG_RESET_I830);
367 }
368
369 msleep(1);
370
371 I915_WRITE(D_STATE, I915_READ(D_STATE) & ~DSTATE_GFX_RESET_I830);
372 POSTING_READ(D_STATE);
373
374 return 0;
375}
376
377static int i965_reset_complete(struct drm_device *dev)
378{
379 u8 gdrst;
380 pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst);
381 return gdrst & 0x1;
382}
383
384static int i965_do_reset(struct drm_device *dev, u8 flags)
385{
386 u8 gdrst;
387
388 /*
389 * Set the domains we want to reset (GRDOM/bits 2 and 3) as
390 * well as the reset bit (GR/bit 0). Setting the GR bit
391 * triggers the reset; when done, the hardware will clear it.
392 */
393 pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst);
394 pci_write_config_byte(dev->pdev, I965_GDRST, gdrst | flags | 0x1);
395
396 return wait_for(i965_reset_complete(dev), 500);
397}
398
399static int ironlake_do_reset(struct drm_device *dev, u8 flags)
400{
401 struct drm_i915_private *dev_priv = dev->dev_private;
402 u32 gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR);
403 I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, gdrst | flags | 0x1);
404 return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500);
310} 405}
311 406
312/** 407/**
@@ -325,54 +420,39 @@ int i915_resume(struct drm_device *dev)
325 * - re-init interrupt state 420 * - re-init interrupt state
326 * - re-init display 421 * - re-init display
327 */ 422 */
328int i965_reset(struct drm_device *dev, u8 flags) 423int i915_reset(struct drm_device *dev, u8 flags)
329{ 424{
330 drm_i915_private_t *dev_priv = dev->dev_private; 425 drm_i915_private_t *dev_priv = dev->dev_private;
331 unsigned long timeout;
332 u8 gdrst;
333 /* 426 /*
334 * We really should only reset the display subsystem if we actually 427 * We really should only reset the display subsystem if we actually
335 * need to 428 * need to
336 */ 429 */
337 bool need_display = true; 430 bool need_display = true;
431 int ret;
338 432
339 mutex_lock(&dev->struct_mutex); 433 mutex_lock(&dev->struct_mutex);
340 434
341 /* 435 i915_gem_reset(dev);
342 * Clear request list 436
343 */ 437 ret = -ENODEV;
344 i915_gem_retire_requests(dev); 438 if (get_seconds() - dev_priv->last_gpu_reset < 5) {
345 439 DRM_ERROR("GPU hanging too fast, declaring wedged!\n");
346 if (need_display) 440 } else switch (INTEL_INFO(dev)->gen) {
347 i915_save_display(dev); 441 case 5:
348 442 ret = ironlake_do_reset(dev, flags);
349 if (IS_I965G(dev) || IS_G4X(dev)) { 443 break;
350 /* 444 case 4:
351 * Set the domains we want to reset, then the reset bit (bit 0). 445 ret = i965_do_reset(dev, flags);
352 * Clear the reset bit after a while and wait for hardware status 446 break;
353 * bit (bit 1) to be set 447 case 2:
354 */ 448 ret = i8xx_do_reset(dev, flags);
355 pci_read_config_byte(dev->pdev, GDRST, &gdrst); 449 break;
356 pci_write_config_byte(dev->pdev, GDRST, gdrst | flags | ((flags == GDRST_FULL) ? 0x1 : 0x0)); 450 }
357 udelay(50); 451 dev_priv->last_gpu_reset = get_seconds();
358 pci_write_config_byte(dev->pdev, GDRST, gdrst & 0xfe); 452 if (ret) {
359 453 DRM_ERROR("Failed to reset chip.\n");
360 /* ...we don't want to loop forever though, 500ms should be plenty */
361 timeout = jiffies + msecs_to_jiffies(500);
362 do {
363 udelay(100);
364 pci_read_config_byte(dev->pdev, GDRST, &gdrst);
365 } while ((gdrst & 0x1) && time_after(timeout, jiffies));
366
367 if (gdrst & 0x1) {
368 WARN(true, "i915: Failed to reset chip\n");
369 mutex_unlock(&dev->struct_mutex);
370 return -EIO;
371 }
372 } else {
373 DRM_ERROR("Error occurred. Don't know how to reset this chip.\n");
374 mutex_unlock(&dev->struct_mutex); 454 mutex_unlock(&dev->struct_mutex);
375 return -ENODEV; 455 return ret;
376 } 456 }
377 457
378 /* Ok, now get things going again... */ 458 /* Ok, now get things going again... */
@@ -400,13 +480,19 @@ int i965_reset(struct drm_device *dev, u8 flags)
400 mutex_lock(&dev->struct_mutex); 480 mutex_lock(&dev->struct_mutex);
401 } 481 }
402 482
483 mutex_unlock(&dev->struct_mutex);
484
403 /* 485 /*
404 * Display needs restore too... 486 * Perform a full modeset as on later generations, e.g. Ironlake, we may
487 * need to retrain the display link and cannot just restore the register
488 * values.
405 */ 489 */
406 if (need_display) 490 if (need_display) {
407 i915_restore_display(dev); 491 mutex_lock(&dev->mode_config.mutex);
492 drm_helper_resume_force_mode(dev);
493 mutex_unlock(&dev->mode_config.mutex);
494 }
408 495
409 mutex_unlock(&dev->struct_mutex);
410 return 0; 496 return 0;
411} 497}
412 498
@@ -524,8 +610,6 @@ static struct drm_driver driver = {
524 .irq_uninstall = i915_driver_irq_uninstall, 610 .irq_uninstall = i915_driver_irq_uninstall,
525 .irq_handler = i915_driver_irq_handler, 611 .irq_handler = i915_driver_irq_handler,
526 .reclaim_buffers = drm_core_reclaim_buffers, 612 .reclaim_buffers = drm_core_reclaim_buffers,
527 .get_map_ofs = drm_core_get_map_ofs,
528 .get_reg_ofs = drm_core_get_reg_ofs,
529 .master_create = i915_master_create, 613 .master_create = i915_master_create,
530 .master_destroy = i915_master_destroy, 614 .master_destroy = i915_master_destroy,
531#if defined(CONFIG_DEBUG_FS) 615#if defined(CONFIG_DEBUG_FS)