diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 182 |
1 files changed, 69 insertions, 113 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cddb0c692334..82128b95785c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1157,12 +1157,10 @@ static const char *state_string(bool enabled) void assert_pll(struct drm_i915_private *dev_priv, enum pipe pipe, bool state) { - int reg; u32 val; bool cur_state; - reg = DPLL(pipe); - val = I915_READ(reg); + val = I915_READ(DPLL(pipe)); cur_state = !!(val & DPLL_VCO_ENABLE); I915_STATE_WARN(cur_state != state, "PLL state assertion failure (expected %s, current %s)\n", @@ -1219,20 +1217,16 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv, static void assert_fdi_tx(struct drm_i915_private *dev_priv, enum pipe pipe, bool state) { - int reg; - u32 val; bool cur_state; enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, pipe); if (HAS_DDI(dev_priv->dev)) { /* DDI does not have a specific FDI_TX register */ - reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); - val = I915_READ(reg); + u32 val = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); cur_state = !!(val & TRANS_DDI_FUNC_ENABLE); } else { - reg = FDI_TX_CTL(pipe); - val = I915_READ(reg); + u32 val = I915_READ(FDI_TX_CTL(pipe)); cur_state = !!(val & FDI_TX_ENABLE); } I915_STATE_WARN(cur_state != state, @@ -1245,12 +1239,10 @@ static void assert_fdi_tx(struct drm_i915_private *dev_priv, static void assert_fdi_rx(struct drm_i915_private *dev_priv, enum pipe pipe, bool state) { - int reg; u32 val; bool cur_state; - reg = FDI_RX_CTL(pipe); - val = I915_READ(reg); + val = I915_READ(FDI_RX_CTL(pipe)); cur_state = !!(val & FDI_RX_ENABLE); I915_STATE_WARN(cur_state != state, "FDI RX state assertion failure (expected %s, current %s)\n", @@ -1262,7 +1254,6 @@ static void assert_fdi_rx(struct drm_i915_private *dev_priv, static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv, enum pipe pipe) { - int reg; u32 val; /* ILK FDI PLL is always enabled */ @@ -1273,20 +1264,17 @@ static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv, if (HAS_DDI(dev_priv->dev)) return; - reg = FDI_TX_CTL(pipe); - val = I915_READ(reg); + val = I915_READ(FDI_TX_CTL(pipe)); I915_STATE_WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n"); } void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, enum pipe pipe, bool state) { - int reg; u32 val; bool cur_state; - reg = FDI_RX_CTL(pipe); - val = I915_READ(reg); + val = I915_READ(FDI_RX_CTL(pipe)); cur_state = !!(val & FDI_RX_PLL_ENABLE); I915_STATE_WARN(cur_state != state, "FDI RX PLL assertion failure (expected %s, current %s)\n", @@ -1356,8 +1344,6 @@ static void assert_cursor(struct drm_i915_private *dev_priv, void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state) { - int reg; - u32 val; bool cur_state; enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, pipe); @@ -1371,8 +1357,7 @@ void assert_pipe(struct drm_i915_private *dev_priv, POWER_DOMAIN_TRANSCODER(cpu_transcoder))) { cur_state = false; } else { - reg = PIPECONF(cpu_transcoder); - val = I915_READ(reg); + u32 val = I915_READ(PIPECONF(cpu_transcoder)); cur_state = !!(val & PIPECONF_ENABLE); } @@ -1384,12 +1369,10 @@ void assert_pipe(struct drm_i915_private *dev_priv, static void assert_plane(struct drm_i915_private *dev_priv, enum plane plane, bool state) { - int reg; u32 val; bool cur_state; - reg = DSPCNTR(plane); - val = I915_READ(reg); + val = I915_READ(DSPCNTR(plane)); cur_state = !!(val & DISPLAY_PLANE_ENABLE); I915_STATE_WARN(cur_state != state, "plane %c assertion failure (expected %s, current %s)\n", @@ -1403,14 +1386,11 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv, enum pipe pipe) { struct drm_device *dev = dev_priv->dev; - int reg, i; - u32 val; - int cur_pipe; + int i; /* Primary planes are fixed to pipes on gen4+ */ if (INTEL_INFO(dev)->gen >= 4) { - reg = DSPCNTR(pipe); - val = I915_READ(reg); + u32 val = I915_READ(DSPCNTR(pipe)); I915_STATE_WARN(val & DISPLAY_PLANE_ENABLE, "plane %c assertion failure, should be disabled but not\n", plane_name(pipe)); @@ -1419,9 +1399,8 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv, /* Need to check both planes against the pipe */ for_each_pipe(dev_priv, i) { - reg = DSPCNTR(i); - val = I915_READ(reg); - cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >> + u32 val = I915_READ(DSPCNTR(i)); + enum pipe cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >> DISPPLANE_SEL_PIPE_SHIFT; I915_STATE_WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe, "plane %c assertion failure, should be off on pipe %c but is still active\n", @@ -1433,33 +1412,29 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv, enum pipe pipe) { struct drm_device *dev = dev_priv->dev; - int reg, sprite; - u32 val; + int sprite; if (INTEL_INFO(dev)->gen >= 9) { for_each_sprite(dev_priv, pipe, sprite) { - val = I915_READ(PLANE_CTL(pipe, sprite)); + u32 val = I915_READ(PLANE_CTL(pipe, sprite)); I915_STATE_WARN(val & PLANE_CTL_ENABLE, "plane %d assertion failure, should be off on pipe %c but is still active\n", sprite, pipe_name(pipe)); } } else if (IS_VALLEYVIEW(dev)) { for_each_sprite(dev_priv, pipe, sprite) { - reg = SPCNTR(pipe, sprite); - val = I915_READ(reg); + u32 val = I915_READ(SPCNTR(pipe, sprite)); I915_STATE_WARN(val & SP_ENABLE, "sprite %c assertion failure, should be off on pipe %c but is still active\n", sprite_name(pipe, sprite), pipe_name(pipe)); } } else if (INTEL_INFO(dev)->gen >= 7) { - reg = SPRCTL(pipe); - val = I915_READ(reg); + u32 val = I915_READ(SPRCTL(pipe)); I915_STATE_WARN(val & SPRITE_ENABLE, "sprite %c assertion failure, should be off on pipe %c but is still active\n", plane_name(pipe), pipe_name(pipe)); } else if (INTEL_INFO(dev)->gen >= 5) { - reg = DVSCNTR(pipe); - val = I915_READ(reg); + u32 val = I915_READ(DVSCNTR(pipe)); I915_STATE_WARN(val & DVS_ENABLE, "sprite %c assertion failure, should be off on pipe %c but is still active\n", plane_name(pipe), pipe_name(pipe)); @@ -1488,12 +1463,10 @@ static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, enum pipe pipe) { - int reg; u32 val; bool enabled; - reg = PCH_TRANSCONF(pipe); - val = I915_READ(reg); + val = I915_READ(PCH_TRANSCONF(pipe)); enabled = !!(val & TRANS_ENABLE); I915_STATE_WARN(enabled, "transcoder assertion failed, should be off on pipe %c but is still active\n", @@ -1600,21 +1573,18 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, enum pipe pipe) { - int reg; u32 val; assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); - reg = PCH_ADPA; - val = I915_READ(reg); + val = I915_READ(PCH_ADPA); I915_STATE_WARN(adpa_pipe_enabled(dev_priv, pipe, val), "PCH VGA enabled on transcoder %c, should be disabled\n", pipe_name(pipe)); - reg = PCH_LVDS; - val = I915_READ(reg); + val = I915_READ(PCH_LVDS); I915_STATE_WARN(lvds_pipe_enabled(dev_priv, pipe, val), "PCH LVDS enabled on transcoder %c, should be disabled\n", pipe_name(pipe)); @@ -4804,6 +4774,7 @@ static void intel_post_plane_update(struct intel_crtc *crtc) struct intel_crtc_atomic_commit *atomic = &crtc->atomic; struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_plane *plane; if (atomic->wait_vblank) intel_wait_for_vblank(dev, crtc->pipe); @@ -4822,6 +4793,10 @@ static void intel_post_plane_update(struct intel_crtc *crtc) if (atomic->post_enable_primary) intel_post_enable_primary(&crtc->base); + drm_for_each_plane_mask(plane, dev, atomic->update_sprite_watermarks) + intel_update_sprite_watermarks(plane, &crtc->base, + 0, 0, 0, false, false); + memset(atomic, 0, sizeof(*atomic)); } @@ -9952,7 +9927,7 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) } cntl |= pipe << 28; /* Connect to correct pipe */ - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) + if (HAS_DDI(dev)) cntl |= CURSOR_PIPE_CSC_ENABLE; } @@ -10822,7 +10797,7 @@ static bool page_flip_finished(struct intel_crtc *crtc) */ return (I915_READ(DSPSURFLIVE(crtc->plane)) & ~0xfff) == crtc->unpin_work->gtt_offset && - g4x_flip_count_after_eq(I915_READ(PIPE_FLIPCOUNT_GM45(crtc->pipe)), + g4x_flip_count_after_eq(I915_READ(PIPE_FLIPCOUNT_G4X(crtc->pipe)), crtc->unpin_work->flip_count); } @@ -10848,11 +10823,11 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane) spin_unlock_irqrestore(&dev->event_lock, flags); } -static inline void intel_mark_page_flip_active(struct intel_crtc *intel_crtc) +static inline void intel_mark_page_flip_active(struct intel_unpin_work *work) { /* Ensure that the work item is consistent when activating it ... */ smp_wmb(); - atomic_set(&intel_crtc->unpin_work->pending, INTEL_FLIP_PENDING); + atomic_set(&work->pending, INTEL_FLIP_PENDING); /* and that it is marked active as soon as the irq could fire. */ smp_wmb(); } @@ -10888,7 +10863,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev, intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); intel_ring_emit(ring, 0); /* aux display base address, unused */ - intel_mark_page_flip_active(intel_crtc); + intel_mark_page_flip_active(intel_crtc->unpin_work); return 0; } @@ -10920,7 +10895,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev, intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); intel_ring_emit(ring, MI_NOOP); - intel_mark_page_flip_active(intel_crtc); + intel_mark_page_flip_active(intel_crtc->unpin_work); return 0; } @@ -10959,7 +10934,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev, pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; intel_ring_emit(ring, pf | pipesrc); - intel_mark_page_flip_active(intel_crtc); + intel_mark_page_flip_active(intel_crtc->unpin_work); return 0; } @@ -10995,7 +10970,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev, pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; intel_ring_emit(ring, pf | pipesrc); - intel_mark_page_flip_active(intel_crtc); + intel_mark_page_flip_active(intel_crtc->unpin_work); return 0; } @@ -11090,7 +11065,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev, intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); intel_ring_emit(ring, (MI_NOOP)); - intel_mark_page_flip_active(intel_crtc); + intel_mark_page_flip_active(intel_crtc->unpin_work); return 0; } @@ -11121,7 +11096,8 @@ static bool use_mmio_flip(struct intel_engine_cs *ring, return ring != i915_gem_request_get_ring(obj->last_write_req); } -static void skl_do_mmio_flip(struct intel_crtc *intel_crtc) +static void skl_do_mmio_flip(struct intel_crtc *intel_crtc, + struct intel_unpin_work *work) { struct drm_device *dev = intel_crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -11162,11 +11138,12 @@ static void skl_do_mmio_flip(struct intel_crtc *intel_crtc) I915_WRITE(PLANE_CTL(pipe, 0), ctl); I915_WRITE(PLANE_STRIDE(pipe, 0), stride); - I915_WRITE(PLANE_SURF(pipe, 0), intel_crtc->unpin_work->gtt_offset); + I915_WRITE(PLANE_SURF(pipe, 0), work->gtt_offset); POSTING_READ(PLANE_SURF(pipe, 0)); } -static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc) +static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc, + struct intel_unpin_work *work) { struct drm_device *dev = intel_crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -11186,31 +11163,36 @@ static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc) I915_WRITE(reg, dspcntr); - I915_WRITE(DSPSURF(intel_crtc->plane), - intel_crtc->unpin_work->gtt_offset); + I915_WRITE(DSPSURF(intel_crtc->plane), work->gtt_offset); POSTING_READ(DSPSURF(intel_crtc->plane)); - } /* * XXX: This is the temporary way to update the plane registers until we get * around to using the usual plane update functions for MMIO flips */ -static void intel_do_mmio_flip(struct intel_crtc *intel_crtc) +static void intel_do_mmio_flip(struct intel_mmio_flip *mmio_flip) { - struct drm_device *dev = intel_crtc->base.dev; + struct intel_crtc *crtc = mmio_flip->crtc; + struct intel_unpin_work *work; - intel_mark_page_flip_active(intel_crtc); + spin_lock_irq(&crtc->base.dev->event_lock); + work = crtc->unpin_work; + spin_unlock_irq(&crtc->base.dev->event_lock); + if (work == NULL) + return; - intel_pipe_update_start(intel_crtc); + intel_mark_page_flip_active(work); - if (INTEL_INFO(dev)->gen >= 9) - skl_do_mmio_flip(intel_crtc); + intel_pipe_update_start(crtc); + + if (INTEL_INFO(mmio_flip->i915)->gen >= 9) + skl_do_mmio_flip(crtc, work); else /* use_mmio_flip() retricts MMIO flips to ilk+ */ - ilk_do_mmio_flip(intel_crtc); + ilk_do_mmio_flip(crtc, work); - intel_pipe_update_end(intel_crtc); + intel_pipe_update_end(crtc); } static void intel_mmio_flip_work_func(struct work_struct *work) @@ -11218,15 +11200,15 @@ static void intel_mmio_flip_work_func(struct work_struct *work) struct intel_mmio_flip *mmio_flip = container_of(work, struct intel_mmio_flip, work); - if (mmio_flip->req) + if (mmio_flip->req) { WARN_ON(__i915_wait_request(mmio_flip->req, mmio_flip->crtc->reset_counter, false, NULL, &mmio_flip->i915->rps.mmioflips)); + i915_gem_request_unreference__unlocked(mmio_flip->req); + } - intel_do_mmio_flip(mmio_flip->crtc); - - i915_gem_request_unreference__unlocked(mmio_flip->req); + intel_do_mmio_flip(mmio_flip); kfree(mmio_flip); } @@ -11427,7 +11409,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, intel_crtc->reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) - work->flip_count = I915_READ(PIPE_FLIPCOUNT_GM45(pipe)) + 1; + work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(pipe)) + 1; if (IS_VALLEYVIEW(dev)) { ring = &dev_priv->ring[BCS]; @@ -11577,30 +11559,16 @@ retry: static bool intel_wm_need_update(struct drm_plane *plane, struct drm_plane_state *state) { - struct intel_plane_state *new = to_intel_plane_state(state); - struct intel_plane_state *cur = to_intel_plane_state(plane->state); - - /* Update watermarks on tiling or size changes. */ + /* Update watermarks on tiling changes. */ if (!plane->state->fb || !state->fb || plane->state->fb->modifier[0] != state->fb->modifier[0] || - plane->state->rotation != state->rotation || - drm_rect_width(&new->src) != drm_rect_width(&cur->src) || - drm_rect_height(&new->src) != drm_rect_height(&cur->src) || - drm_rect_width(&new->dst) != drm_rect_width(&cur->dst) || - drm_rect_height(&new->dst) != drm_rect_height(&cur->dst)) + plane->state->rotation != state->rotation) return true; - return false; -} - -static bool needs_scaling(struct intel_plane_state *state) -{ - int src_w = drm_rect_width(&state->src) >> 16; - int src_h = drm_rect_height(&state->src) >> 16; - int dst_w = drm_rect_width(&state->dst); - int dst_h = drm_rect_height(&state->dst); + if (plane->state->crtc_w != state->crtc_w) + return true; - return (src_w != dst_w || src_h != dst_h); + return false; } int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, @@ -11618,6 +11586,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, bool mode_changed = needs_modeset(crtc_state); bool was_crtc_enabled = crtc->state->active; bool is_crtc_enabled = crtc_state->active; + bool turn_off, turn_on, visible, was_visible; struct drm_framebuffer *fb = plane_state->fb; @@ -11735,23 +11704,11 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, case DRM_PLANE_TYPE_CURSOR: break; case DRM_PLANE_TYPE_OVERLAY: - /* - * WaCxSRDisabledForSpriteScaling:ivb - * - * cstate->update_wm was already set above, so this flag will - * take effect when we commit and program watermarks. - */ - if (IS_IVYBRIDGE(dev) && - needs_scaling(to_intel_plane_state(plane_state)) && - !needs_scaling(old_plane_state)) { - to_intel_crtc_state(crtc_state)->disable_lp_wm = true; - } else if (turn_off && !mode_changed) { + if (turn_off && !mode_changed) { intel_crtc->atomic.wait_vblank = true; intel_crtc->atomic.update_sprite_watermarks |= 1 << i; } - - break; } return 0; } @@ -14942,13 +14899,12 @@ intel_check_plane_mapping(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - u32 reg, val; + u32 val; if (INTEL_INFO(dev)->num_pipes == 1) return true; - reg = DSPCNTR(!crtc->plane); - val = I915_READ(reg); + val = I915_READ(DSPCNTR(!crtc->plane)); if ((val & DISPLAY_PLANE_ENABLE) && (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) |