diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/drm_edid.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_context.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_tiling.c | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 16 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 52 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 73 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 5 |
10 files changed, 118 insertions, 57 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 5dda07cf7097..fadcd44ff196 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
| @@ -395,13 +395,14 @@ out: | |||
| 395 | * \param adapter : i2c device adaptor | 395 | * \param adapter : i2c device adaptor |
| 396 | * \return 1 on success | 396 | * \return 1 on success |
| 397 | */ | 397 | */ |
| 398 | static bool | 398 | bool |
| 399 | drm_probe_ddc(struct i2c_adapter *adapter) | 399 | drm_probe_ddc(struct i2c_adapter *adapter) |
| 400 | { | 400 | { |
| 401 | unsigned char out; | 401 | unsigned char out; |
| 402 | 402 | ||
| 403 | return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0); | 403 | return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0); |
| 404 | } | 404 | } |
| 405 | EXPORT_SYMBOL(drm_probe_ddc); | ||
| 405 | 406 | ||
| 406 | /** | 407 | /** |
| 407 | * drm_get_edid - get EDID data, if available | 408 | * drm_get_edid - get EDID data, if available |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e957f3740f68..19dbdd7dd564 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -1399,10 +1399,16 @@ out: | |||
| 1399 | case 0: | 1399 | case 0: |
| 1400 | case -ERESTARTSYS: | 1400 | case -ERESTARTSYS: |
| 1401 | case -EINTR: | 1401 | case -EINTR: |
| 1402 | case -EBUSY: | ||
| 1403 | /* | ||
| 1404 | * EBUSY is ok: this just means that another thread | ||
| 1405 | * already did the job. | ||
| 1406 | */ | ||
| 1402 | return VM_FAULT_NOPAGE; | 1407 | return VM_FAULT_NOPAGE; |
| 1403 | case -ENOMEM: | 1408 | case -ENOMEM: |
| 1404 | return VM_FAULT_OOM; | 1409 | return VM_FAULT_OOM; |
| 1405 | default: | 1410 | default: |
| 1411 | WARN_ON_ONCE(ret); | ||
| 1406 | return VM_FAULT_SIGBUS; | 1412 | return VM_FAULT_SIGBUS; |
| 1407 | } | 1413 | } |
| 1408 | } | 1414 | } |
| @@ -3217,10 +3223,6 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, | |||
| 3217 | enum i915_cache_level level; | 3223 | enum i915_cache_level level; |
| 3218 | int ret; | 3224 | int ret; |
| 3219 | 3225 | ||
| 3220 | ret = i915_mutex_lock_interruptible(dev); | ||
| 3221 | if (ret) | ||
| 3222 | return ret; | ||
| 3223 | |||
| 3224 | switch (args->caching) { | 3226 | switch (args->caching) { |
| 3225 | case I915_CACHING_NONE: | 3227 | case I915_CACHING_NONE: |
| 3226 | level = I915_CACHE_NONE; | 3228 | level = I915_CACHE_NONE; |
| @@ -3232,6 +3234,10 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, | |||
| 3232 | return -EINVAL; | 3234 | return -EINVAL; |
| 3233 | } | 3235 | } |
| 3234 | 3236 | ||
| 3237 | ret = i915_mutex_lock_interruptible(dev); | ||
| 3238 | if (ret) | ||
| 3239 | return ret; | ||
| 3240 | |||
| 3235 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); | 3241 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
| 3236 | if (&obj->base == NULL) { | 3242 | if (&obj->base == NULL) { |
| 3237 | ret = -ENOENT; | 3243 | ret = -ENOENT; |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 1eb48faf741b..05ed42f203d7 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
| @@ -328,7 +328,7 @@ mi_set_context(struct intel_ring_buffer *ring, | |||
| 328 | * itlb_before_ctx_switch. | 328 | * itlb_before_ctx_switch. |
| 329 | */ | 329 | */ |
| 330 | if (IS_GEN6(ring->dev) && ring->itlb_before_ctx_switch) { | 330 | if (IS_GEN6(ring->dev) && ring->itlb_before_ctx_switch) { |
| 331 | ret = ring->flush(ring, 0, 0); | 331 | ret = ring->flush(ring, I915_GEM_GPU_DOMAINS, 0); |
| 332 | if (ret) | 332 | if (ret) |
| 333 | return ret; | 333 | return ret; |
| 334 | } | 334 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 3208650a235c..cedbfd7b3dfa 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
| @@ -91,7 +91,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | |||
| 91 | uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; | 91 | uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; |
| 92 | uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | 92 | uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; |
| 93 | 93 | ||
| 94 | if (INTEL_INFO(dev)->gen >= 6) { | 94 | if (IS_VALLEYVIEW(dev)) { |
| 95 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
| 96 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
| 97 | } else if (INTEL_INFO(dev)->gen >= 6) { | ||
| 95 | uint32_t dimm_c0, dimm_c1; | 98 | uint32_t dimm_c0, dimm_c1; |
| 96 | dimm_c0 = I915_READ(MAD_DIMM_C0); | 99 | dimm_c0 = I915_READ(MAD_DIMM_C0); |
| 97 | dimm_c1 = I915_READ(MAD_DIMM_C1); | 100 | dimm_c1 = I915_READ(MAD_DIMM_C1); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4e9888388c0c..32e1bda865b8 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -697,12 +697,12 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) | |||
| 697 | intel_opregion_gse_intr(dev); | 697 | intel_opregion_gse_intr(dev); |
| 698 | 698 | ||
| 699 | for (i = 0; i < 3; i++) { | 699 | for (i = 0; i < 3; i++) { |
| 700 | if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i))) | ||
| 701 | drm_handle_vblank(dev, i); | ||
| 700 | if (de_iir & (DE_PLANEA_FLIP_DONE_IVB << (5 * i))) { | 702 | if (de_iir & (DE_PLANEA_FLIP_DONE_IVB << (5 * i))) { |
| 701 | intel_prepare_page_flip(dev, i); | 703 | intel_prepare_page_flip(dev, i); |
| 702 | intel_finish_page_flip_plane(dev, i); | 704 | intel_finish_page_flip_plane(dev, i); |
| 703 | } | 705 | } |
| 704 | if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i))) | ||
| 705 | drm_handle_vblank(dev, i); | ||
| 706 | } | 706 | } |
| 707 | 707 | ||
| 708 | /* check event from PCH */ | 708 | /* check event from PCH */ |
| @@ -784,6 +784,12 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) | |||
| 784 | if (de_iir & DE_GSE) | 784 | if (de_iir & DE_GSE) |
| 785 | intel_opregion_gse_intr(dev); | 785 | intel_opregion_gse_intr(dev); |
| 786 | 786 | ||
| 787 | if (de_iir & DE_PIPEA_VBLANK) | ||
| 788 | drm_handle_vblank(dev, 0); | ||
| 789 | |||
| 790 | if (de_iir & DE_PIPEB_VBLANK) | ||
| 791 | drm_handle_vblank(dev, 1); | ||
| 792 | |||
| 787 | if (de_iir & DE_PLANEA_FLIP_DONE) { | 793 | if (de_iir & DE_PLANEA_FLIP_DONE) { |
| 788 | intel_prepare_page_flip(dev, 0); | 794 | intel_prepare_page_flip(dev, 0); |
| 789 | intel_finish_page_flip_plane(dev, 0); | 795 | intel_finish_page_flip_plane(dev, 0); |
| @@ -794,12 +800,6 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) | |||
| 794 | intel_finish_page_flip_plane(dev, 1); | 800 | intel_finish_page_flip_plane(dev, 1); |
| 795 | } | 801 | } |
| 796 | 802 | ||
| 797 | if (de_iir & DE_PIPEA_VBLANK) | ||
| 798 | drm_handle_vblank(dev, 0); | ||
| 799 | |||
| 800 | if (de_iir & DE_PIPEB_VBLANK) | ||
| 801 | drm_handle_vblank(dev, 1); | ||
| 802 | |||
| 803 | /* check event from PCH */ | 803 | /* check event from PCH */ |
| 804 | if (de_iir & DE_PCH_EVENT) { | 804 | if (de_iir & DE_PCH_EVENT) { |
| 805 | if (pch_iir & hotplug_mask) | 805 | if (pch_iir & hotplug_mask) |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7637824c6a7d..64c1be0a9cfd 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -527,6 +527,9 @@ | |||
| 527 | # define VS_TIMER_DISPATCH (1 << 6) | 527 | # define VS_TIMER_DISPATCH (1 << 6) |
| 528 | # define MI_FLUSH_ENABLE (1 << 12) | 528 | # define MI_FLUSH_ENABLE (1 << 12) |
| 529 | 529 | ||
| 530 | #define GEN6_GT_MODE 0x20d0 | ||
| 531 | #define GEN6_GT_MODE_HI (1 << 9) | ||
| 532 | |||
| 530 | #define GFX_MODE 0x02520 | 533 | #define GFX_MODE 0x02520 |
| 531 | #define GFX_MODE_GEN7 0x0229c | 534 | #define GFX_MODE_GEN7 0x0229c |
| 532 | #define RING_MODE_GEN7(ring) ((ring)->mmio_base+0x29c) | 535 | #define RING_MODE_GEN7(ring) ((ring)->mmio_base+0x29c) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e3c02655d36f..2b6ce9b2674a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -2806,13 +2806,34 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc) | |||
| 2806 | udelay(100); | 2806 | udelay(100); |
| 2807 | } | 2807 | } |
| 2808 | 2808 | ||
| 2809 | static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) | ||
| 2810 | { | ||
| 2811 | struct drm_device *dev = crtc->dev; | ||
| 2812 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 2813 | unsigned long flags; | ||
| 2814 | bool pending; | ||
| 2815 | |||
| 2816 | if (atomic_read(&dev_priv->mm.wedged)) | ||
| 2817 | return false; | ||
| 2818 | |||
| 2819 | spin_lock_irqsave(&dev->event_lock, flags); | ||
| 2820 | pending = to_intel_crtc(crtc)->unpin_work != NULL; | ||
| 2821 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 2822 | |||
| 2823 | return pending; | ||
| 2824 | } | ||
| 2825 | |||
| 2809 | static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) | 2826 | static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) |
| 2810 | { | 2827 | { |
| 2811 | struct drm_device *dev = crtc->dev; | 2828 | struct drm_device *dev = crtc->dev; |
| 2829 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 2812 | 2830 | ||
| 2813 | if (crtc->fb == NULL) | 2831 | if (crtc->fb == NULL) |
| 2814 | return; | 2832 | return; |
| 2815 | 2833 | ||
| 2834 | wait_event(dev_priv->pending_flip_queue, | ||
| 2835 | !intel_crtc_has_pending_flip(crtc)); | ||
| 2836 | |||
| 2816 | mutex_lock(&dev->struct_mutex); | 2837 | mutex_lock(&dev->struct_mutex); |
| 2817 | intel_finish_fb(crtc->fb); | 2838 | intel_finish_fb(crtc->fb); |
| 2818 | mutex_unlock(&dev->struct_mutex); | 2839 | mutex_unlock(&dev->struct_mutex); |
| @@ -4370,7 +4391,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4370 | /* default to 8bpc */ | 4391 | /* default to 8bpc */ |
| 4371 | pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN); | 4392 | pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN); |
| 4372 | if (is_dp) { | 4393 | if (is_dp) { |
| 4373 | if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) { | 4394 | if (adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) { |
| 4374 | pipeconf |= PIPECONF_BPP_6 | | 4395 | pipeconf |= PIPECONF_BPP_6 | |
| 4375 | PIPECONF_DITHER_EN | | 4396 | PIPECONF_DITHER_EN | |
| 4376 | PIPECONF_DITHER_TYPE_SP; | 4397 | PIPECONF_DITHER_TYPE_SP; |
| @@ -4802,7 +4823,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4802 | target_clock = adjusted_mode->clock; | 4823 | target_clock = adjusted_mode->clock; |
| 4803 | 4824 | ||
| 4804 | /* determine panel color depth */ | 4825 | /* determine panel color depth */ |
| 4805 | dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp, mode); | 4826 | dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp, |
| 4827 | adjusted_mode); | ||
| 4806 | if (is_lvds && dev_priv->lvds_dither) | 4828 | if (is_lvds && dev_priv->lvds_dither) |
| 4807 | dither = true; | 4829 | dither = true; |
| 4808 | 4830 | ||
| @@ -6159,15 +6181,13 @@ static void do_intel_finish_page_flip(struct drm_device *dev, | |||
| 6159 | struct intel_unpin_work *work; | 6181 | struct intel_unpin_work *work; |
| 6160 | struct drm_i915_gem_object *obj; | 6182 | struct drm_i915_gem_object *obj; |
| 6161 | struct drm_pending_vblank_event *e; | 6183 | struct drm_pending_vblank_event *e; |
| 6162 | struct timeval tnow, tvbl; | 6184 | struct timeval tvbl; |
| 6163 | unsigned long flags; | 6185 | unsigned long flags; |
| 6164 | 6186 | ||
| 6165 | /* Ignore early vblank irqs */ | 6187 | /* Ignore early vblank irqs */ |
| 6166 | if (intel_crtc == NULL) | 6188 | if (intel_crtc == NULL) |
| 6167 | return; | 6189 | return; |
| 6168 | 6190 | ||
| 6169 | do_gettimeofday(&tnow); | ||
| 6170 | |||
| 6171 | spin_lock_irqsave(&dev->event_lock, flags); | 6191 | spin_lock_irqsave(&dev->event_lock, flags); |
| 6172 | work = intel_crtc->unpin_work; | 6192 | work = intel_crtc->unpin_work; |
| 6173 | if (work == NULL || !work->pending) { | 6193 | if (work == NULL || !work->pending) { |
| @@ -6181,25 +6201,6 @@ static void do_intel_finish_page_flip(struct drm_device *dev, | |||
| 6181 | e = work->event; | 6201 | e = work->event; |
| 6182 | e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &tvbl); | 6202 | e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &tvbl); |
| 6183 | 6203 | ||
| 6184 | /* Called before vblank count and timestamps have | ||
| 6185 | * been updated for the vblank interval of flip | ||
| 6186 | * completion? Need to increment vblank count and | ||
| 6187 | * add one videorefresh duration to returned timestamp | ||
| 6188 | * to account for this. We assume this happened if we | ||
| 6189 | * get called over 0.9 frame durations after the last | ||
| 6190 | * timestamped vblank. | ||
| 6191 | * | ||
| 6192 | * This calculation can not be used with vrefresh rates | ||
| 6193 | * below 5Hz (10Hz to be on the safe side) without | ||
| 6194 | * promoting to 64 integers. | ||
| 6195 | */ | ||
| 6196 | if (10 * (timeval_to_ns(&tnow) - timeval_to_ns(&tvbl)) > | ||
| 6197 | 9 * crtc->framedur_ns) { | ||
| 6198 | e->event.sequence++; | ||
| 6199 | tvbl = ns_to_timeval(timeval_to_ns(&tvbl) + | ||
| 6200 | crtc->framedur_ns); | ||
| 6201 | } | ||
| 6202 | |||
| 6203 | e->event.tv_sec = tvbl.tv_sec; | 6204 | e->event.tv_sec = tvbl.tv_sec; |
| 6204 | e->event.tv_usec = tvbl.tv_usec; | 6205 | e->event.tv_usec = tvbl.tv_usec; |
| 6205 | 6206 | ||
| @@ -6216,9 +6217,8 @@ static void do_intel_finish_page_flip(struct drm_device *dev, | |||
| 6216 | 6217 | ||
| 6217 | atomic_clear_mask(1 << intel_crtc->plane, | 6218 | atomic_clear_mask(1 << intel_crtc->plane, |
| 6218 | &obj->pending_flip.counter); | 6219 | &obj->pending_flip.counter); |
| 6219 | if (atomic_read(&obj->pending_flip) == 0) | ||
| 6220 | wake_up(&dev_priv->pending_flip_queue); | ||
| 6221 | 6220 | ||
| 6221 | wake_up(&dev_priv->pending_flip_queue); | ||
| 6222 | schedule_work(&work->work); | 6222 | schedule_work(&work->work); |
| 6223 | 6223 | ||
| 6224 | trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); | 6224 | trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6c8746c030c7..d1e8ddb2d6c0 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <drm/i915_drm.h> | 36 | #include <drm/i915_drm.h> |
| 37 | #include "i915_drv.h" | 37 | #include "i915_drv.h" |
| 38 | 38 | ||
| 39 | #define DP_RECEIVER_CAP_SIZE 0xf | ||
| 39 | #define DP_LINK_STATUS_SIZE 6 | 40 | #define DP_LINK_STATUS_SIZE 6 |
| 40 | #define DP_LINK_CHECK_TIMEOUT (10 * 1000) | 41 | #define DP_LINK_CHECK_TIMEOUT (10 * 1000) |
| 41 | 42 | ||
| @@ -1796,8 +1797,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
| 1796 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1797 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
| 1797 | break; | 1798 | break; |
| 1798 | if (i == intel_dp->lane_count && voltage_tries == 5) { | 1799 | if (i == intel_dp->lane_count && voltage_tries == 5) { |
| 1799 | ++loop_tries; | 1800 | if (++loop_tries == 5) { |
| 1800 | if (loop_tries == 5) { | ||
| 1801 | DRM_DEBUG_KMS("too many full retries, give up\n"); | 1801 | DRM_DEBUG_KMS("too many full retries, give up\n"); |
| 1802 | break; | 1802 | break; |
| 1803 | } | 1803 | } |
| @@ -1807,15 +1807,11 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
| 1807 | } | 1807 | } |
| 1808 | 1808 | ||
| 1809 | /* Check to see if we've tried the same voltage 5 times */ | 1809 | /* Check to see if we've tried the same voltage 5 times */ |
| 1810 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { | 1810 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) { |
| 1811 | ++voltage_tries; | 1811 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; |
| 1812 | if (voltage_tries == 5) { | ||
| 1813 | DRM_DEBUG_KMS("too many voltage retries, give up\n"); | ||
| 1814 | break; | ||
| 1815 | } | ||
| 1816 | } else | ||
| 1817 | voltage_tries = 0; | 1812 | voltage_tries = 0; |
| 1818 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | 1813 | } else |
| 1814 | ++voltage_tries; | ||
| 1819 | 1815 | ||
| 1820 | /* Compute new intel_dp->train_set as requested by target */ | 1816 | /* Compute new intel_dp->train_set as requested by target */ |
| 1821 | intel_get_adjust_train(intel_dp, link_status); | 1817 | intel_get_adjust_train(intel_dp, link_status); |
| @@ -1963,12 +1959,25 @@ static bool | |||
| 1963 | intel_dp_get_dpcd(struct intel_dp *intel_dp) | 1959 | intel_dp_get_dpcd(struct intel_dp *intel_dp) |
| 1964 | { | 1960 | { |
| 1965 | if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd, | 1961 | if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd, |
| 1966 | sizeof(intel_dp->dpcd)) && | 1962 | sizeof(intel_dp->dpcd)) == 0) |
| 1967 | (intel_dp->dpcd[DP_DPCD_REV] != 0)) { | 1963 | return false; /* aux transfer failed */ |
| 1968 | return true; | ||
| 1969 | } | ||
| 1970 | 1964 | ||
| 1971 | return false; | 1965 | if (intel_dp->dpcd[DP_DPCD_REV] == 0) |
| 1966 | return false; /* DPCD not present */ | ||
| 1967 | |||
| 1968 | if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & | ||
| 1969 | DP_DWN_STRM_PORT_PRESENT)) | ||
| 1970 | return true; /* native DP sink */ | ||
| 1971 | |||
| 1972 | if (intel_dp->dpcd[DP_DPCD_REV] == 0x10) | ||
| 1973 | return true; /* no per-port downstream info */ | ||
| 1974 | |||
| 1975 | if (intel_dp_aux_native_read_retry(intel_dp, DP_DOWNSTREAM_PORT_0, | ||
| 1976 | intel_dp->downstream_ports, | ||
| 1977 | DP_MAX_DOWNSTREAM_PORTS) == 0) | ||
| 1978 | return false; /* downstream port status fetch failed */ | ||
| 1979 | |||
| 1980 | return true; | ||
| 1972 | } | 1981 | } |
| 1973 | 1982 | ||
| 1974 | static void | 1983 | static void |
| @@ -2068,11 +2077,43 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
| 2068 | } | 2077 | } |
| 2069 | } | 2078 | } |
| 2070 | 2079 | ||
| 2080 | /* XXX this is probably wrong for multiple downstream ports */ | ||
| 2071 | static enum drm_connector_status | 2081 | static enum drm_connector_status |
| 2072 | intel_dp_detect_dpcd(struct intel_dp *intel_dp) | 2082 | intel_dp_detect_dpcd(struct intel_dp *intel_dp) |
| 2073 | { | 2083 | { |
| 2074 | if (intel_dp_get_dpcd(intel_dp)) | 2084 | uint8_t *dpcd = intel_dp->dpcd; |
| 2085 | bool hpd; | ||
| 2086 | uint8_t type; | ||
| 2087 | |||
| 2088 | if (!intel_dp_get_dpcd(intel_dp)) | ||
| 2089 | return connector_status_disconnected; | ||
| 2090 | |||
| 2091 | /* if there's no downstream port, we're done */ | ||
| 2092 | if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT)) | ||
| 2093 | return connector_status_connected; | ||
| 2094 | |||
| 2095 | /* If we're HPD-aware, SINK_COUNT changes dynamically */ | ||
| 2096 | hpd = !!(intel_dp->downstream_ports[0] & DP_DS_PORT_HPD); | ||
| 2097 | if (hpd) { | ||
| 2098 | uint8_t reg; | ||
| 2099 | if (!intel_dp_aux_native_read_retry(intel_dp, DP_SINK_COUNT, | ||
| 2100 | ®, 1)) | ||
| 2101 | return connector_status_unknown; | ||
| 2102 | return DP_GET_SINK_COUNT(reg) ? connector_status_connected | ||
| 2103 | : connector_status_disconnected; | ||
| 2104 | } | ||
| 2105 | |||
| 2106 | /* If no HPD, poke DDC gently */ | ||
| 2107 | if (drm_probe_ddc(&intel_dp->adapter)) | ||
| 2075 | return connector_status_connected; | 2108 | return connector_status_connected; |
| 2109 | |||
| 2110 | /* Well we tried, say unknown for unreliable port types */ | ||
| 2111 | type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK; | ||
| 2112 | if (type == DP_DS_PORT_TYPE_VGA || type == DP_DS_PORT_TYPE_NON_EDID) | ||
| 2113 | return connector_status_unknown; | ||
| 2114 | |||
| 2115 | /* Anything else is out of spec, warn and ignore */ | ||
| 2116 | DRM_DEBUG_KMS("Broken DP branch device, ignoring\n"); | ||
| 2076 | return connector_status_disconnected; | 2117 | return connector_status_disconnected; |
| 2077 | } | 2118 | } |
| 2078 | 2119 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 05cc7c372fc5..fe7142502f43 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -332,6 +332,7 @@ struct intel_hdmi { | |||
| 332 | }; | 332 | }; |
| 333 | 333 | ||
| 334 | #define DP_RECEIVER_CAP_SIZE 0xf | 334 | #define DP_RECEIVER_CAP_SIZE 0xf |
| 335 | #define DP_MAX_DOWNSTREAM_PORTS 0x10 | ||
| 335 | #define DP_LINK_CONFIGURATION_SIZE 9 | 336 | #define DP_LINK_CONFIGURATION_SIZE 9 |
| 336 | 337 | ||
| 337 | struct intel_dp { | 338 | struct intel_dp { |
| @@ -346,6 +347,7 @@ struct intel_dp { | |||
| 346 | uint8_t link_bw; | 347 | uint8_t link_bw; |
| 347 | uint8_t lane_count; | 348 | uint8_t lane_count; |
| 348 | uint8_t dpcd[DP_RECEIVER_CAP_SIZE]; | 349 | uint8_t dpcd[DP_RECEIVER_CAP_SIZE]; |
| 350 | uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS]; | ||
| 349 | struct i2c_adapter adapter; | 351 | struct i2c_adapter adapter; |
| 350 | struct i2c_algo_dp_aux_data algo; | 352 | struct i2c_algo_dp_aux_data algo; |
| 351 | bool is_pch_edp; | 353 | bool is_pch_edp; |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d69f8f49beb5..b3b4b6cea8b0 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -3474,6 +3474,11 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
| 3474 | DISPPLANE_TRICKLE_FEED_DISABLE); | 3474 | DISPPLANE_TRICKLE_FEED_DISABLE); |
| 3475 | intel_flush_display_plane(dev_priv, pipe); | 3475 | intel_flush_display_plane(dev_priv, pipe); |
| 3476 | } | 3476 | } |
| 3477 | |||
| 3478 | /* The default value should be 0x200 according to docs, but the two | ||
| 3479 | * platforms I checked have a 0 for this. (Maybe BIOS overrides?) */ | ||
| 3480 | I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_DISABLE(0xffff)); | ||
| 3481 | I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_ENABLE(GEN6_GT_MODE_HI)); | ||
| 3477 | } | 3482 | } |
| 3478 | 3483 | ||
| 3479 | static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) | 3484 | static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) |
