diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_context.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 33 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_modes.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_panel.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sprite.c | 1 |
18 files changed, 140 insertions, 119 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 2909b123baf5..359f6e8b9b00 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -676,6 +676,7 @@ static void i915_ring_error_state(struct seq_file *m, | |||
676 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); | 676 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); |
677 | seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); | 677 | seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); |
678 | if (INTEL_INFO(dev)->gen >= 6) { | 678 | if (INTEL_INFO(dev)->gen >= 6) { |
679 | seq_printf(m, " RC PSMI: 0x%08x\n", error->rc_psmi[ring]); | ||
679 | seq_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); | 680 | seq_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); |
680 | seq_printf(m, " SYNC_0: 0x%08x\n", | 681 | seq_printf(m, " SYNC_0: 0x%08x\n", |
681 | error->semaphore_mboxes[ring][0]); | 682 | error->semaphore_mboxes[ring][0]); |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f64ef4b723fd..9cf7dfe022b9 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1781,7 +1781,13 @@ void i915_driver_lastclose(struct drm_device * dev) | |||
1781 | { | 1781 | { |
1782 | drm_i915_private_t *dev_priv = dev->dev_private; | 1782 | drm_i915_private_t *dev_priv = dev->dev_private; |
1783 | 1783 | ||
1784 | if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { | 1784 | /* On gen6+ we refuse to init without kms enabled, but then the drm core |
1785 | * goes right around and calls lastclose. Check for this and don't clean | ||
1786 | * up anything. */ | ||
1787 | if (!dev_priv) | ||
1788 | return; | ||
1789 | |||
1790 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
1785 | intel_fb_restore_mode(dev); | 1791 | intel_fb_restore_mode(dev); |
1786 | vga_switcheroo_process_delayed_switch(); | 1792 | vga_switcheroo_process_delayed_switch(); |
1787 | return; | 1793 | return; |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 476c64c4844c..627fe35781b4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -190,6 +190,7 @@ struct drm_i915_error_state { | |||
190 | u32 instdone[I915_NUM_RINGS]; | 190 | u32 instdone[I915_NUM_RINGS]; |
191 | u32 acthd[I915_NUM_RINGS]; | 191 | u32 acthd[I915_NUM_RINGS]; |
192 | u32 semaphore_mboxes[I915_NUM_RINGS][I915_NUM_RINGS - 1]; | 192 | u32 semaphore_mboxes[I915_NUM_RINGS][I915_NUM_RINGS - 1]; |
193 | u32 rc_psmi[I915_NUM_RINGS]; /* sleep state */ | ||
193 | /* our own tracking of ring head and tail */ | 194 | /* our own tracking of ring head and tail */ |
194 | u32 cpu_ring_head[I915_NUM_RINGS]; | 195 | u32 cpu_ring_head[I915_NUM_RINGS]; |
195 | u32 cpu_ring_tail[I915_NUM_RINGS]; | 196 | u32 cpu_ring_tail[I915_NUM_RINGS]; |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0fdb3d29cbbb..5c4657a54f97 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2003,6 +2003,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, | |||
2003 | } | 2003 | } |
2004 | 2004 | ||
2005 | switch (end) { | 2005 | switch (end) { |
2006 | case -EIO: | ||
2006 | case -EAGAIN: /* Wedged */ | 2007 | case -EAGAIN: /* Wedged */ |
2007 | case -ERESTARTSYS: /* Signal */ | 2008 | case -ERESTARTSYS: /* Signal */ |
2008 | return (int)end; | 2009 | return (int)end; |
@@ -3726,6 +3727,22 @@ void i915_gem_init_ppgtt(struct drm_device *dev) | |||
3726 | } | 3727 | } |
3727 | } | 3728 | } |
3728 | 3729 | ||
3730 | static bool | ||
3731 | intel_enable_blt(struct drm_device *dev) | ||
3732 | { | ||
3733 | if (!HAS_BLT(dev)) | ||
3734 | return false; | ||
3735 | |||
3736 | /* The blitter was dysfunctional on early prototypes */ | ||
3737 | if (IS_GEN6(dev) && dev->pdev->revision < 8) { | ||
3738 | DRM_INFO("BLT not supported on this pre-production hardware;" | ||
3739 | " graphics performance will be degraded.\n"); | ||
3740 | return false; | ||
3741 | } | ||
3742 | |||
3743 | return true; | ||
3744 | } | ||
3745 | |||
3729 | int | 3746 | int |
3730 | i915_gem_init_hw(struct drm_device *dev) | 3747 | i915_gem_init_hw(struct drm_device *dev) |
3731 | { | 3748 | { |
@@ -3749,7 +3766,7 @@ i915_gem_init_hw(struct drm_device *dev) | |||
3749 | goto cleanup_render_ring; | 3766 | goto cleanup_render_ring; |
3750 | } | 3767 | } |
3751 | 3768 | ||
3752 | if (HAS_BLT(dev)) { | 3769 | if (intel_enable_blt(dev)) { |
3753 | ret = intel_init_blt_ring_buffer(dev); | 3770 | ret = intel_init_blt_ring_buffer(dev); |
3754 | if (ret) | 3771 | if (ret) |
3755 | goto cleanup_bsd_ring; | 3772 | goto cleanup_bsd_ring; |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 9ae3f2cf414e..da8b01fb1bf8 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -112,8 +112,8 @@ static int get_context_size(struct drm_device *dev) | |||
112 | ret = GEN6_CXT_TOTAL_SIZE(reg) * 64; | 112 | ret = GEN6_CXT_TOTAL_SIZE(reg) * 64; |
113 | break; | 113 | break; |
114 | case 7: | 114 | case 7: |
115 | reg = I915_READ(GEN7_CTX_SIZE); | 115 | reg = I915_READ(GEN7_CXT_SIZE); |
116 | ret = GEN7_CTX_TOTAL_SIZE(reg) * 64; | 116 | ret = GEN7_CXT_TOTAL_SIZE(reg) * 64; |
117 | break; | 117 | break; |
118 | default: | 118 | default: |
119 | BUG(); | 119 | BUG(); |
@@ -374,6 +374,17 @@ static int do_switch(struct drm_i915_gem_object *from_obj, | |||
374 | if (ret) | 374 | if (ret) |
375 | return ret; | 375 | return ret; |
376 | 376 | ||
377 | /* Clear this page out of any CPU caches for coherent swap-in/out. Note | ||
378 | * that thanks to write = false in this call and us not setting any gpu | ||
379 | * write domains when putting a context object onto the active list | ||
380 | * (when switching away from it), this won't block. | ||
381 | * XXX: We need a real interface to do this instead of trickery. */ | ||
382 | ret = i915_gem_object_set_to_gtt_domain(to->obj, false); | ||
383 | if (ret) { | ||
384 | i915_gem_object_unpin(to->obj); | ||
385 | return ret; | ||
386 | } | ||
387 | |||
377 | if (!to->obj->has_global_gtt_mapping) | 388 | if (!to->obj->has_global_gtt_mapping) |
378 | i915_gem_gtt_bind_object(to->obj, to->obj->cache_level); | 389 | i915_gem_gtt_bind_object(to->obj, to->obj->cache_level); |
379 | 390 | ||
@@ -408,8 +419,11 @@ static int do_switch(struct drm_i915_gem_object *from_obj, | |||
408 | from_obj->dirty = 1; | 419 | from_obj->dirty = 1; |
409 | BUG_ON(from_obj->ring != to->ring); | 420 | BUG_ON(from_obj->ring != to->ring); |
410 | i915_gem_object_unpin(from_obj); | 421 | i915_gem_object_unpin(from_obj); |
422 | |||
423 | drm_gem_object_unreference(&from_obj->base); | ||
411 | } | 424 | } |
412 | 425 | ||
426 | drm_gem_object_reference(&to->obj->base); | ||
413 | ring->last_context_obj = to->obj; | 427 | ring->last_context_obj = to->obj; |
414 | to->is_initialized = true; | 428 | to->is_initialized = true; |
415 | 429 | ||
@@ -459,20 +473,7 @@ int i915_switch_context(struct intel_ring_buffer *ring, | |||
459 | if (from_obj == to->obj) | 473 | if (from_obj == to->obj) |
460 | return 0; | 474 | return 0; |
461 | 475 | ||
462 | ret = do_switch(from_obj, to, i915_gem_next_request_seqno(to->ring)); | 476 | return do_switch(from_obj, to, i915_gem_next_request_seqno(to->ring)); |
463 | if (ret) | ||
464 | return ret; | ||
465 | |||
466 | /* Just to make the code a little cleaner we take the object reference | ||
467 | * after the switch was successful. It would be more intuitive to ref | ||
468 | * the 'to' object before the switch but we know the refcount must be >0 | ||
469 | * if context_get() succeeded, and we hold struct mutex. So it's safe to | ||
470 | * do this here/now | ||
471 | */ | ||
472 | drm_gem_object_reference(&to->obj->base); | ||
473 | if (from_obj != NULL) | ||
474 | drm_gem_object_unreference(&from_obj->base); | ||
475 | return ret; | ||
476 | } | 477 | } |
477 | 478 | ||
478 | int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, | 479 | int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, |
@@ -496,11 +497,13 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, | |||
496 | 497 | ||
497 | ctx = create_hw_context(dev, file_priv); | 498 | ctx = create_hw_context(dev, file_priv); |
498 | mutex_unlock(&dev->struct_mutex); | 499 | mutex_unlock(&dev->struct_mutex); |
500 | if (IS_ERR(ctx)) | ||
501 | return PTR_ERR(ctx); | ||
499 | 502 | ||
500 | args->ctx_id = ctx->id; | 503 | args->ctx_id = ctx->id; |
501 | DRM_DEBUG_DRIVER("HW context %d created\n", args->ctx_id); | 504 | DRM_DEBUG_DRIVER("HW context %d created\n", args->ctx_id); |
502 | 505 | ||
503 | return PTR_RET(ctx); | 506 | return 0; |
504 | } | 507 | } |
505 | 508 | ||
506 | int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, | 509 | int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 88e2e114189c..5af631e788c8 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -885,11 +885,16 @@ i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, | |||
885 | return ret; | 885 | return ret; |
886 | } | 886 | } |
887 | 887 | ||
888 | /* Unconditionally invalidate gpu caches. */ | 888 | /* Unconditionally invalidate gpu caches and ensure that we do flush |
889 | ret = i915_gem_flush_ring(ring, I915_GEM_GPU_DOMAINS, 0); | 889 | * any residual writes from the previous batch. |
890 | */ | ||
891 | ret = i915_gem_flush_ring(ring, | ||
892 | I915_GEM_GPU_DOMAINS, | ||
893 | ring->gpu_caches_dirty ? I915_GEM_GPU_DOMAINS : 0); | ||
890 | if (ret) | 894 | if (ret) |
891 | return ret; | 895 | return ret; |
892 | 896 | ||
897 | ring->gpu_caches_dirty = false; | ||
893 | return 0; | 898 | return 0; |
894 | } | 899 | } |
895 | 900 | ||
@@ -1223,6 +1228,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1223 | } | 1228 | } |
1224 | } | 1229 | } |
1225 | 1230 | ||
1231 | ret = i915_switch_context(ring, file, ctx_id); | ||
1232 | if (ret) | ||
1233 | goto err; | ||
1234 | |||
1226 | if (ring == &dev_priv->ring[RCS] && | 1235 | if (ring == &dev_priv->ring[RCS] && |
1227 | mode != dev_priv->relative_constants_mode) { | 1236 | mode != dev_priv->relative_constants_mode) { |
1228 | ret = intel_ring_begin(ring, 4); | 1237 | ret = intel_ring_begin(ring, 4); |
@@ -1244,10 +1253,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1244 | goto err; | 1253 | goto err; |
1245 | } | 1254 | } |
1246 | 1255 | ||
1247 | ret = i915_switch_context(ring, file, ctx_id); | ||
1248 | if (ret) | ||
1249 | goto err; | ||
1250 | |||
1251 | trace_i915_gem_ring_dispatch(ring, seqno); | 1256 | trace_i915_gem_ring_dispatch(ring, seqno); |
1252 | 1257 | ||
1253 | exec_start = batch_obj->gtt_offset + args->batch_start_offset; | 1258 | exec_start = batch_obj->gtt_offset + args->batch_start_offset; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 05014bc20ee8..8a3828528b9d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1066,6 +1066,7 @@ static void i915_record_ring_state(struct drm_device *dev, | |||
1066 | struct drm_i915_private *dev_priv = dev->dev_private; | 1066 | struct drm_i915_private *dev_priv = dev->dev_private; |
1067 | 1067 | ||
1068 | if (INTEL_INFO(dev)->gen >= 6) { | 1068 | if (INTEL_INFO(dev)->gen >= 6) { |
1069 | error->rc_psmi[ring->id] = I915_READ(ring->mmio_base + 0x50); | ||
1069 | error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); | 1070 | error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); |
1070 | error->semaphore_mboxes[ring->id][0] | 1071 | error->semaphore_mboxes[ring->id][0] |
1071 | = I915_READ(RING_SYNC_0(ring->mmio_base)); | 1072 | = I915_READ(RING_SYNC_0(ring->mmio_base)); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1218069c7f66..acc99b21e0b6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -690,10 +690,10 @@ | |||
690 | #define GEN6_BLITTER_FBC_NOTIFY (1<<3) | 690 | #define GEN6_BLITTER_FBC_NOTIFY (1<<3) |
691 | 691 | ||
692 | #define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050 | 692 | #define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050 |
693 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK (1 << 16) | 693 | #define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0) |
694 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE (1 << 0) | 694 | #define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2) |
695 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE 0 | 695 | #define GEN6_BSD_SLEEP_INDICATOR (1 << 3) |
696 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3) | 696 | #define GEN6_BSD_GO_INDICATOR (1 << 4) |
697 | 697 | ||
698 | #define GEN6_BSD_HWSTAM 0x12098 | 698 | #define GEN6_BSD_HWSTAM 0x12098 |
699 | #define GEN6_BSD_IMR 0x120a8 | 699 | #define GEN6_BSD_IMR 0x120a8 |
@@ -1482,15 +1482,19 @@ | |||
1482 | GEN6_CXT_RENDER_SIZE(cxt_reg) + \ | 1482 | GEN6_CXT_RENDER_SIZE(cxt_reg) + \ |
1483 | GEN6_CXT_EXTENDED_SIZE(cxt_reg) + \ | 1483 | GEN6_CXT_EXTENDED_SIZE(cxt_reg) + \ |
1484 | GEN6_CXT_PIPELINE_SIZE(cxt_reg)) | 1484 | GEN6_CXT_PIPELINE_SIZE(cxt_reg)) |
1485 | #define GEN7_CTX_SIZE 0x21a8 | 1485 | #define GEN7_CXT_SIZE 0x21a8 |
1486 | #define GEN7_CTX_RENDER_SIZE(ctx_reg) ((ctx_reg >> 16) & 0x3f) | 1486 | #define GEN7_CXT_POWER_SIZE(ctx_reg) ((ctx_reg >> 25) & 0x7f) |
1487 | #define GEN7_CTX_EXTENDED_SIZE(ctx_reg) ((ctx_reg >> 9) & 0x7f) | 1487 | #define GEN7_CXT_RING_SIZE(ctx_reg) ((ctx_reg >> 22) & 0x7) |
1488 | #define GEN7_CTX_GT1_SIZE(ctx_reg) ((ctx_reg >> 6) & 0x7) | 1488 | #define GEN7_CXT_RENDER_SIZE(ctx_reg) ((ctx_reg >> 16) & 0x3f) |
1489 | #define GEN7_CTX_VFSTATE_SIZE(ctx_reg) ((ctx_reg >> 0) & 0x3f) | 1489 | #define GEN7_CXT_EXTENDED_SIZE(ctx_reg) ((ctx_reg >> 9) & 0x7f) |
1490 | #define GEN7_CTX_TOTAL_SIZE(ctx_reg) (GEN7_CTX_RENDER_SIZE(ctx_reg) + \ | 1490 | #define GEN7_CXT_GT1_SIZE(ctx_reg) ((ctx_reg >> 6) & 0x7) |
1491 | GEN7_CTX_EXTENDED_SIZE(ctx_reg) + \ | 1491 | #define GEN7_CXT_VFSTATE_SIZE(ctx_reg) ((ctx_reg >> 0) & 0x3f) |
1492 | GEN7_CTX_GT1_SIZE(ctx_reg) + \ | 1492 | #define GEN7_CXT_TOTAL_SIZE(ctx_reg) (GEN7_CXT_POWER_SIZE(ctx_reg) + \ |
1493 | GEN7_CTX_VFSTATE_SIZE(ctx_reg)) | 1493 | GEN7_CXT_RING_SIZE(ctx_reg) + \ |
1494 | GEN7_CXT_RENDER_SIZE(ctx_reg) + \ | ||
1495 | GEN7_CXT_EXTENDED_SIZE(ctx_reg) + \ | ||
1496 | GEN7_CXT_GT1_SIZE(ctx_reg) + \ | ||
1497 | GEN7_CXT_VFSTATE_SIZE(ctx_reg)) | ||
1494 | 1498 | ||
1495 | /* | 1499 | /* |
1496 | * Overlay regs | 1500 | * Overlay regs |
@@ -1896,7 +1900,7 @@ | |||
1896 | /* PCH CTL1 is totally different, all but the below bits are reserved. CTL2 is | 1900 | /* PCH CTL1 is totally different, all but the below bits are reserved. CTL2 is |
1897 | * like the normal CTL from gen4 and earlier. Hooray for confusing naming. */ | 1901 | * like the normal CTL from gen4 and earlier. Hooray for confusing naming. */ |
1898 | #define BLC_PWM_PCH_CTL1 0xc8250 | 1902 | #define BLC_PWM_PCH_CTL1 0xc8250 |
1899 | #define BLM_PCH_PWM_ENABLE (1 << 30) | 1903 | #define BLM_PCH_PWM_ENABLE (1 << 31) |
1900 | #define BLM_PCH_OVERRIDE_ENABLE (1 << 30) | 1904 | #define BLM_PCH_OVERRIDE_ENABLE (1 << 30) |
1901 | #define BLM_PCH_POLARITY (1 << 29) | 1905 | #define BLM_PCH_POLARITY (1 << 29) |
1902 | #define BLC_PWM_PCH_CTL2 0xc8254 | 1906 | #define BLC_PWM_PCH_CTL2 0xc8254 |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 48e3b76e0ab2..7ed4a41c3965 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -330,39 +330,34 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector) | |||
330 | { | 330 | { |
331 | struct intel_crt *crt = intel_attached_crt(connector); | 331 | struct intel_crt *crt = intel_attached_crt(connector); |
332 | struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; | 332 | struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; |
333 | struct edid *edid; | ||
334 | struct i2c_adapter *i2c; | ||
335 | |||
336 | BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG); | ||
333 | 337 | ||
334 | /* CRT should always be at 0, but check anyway */ | 338 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); |
335 | if (crt->base.type != INTEL_OUTPUT_ANALOG) | 339 | edid = drm_get_edid(connector, i2c); |
336 | return false; | ||
337 | 340 | ||
338 | if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { | 341 | if (edid) { |
339 | struct edid *edid; | 342 | bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; |
340 | bool is_digital = false; | ||
341 | struct i2c_adapter *i2c; | ||
342 | 343 | ||
343 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); | ||
344 | edid = drm_get_edid(connector, i2c); | ||
345 | /* | 344 | /* |
346 | * This may be a DVI-I connector with a shared DDC | 345 | * This may be a DVI-I connector with a shared DDC |
347 | * link between analog and digital outputs, so we | 346 | * link between analog and digital outputs, so we |
348 | * have to check the EDID input spec of the attached device. | 347 | * have to check the EDID input spec of the attached device. |
349 | * | ||
350 | * On the other hand, what should we do if it is a broken EDID? | ||
351 | */ | 348 | */ |
352 | if (edid != NULL) { | ||
353 | is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; | ||
354 | connector->display_info.raw_edid = NULL; | ||
355 | kfree(edid); | ||
356 | } | ||
357 | |||
358 | if (!is_digital) { | 349 | if (!is_digital) { |
359 | DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); | 350 | DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); |
360 | return true; | 351 | return true; |
361 | } else { | ||
362 | DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n"); | ||
363 | } | 352 | } |
353 | |||
354 | DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n"); | ||
355 | } else { | ||
356 | DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [no valid EDID found]\n"); | ||
364 | } | 357 | } |
365 | 358 | ||
359 | kfree(edid); | ||
360 | |||
366 | return false; | 361 | return false; |
367 | } | 362 | } |
368 | 363 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bc25a24a08c5..f6159765f1eb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3573,7 +3573,7 @@ void intel_encoder_destroy(struct drm_encoder *encoder) | |||
3573 | } | 3573 | } |
3574 | 3574 | ||
3575 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | 3575 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, |
3576 | struct drm_display_mode *mode, | 3576 | const struct drm_display_mode *mode, |
3577 | struct drm_display_mode *adjusted_mode) | 3577 | struct drm_display_mode *adjusted_mode) |
3578 | { | 3578 | { |
3579 | struct drm_device *dev = crtc->dev; | 3579 | struct drm_device *dev = crtc->dev; |
@@ -6486,7 +6486,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
6486 | intel_fb = to_intel_framebuffer(fb); | 6486 | intel_fb = to_intel_framebuffer(fb); |
6487 | obj = intel_fb->obj; | 6487 | obj = intel_fb->obj; |
6488 | 6488 | ||
6489 | mutex_lock(&dev->struct_mutex); | 6489 | ret = i915_mutex_lock_interruptible(dev); |
6490 | if (ret) | ||
6491 | goto cleanup; | ||
6490 | 6492 | ||
6491 | /* Reference the objects for the scheduled work. */ | 6493 | /* Reference the objects for the scheduled work. */ |
6492 | drm_gem_object_reference(&work->old_fb_obj->base); | 6494 | drm_gem_object_reference(&work->old_fb_obj->base); |
@@ -6521,6 +6523,7 @@ cleanup_pending: | |||
6521 | drm_gem_object_unreference(&obj->base); | 6523 | drm_gem_object_unreference(&obj->base); |
6522 | mutex_unlock(&dev->struct_mutex); | 6524 | mutex_unlock(&dev->struct_mutex); |
6523 | 6525 | ||
6526 | cleanup: | ||
6524 | spin_lock_irqsave(&dev->event_lock, flags); | 6527 | spin_lock_irqsave(&dev->event_lock, flags); |
6525 | intel_crtc->unpin_work = NULL; | 6528 | intel_crtc->unpin_work = NULL; |
6526 | spin_unlock_irqrestore(&dev->event_lock, flags); | 6529 | spin_unlock_irqrestore(&dev->event_lock, flags); |
@@ -7174,6 +7177,11 @@ static void i915_disable_vga(struct drm_device *dev) | |||
7174 | 7177 | ||
7175 | void intel_modeset_init_hw(struct drm_device *dev) | 7178 | void intel_modeset_init_hw(struct drm_device *dev) |
7176 | { | 7179 | { |
7180 | /* We attempt to init the necessary power wells early in the initialization | ||
7181 | * time, so the subsystems that expect power to be enabled can work. | ||
7182 | */ | ||
7183 | intel_init_power_wells(dev); | ||
7184 | |||
7177 | intel_prepare_ddi(dev); | 7185 | intel_prepare_ddi(dev); |
7178 | 7186 | ||
7179 | intel_init_clock_gating(dev); | 7187 | intel_init_clock_gating(dev); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2bc1505132c3..0a56b9ab0f58 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1771,7 +1771,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1771 | for (i = 0; i < intel_dp->lane_count; i++) | 1771 | for (i = 0; i < intel_dp->lane_count; i++) |
1772 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1772 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
1773 | break; | 1773 | break; |
1774 | if (i == intel_dp->lane_count) { | 1774 | if (i == intel_dp->lane_count && voltage_tries == 5) { |
1775 | ++loop_tries; | 1775 | ++loop_tries; |
1776 | if (loop_tries == 5) { | 1776 | if (loop_tries == 5) { |
1777 | DRM_DEBUG_KMS("too many full retries, give up\n"); | 1777 | DRM_DEBUG_KMS("too many full retries, give up\n"); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b7859e7110a7..84353559441c 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -342,7 +342,6 @@ struct intel_fbc_work { | |||
342 | }; | 342 | }; |
343 | 343 | ||
344 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); | 344 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); |
345 | extern bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus); | ||
346 | 345 | ||
347 | extern void intel_attach_force_audio_property(struct drm_connector *connector); | 346 | extern void intel_attach_force_audio_property(struct drm_connector *connector); |
348 | extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector); | 347 | extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector); |
@@ -496,6 +495,7 @@ extern void intel_update_fbc(struct drm_device *dev); | |||
496 | extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv); | 495 | extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv); |
497 | extern void intel_gpu_ips_teardown(void); | 496 | extern void intel_gpu_ips_teardown(void); |
498 | 497 | ||
498 | extern void intel_init_power_wells(struct drm_device *dev); | ||
499 | extern void intel_enable_gt_powersave(struct drm_device *dev); | 499 | extern void intel_enable_gt_powersave(struct drm_device *dev); |
500 | extern void intel_disable_gt_powersave(struct drm_device *dev); | 500 | extern void intel_disable_gt_powersave(struct drm_device *dev); |
501 | extern void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv); | 501 | extern void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 49f09a8b05e9..e05c0d3e3440 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -409,13 +409,7 @@ static void intel_lvds_prepare(struct drm_encoder *encoder) | |||
409 | { | 409 | { |
410 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | 410 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
411 | 411 | ||
412 | /* | 412 | intel_lvds_disable(intel_lvds); |
413 | * Prior to Ironlake, we must disable the pipe if we want to adjust | ||
414 | * the panel fitter. However at all other times we can just reset | ||
415 | * the registers regardless. | ||
416 | */ | ||
417 | if (!HAS_PCH_SPLIT(encoder->dev) && intel_lvds->pfit_dirty) | ||
418 | intel_lvds_disable(intel_lvds); | ||
419 | } | 413 | } |
420 | 414 | ||
421 | static void intel_lvds_commit(struct drm_encoder *encoder) | 415 | static void intel_lvds_commit(struct drm_encoder *encoder) |
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index d67ec3a51e42..45848b9b670b 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c | |||
@@ -33,34 +33,6 @@ | |||
33 | #include "i915_drv.h" | 33 | #include "i915_drv.h" |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * intel_ddc_probe | ||
37 | * | ||
38 | */ | ||
39 | bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus) | ||
40 | { | ||
41 | struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private; | ||
42 | u8 out_buf[] = { 0x0, 0x0}; | ||
43 | u8 buf[2]; | ||
44 | struct i2c_msg msgs[] = { | ||
45 | { | ||
46 | .addr = DDC_ADDR, | ||
47 | .flags = 0, | ||
48 | .len = 1, | ||
49 | .buf = out_buf, | ||
50 | }, | ||
51 | { | ||
52 | .addr = DDC_ADDR, | ||
53 | .flags = I2C_M_RD, | ||
54 | .len = 1, | ||
55 | .buf = buf, | ||
56 | } | ||
57 | }; | ||
58 | |||
59 | return i2c_transfer(intel_gmbus_get_adapter(dev_priv, ddc_bus), | ||
60 | msgs, 2) == 2; | ||
61 | } | ||
62 | |||
63 | /** | ||
64 | * intel_ddc_get_modes - get modelist from monitor | 36 | * intel_ddc_get_modes - get modelist from monitor |
65 | * @connector: DRM connector device to use | 37 | * @connector: DRM connector device to use |
66 | * @adapter: i2c adapter | 38 | * @adapter: i2c adapter |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 58c7ee7238b8..10c7d39034e1 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -289,11 +289,17 @@ void intel_panel_disable_backlight(struct drm_device *dev) | |||
289 | intel_panel_actually_set_backlight(dev, 0); | 289 | intel_panel_actually_set_backlight(dev, 0); |
290 | 290 | ||
291 | if (INTEL_INFO(dev)->gen >= 4) { | 291 | if (INTEL_INFO(dev)->gen >= 4) { |
292 | uint32_t reg; | 292 | uint32_t reg, tmp; |
293 | 293 | ||
294 | reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2; | 294 | reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2; |
295 | 295 | ||
296 | I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE); | 296 | I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE); |
297 | |||
298 | if (HAS_PCH_SPLIT(dev)) { | ||
299 | tmp = I915_READ(BLC_PWM_PCH_CTL1); | ||
300 | tmp &= ~BLM_PCH_PWM_ENABLE; | ||
301 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); | ||
302 | } | ||
297 | } | 303 | } |
298 | } | 304 | } |
299 | 305 | ||
@@ -333,6 +339,13 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
333 | I915_WRITE(reg, tmp); | 339 | I915_WRITE(reg, tmp); |
334 | POSTING_READ(reg); | 340 | POSTING_READ(reg); |
335 | I915_WRITE(reg, tmp | BLM_PWM_ENABLE); | 341 | I915_WRITE(reg, tmp | BLM_PWM_ENABLE); |
342 | |||
343 | if (HAS_PCH_SPLIT(dev)) { | ||
344 | tmp = I915_READ(BLC_PWM_PCH_CTL1); | ||
345 | tmp |= BLM_PCH_PWM_ENABLE; | ||
346 | tmp &= ~BLM_PCH_OVERRIDE_ENABLE; | ||
347 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); | ||
348 | } | ||
336 | } | 349 | } |
337 | } | 350 | } |
338 | 351 | ||
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0bb69fd255a9..94aabcaa3a67 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -2491,14 +2491,7 @@ static void gen6_enable_rps(struct drm_device *dev) | |||
2491 | gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8); | 2491 | gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8); |
2492 | 2492 | ||
2493 | /* requires MSI enabled */ | 2493 | /* requires MSI enabled */ |
2494 | I915_WRITE(GEN6_PMIER, | 2494 | I915_WRITE(GEN6_PMIER, GEN6_PM_DEFERRED_EVENTS); |
2495 | GEN6_PM_MBOX_EVENT | | ||
2496 | GEN6_PM_THERMAL_EVENT | | ||
2497 | GEN6_PM_RP_DOWN_TIMEOUT | | ||
2498 | GEN6_PM_RP_UP_THRESHOLD | | ||
2499 | GEN6_PM_RP_DOWN_THRESHOLD | | ||
2500 | GEN6_PM_RP_UP_EI_EXPIRED | | ||
2501 | GEN6_PM_RP_DOWN_EI_EXPIRED); | ||
2502 | spin_lock_irq(&dev_priv->rps_lock); | 2495 | spin_lock_irq(&dev_priv->rps_lock); |
2503 | WARN_ON(dev_priv->pm_iir != 0); | 2496 | WARN_ON(dev_priv->pm_iir != 0); |
2504 | I915_WRITE(GEN6_PMIMR, 0); | 2497 | I915_WRITE(GEN6_PMIMR, 0); |
@@ -3939,11 +3932,6 @@ void intel_init_pm(struct drm_device *dev) | |||
3939 | else | 3932 | else |
3940 | dev_priv->display.get_fifo_size = i830_get_fifo_size; | 3933 | dev_priv->display.get_fifo_size = i830_get_fifo_size; |
3941 | } | 3934 | } |
3942 | |||
3943 | /* We attempt to init the necessary power wells early in the initialization | ||
3944 | * time, so the subsystems that expect power to be enabled can work. | ||
3945 | */ | ||
3946 | intel_init_power_wells(dev); | ||
3947 | } | 3935 | } |
3948 | 3936 | ||
3949 | static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) | 3937 | static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv) |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index d42d821c64d6..bf0195a96d53 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -972,6 +972,7 @@ static int init_status_page(struct intel_ring_buffer *ring) | |||
972 | ring->status_page.gfx_addr = obj->gtt_offset; | 972 | ring->status_page.gfx_addr = obj->gtt_offset; |
973 | ring->status_page.page_addr = kmap(obj->pages[0]); | 973 | ring->status_page.page_addr = kmap(obj->pages[0]); |
974 | if (ring->status_page.page_addr == NULL) { | 974 | if (ring->status_page.page_addr == NULL) { |
975 | ret = -ENOMEM; | ||
975 | goto err_unpin; | 976 | goto err_unpin; |
976 | } | 977 | } |
977 | ring->status_page.obj = obj; | 978 | ring->status_page.obj = obj; |
@@ -1270,20 +1271,31 @@ static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, | |||
1270 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 1271 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1271 | 1272 | ||
1272 | /* Every tail move must follow the sequence below */ | 1273 | /* Every tail move must follow the sequence below */ |
1274 | |||
1275 | /* Disable notification that the ring is IDLE. The GT | ||
1276 | * will then assume that it is busy and bring it out of rc6. | ||
1277 | */ | ||
1273 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, | 1278 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, |
1274 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK | | 1279 | _MASKED_BIT_ENABLE(GEN6_BSD_SLEEP_MSG_DISABLE)); |
1275 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE); | ||
1276 | I915_WRITE(GEN6_BSD_RNCID, 0x0); | ||
1277 | 1280 | ||
1281 | /* Clear the context id. Here be magic! */ | ||
1282 | I915_WRITE64(GEN6_BSD_RNCID, 0x0); | ||
1283 | |||
1284 | /* Wait for the ring not to be idle, i.e. for it to wake up. */ | ||
1278 | if (wait_for((I915_READ(GEN6_BSD_SLEEP_PSMI_CONTROL) & | 1285 | if (wait_for((I915_READ(GEN6_BSD_SLEEP_PSMI_CONTROL) & |
1279 | GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR) == 0, | 1286 | GEN6_BSD_SLEEP_INDICATOR) == 0, |
1280 | 50)) | 1287 | 50)) |
1281 | DRM_ERROR("timed out waiting for IDLE Indicator\n"); | 1288 | DRM_ERROR("timed out waiting for the BSD ring to wake up\n"); |
1282 | 1289 | ||
1290 | /* Now that the ring is fully powered up, update the tail */ | ||
1283 | I915_WRITE_TAIL(ring, value); | 1291 | I915_WRITE_TAIL(ring, value); |
1292 | POSTING_READ(RING_TAIL(ring->mmio_base)); | ||
1293 | |||
1294 | /* Let the ring send IDLE messages to the GT again, | ||
1295 | * and so let it sleep to conserve power when idle. | ||
1296 | */ | ||
1284 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, | 1297 | I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, |
1285 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK | | 1298 | _MASKED_BIT_DISABLE(GEN6_BSD_SLEEP_MSG_DISABLE)); |
1286 | GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); | ||
1287 | } | 1299 | } |
1288 | 1300 | ||
1289 | static int gen6_ring_flush(struct intel_ring_buffer *ring, | 1301 | static int gen6_ring_flush(struct intel_ring_buffer *ring, |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 1a1483b924d0..cc8df4de2d92 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -234,6 +234,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
234 | dvscntr &= ~DVS_PIXFORMAT_MASK; | 234 | dvscntr &= ~DVS_PIXFORMAT_MASK; |
235 | dvscntr &= ~DVS_RGB_ORDER_XBGR; | 235 | dvscntr &= ~DVS_RGB_ORDER_XBGR; |
236 | dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; | 236 | dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; |
237 | dvscntr &= ~DVS_TILED; | ||
237 | 238 | ||
238 | switch (fb->pixel_format) { | 239 | switch (fb->pixel_format) { |
239 | case DRM_FORMAT_XBGR8888: | 240 | case DRM_FORMAT_XBGR8888: |