diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 95 |
1 files changed, 80 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 48d8fd686ea9..d9b7092439ef 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1611,6 +1611,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1611 | 1611 | ||
1612 | wait_event(dev_priv->pending_flip_queue, | 1612 | wait_event(dev_priv->pending_flip_queue, |
1613 | atomic_read(&obj_priv->pending_flip) == 0); | 1613 | atomic_read(&obj_priv->pending_flip) == 0); |
1614 | |||
1615 | /* Big Hammer, we also need to ensure that any pending | ||
1616 | * MI_WAIT_FOR_EVENT inside a user batch buffer on the | ||
1617 | * current scanout is retired before unpinning the old | ||
1618 | * framebuffer. | ||
1619 | */ | ||
1620 | ret = i915_gem_object_flush_gpu(obj_priv, false); | ||
1621 | if (ret) { | ||
1622 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); | ||
1623 | mutex_unlock(&dev->struct_mutex); | ||
1624 | return ret; | ||
1625 | } | ||
1614 | } | 1626 | } |
1615 | 1627 | ||
1616 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, | 1628 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, |
@@ -2108,9 +2120,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
2108 | reg = TRANS_DP_CTL(pipe); | 2120 | reg = TRANS_DP_CTL(pipe); |
2109 | temp = I915_READ(reg); | 2121 | temp = I915_READ(reg); |
2110 | temp &= ~(TRANS_DP_PORT_SEL_MASK | | 2122 | temp &= ~(TRANS_DP_PORT_SEL_MASK | |
2111 | TRANS_DP_SYNC_MASK); | 2123 | TRANS_DP_SYNC_MASK | |
2124 | TRANS_DP_BPC_MASK); | ||
2112 | temp |= (TRANS_DP_OUTPUT_ENABLE | | 2125 | temp |= (TRANS_DP_OUTPUT_ENABLE | |
2113 | TRANS_DP_ENH_FRAMING); | 2126 | TRANS_DP_ENH_FRAMING); |
2127 | temp |= TRANS_DP_8BPC; | ||
2114 | 2128 | ||
2115 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | 2129 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
2116 | temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; | 2130 | temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; |
@@ -2700,27 +2714,19 @@ fdi_reduce_ratio(u32 *num, u32 *den) | |||
2700 | } | 2714 | } |
2701 | } | 2715 | } |
2702 | 2716 | ||
2703 | #define DATA_N 0x800000 | ||
2704 | #define LINK_N 0x80000 | ||
2705 | |||
2706 | static void | 2717 | static void |
2707 | ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, | 2718 | ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, |
2708 | int link_clock, struct fdi_m_n *m_n) | 2719 | int link_clock, struct fdi_m_n *m_n) |
2709 | { | 2720 | { |
2710 | u64 temp; | ||
2711 | |||
2712 | m_n->tu = 64; /* default size */ | 2721 | m_n->tu = 64; /* default size */ |
2713 | 2722 | ||
2714 | temp = (u64) DATA_N * pixel_clock; | 2723 | /* BUG_ON(pixel_clock > INT_MAX / 36); */ |
2715 | temp = div_u64(temp, link_clock); | 2724 | m_n->gmch_m = bits_per_pixel * pixel_clock; |
2716 | m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes); | 2725 | m_n->gmch_n = link_clock * nlanes * 8; |
2717 | m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */ | ||
2718 | m_n->gmch_n = DATA_N; | ||
2719 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 2726 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
2720 | 2727 | ||
2721 | temp = (u64) LINK_N * pixel_clock; | 2728 | m_n->link_m = pixel_clock; |
2722 | m_n->link_m = div_u64(temp, link_clock); | 2729 | m_n->link_n = link_clock; |
2723 | m_n->link_n = LINK_N; | ||
2724 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); | 2730 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); |
2725 | } | 2731 | } |
2726 | 2732 | ||
@@ -3704,6 +3710,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3704 | 3710 | ||
3705 | /* FDI link */ | 3711 | /* FDI link */ |
3706 | if (HAS_PCH_SPLIT(dev)) { | 3712 | if (HAS_PCH_SPLIT(dev)) { |
3713 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | ||
3707 | int lane = 0, link_bw, bpp; | 3714 | int lane = 0, link_bw, bpp; |
3708 | /* CPU eDP doesn't require FDI link, so just set DP M/N | 3715 | /* CPU eDP doesn't require FDI link, so just set DP M/N |
3709 | according to current link config */ | 3716 | according to current link config */ |
@@ -3787,6 +3794,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3787 | 3794 | ||
3788 | intel_crtc->fdi_lanes = lane; | 3795 | intel_crtc->fdi_lanes = lane; |
3789 | 3796 | ||
3797 | if (pixel_multiplier > 1) | ||
3798 | link_bw *= pixel_multiplier; | ||
3790 | ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); | 3799 | ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); |
3791 | } | 3800 | } |
3792 | 3801 | ||
@@ -5224,6 +5233,55 @@ static const struct drm_crtc_funcs intel_crtc_funcs = { | |||
5224 | .page_flip = intel_crtc_page_flip, | 5233 | .page_flip = intel_crtc_page_flip, |
5225 | }; | 5234 | }; |
5226 | 5235 | ||
5236 | static void intel_sanitize_modesetting(struct drm_device *dev, | ||
5237 | int pipe, int plane) | ||
5238 | { | ||
5239 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5240 | u32 reg, val; | ||
5241 | |||
5242 | if (HAS_PCH_SPLIT(dev)) | ||
5243 | return; | ||
5244 | |||
5245 | /* Who knows what state these registers were left in by the BIOS or | ||
5246 | * grub? | ||
5247 | * | ||
5248 | * If we leave the registers in a conflicting state (e.g. with the | ||
5249 | * display plane reading from the other pipe than the one we intend | ||
5250 | * to use) then when we attempt to teardown the active mode, we will | ||
5251 | * not disable the pipes and planes in the correct order -- leaving | ||
5252 | * a plane reading from a disabled pipe and possibly leading to | ||
5253 | * undefined behaviour. | ||
5254 | */ | ||
5255 | |||
5256 | reg = DSPCNTR(plane); | ||
5257 | val = I915_READ(reg); | ||
5258 | |||
5259 | if ((val & DISPLAY_PLANE_ENABLE) == 0) | ||
5260 | return; | ||
5261 | if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe) | ||
5262 | return; | ||
5263 | |||
5264 | /* This display plane is active and attached to the other CPU pipe. */ | ||
5265 | pipe = !pipe; | ||
5266 | |||
5267 | /* Disable the plane and wait for it to stop reading from the pipe. */ | ||
5268 | I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); | ||
5269 | intel_flush_display_plane(dev, plane); | ||
5270 | |||
5271 | if (IS_GEN2(dev)) | ||
5272 | intel_wait_for_vblank(dev, pipe); | ||
5273 | |||
5274 | if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) | ||
5275 | return; | ||
5276 | |||
5277 | /* Switch off the pipe. */ | ||
5278 | reg = PIPECONF(pipe); | ||
5279 | val = I915_READ(reg); | ||
5280 | if (val & PIPECONF_ENABLE) { | ||
5281 | I915_WRITE(reg, val & ~PIPECONF_ENABLE); | ||
5282 | intel_wait_for_pipe_off(dev, pipe); | ||
5283 | } | ||
5284 | } | ||
5227 | 5285 | ||
5228 | static void intel_crtc_init(struct drm_device *dev, int pipe) | 5286 | static void intel_crtc_init(struct drm_device *dev, int pipe) |
5229 | { | 5287 | { |
@@ -5275,6 +5333,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
5275 | 5333 | ||
5276 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, | 5334 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, |
5277 | (unsigned long)intel_crtc); | 5335 | (unsigned long)intel_crtc); |
5336 | |||
5337 | intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); | ||
5278 | } | 5338 | } |
5279 | 5339 | ||
5280 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 5340 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
@@ -5324,9 +5384,14 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
5324 | struct drm_i915_private *dev_priv = dev->dev_private; | 5384 | struct drm_i915_private *dev_priv = dev->dev_private; |
5325 | struct intel_encoder *encoder; | 5385 | struct intel_encoder *encoder; |
5326 | bool dpd_is_edp = false; | 5386 | bool dpd_is_edp = false; |
5387 | bool has_lvds = false; | ||
5327 | 5388 | ||
5328 | if (IS_MOBILE(dev) && !IS_I830(dev)) | 5389 | if (IS_MOBILE(dev) && !IS_I830(dev)) |
5329 | intel_lvds_init(dev); | 5390 | has_lvds = intel_lvds_init(dev); |
5391 | if (!has_lvds && !HAS_PCH_SPLIT(dev)) { | ||
5392 | /* disable the panel fitter on everything but LVDS */ | ||
5393 | I915_WRITE(PFIT_CONTROL, 0); | ||
5394 | } | ||
5330 | 5395 | ||
5331 | if (HAS_PCH_SPLIT(dev)) { | 5396 | if (HAS_PCH_SPLIT(dev)) { |
5332 | dpd_is_edp = intel_dpd_is_edp(dev); | 5397 | dpd_is_edp = intel_dpd_is_edp(dev); |