diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 643f342..a3ac4d4 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -93,7 +93,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) __drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base); - crtc_state->update_pipe = false; + crtc_state->update_pipe = true; crtc_state->disable_lp_wm = false; return &crtc_state->base; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 688d484..ade97a7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3304,20 +3304,11 @@ static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) return pending; } -static void intel_update_pipe_config(struct intel_crtc *crtc, - struct intel_crtc_state *old_crtc_state) +static void intel_update_pipe_config(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc_state *pipe_config = - to_intel_crtc_state(crtc->base.state); - - /* drm_atomic_helper_update_legacy_modeset_state might not be called. */ - crtc->base.mode = crtc->base.state->mode; - - DRM_DEBUG_KMS("Updating pipe size %ix%i -> %ix%i\n", - old_crtc_state->pipe_src_w, old_crtc_state->pipe_src_h, - pipe_config->pipe_src_w, pipe_config->pipe_src_h); + const struct drm_display_mode *adjusted_mode; if (HAS_DDI(dev)) intel_set_pipe_csc(&crtc->base); @@ -3329,24 +3320,27 @@ static void intel_update_pipe_config(struct intel_crtc *crtc, * fastboot case, we'll flip, but if we don't update the pipesrc and * pfit state, we'll end up with a big fb scanned out into the wrong * sized surface. + * + * To fix this properly, we need to hoist the checks up into + * compute_mode_changes (or above), check the actual pfit state and + * whether the platform allows pfit disable with pipe active, and only + * then update the pipesrc and pfit state, even on the flip path. */ - I915_WRITE(PIPESRC(crtc->pipe), - ((pipe_config->pipe_src_w - 1) << 16) | - (pipe_config->pipe_src_h - 1)); - - /* on skylake this is done by detaching scalers */ - if (INTEL_INFO(dev)->gen >= 9) { - skl_detach_scalers(crtc); + adjusted_mode = &crtc->config->base.adjusted_mode; - if (pipe_config->pch_pfit.enabled) - skylake_pfit_enable(crtc); - } else if (HAS_PCH_SPLIT(dev)) { - if (pipe_config->pch_pfit.enabled) - ironlake_pfit_enable(crtc); - else if (old_crtc_state->pch_pfit.enabled) - ironlake_pfit_disable(crtc, true); + I915_WRITE(PIPESRC(crtc->pipe), + ((adjusted_mode->crtc_hdisplay - 1) << 16) | + (adjusted_mode->crtc_vdisplay - 1)); + if (!crtc->config->pch_pfit.enabled && + (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || + intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { + I915_WRITE(PF_CTL(crtc->pipe), 0); + I915_WRITE(PF_WIN_POS(crtc->pipe), 0); + I915_WRITE(PF_WIN_SZ(crtc->pipe), 0); } + crtc->config->pipe_src_w = adjusted_mode->crtc_hdisplay; + crtc->config->pipe_src_h = adjusted_mode->crtc_vdisplay; } static void intel_fdi_normal_train(struct drm_crtc *crtc) @@ -12602,7 +12596,6 @@ intel_pipe_config_compare(struct drm_device *dev, if (!adjust) { PIPE_CONF_CHECK_I(pipe_src_w); PIPE_CONF_CHECK_I(pipe_src_h); - PIPE_CONF_CHECK_I(pch_pfit.enabled); if (current_config->pch_pfit.enabled) { PIPE_CONF_CHECK_X(pch_pfit.pos); @@ -13199,7 +13192,7 @@ static int intel_atomic_check(struct drm_device *dev, if (intel_pipe_config_compare(state->dev, to_intel_crtc_state(crtc->state), - pipe_config, true)) { + pipe_config, false)) { crtc_state->mode_changed = false; to_intel_crtc_state(crtc_state)->update_pipe = true; } @@ -13747,8 +13740,14 @@ intel_commit_primary_plane(struct drm_plane *plane, struct drm_framebuffer *fb = state->base.fb; struct drm_device *dev = plane->dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc; crtc = crtc ? crtc : plane->crtc; + intel_crtc = to_intel_crtc(crtc); + + if (state->visible) + /* FIXME: kill this fastboot hack */ + intel_update_pipe_config(intel_crtc); dev_priv->display.update_primary_plane(crtc, fb, state->src.x1 >> 16, @@ -13784,7 +13783,7 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc, return; if (to_intel_crtc_state(crtc->state)->update_pipe) - intel_update_pipe_config(intel_crtc, old_intel_state); + intel_update_pipe_config(intel_crtc); else if (INTEL_INFO(dev)->gen >= 9) skl_detach_scalers(intel_crtc); } diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 98772d3..a6d2530 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -556,7 +556,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, intel_fb_obj(crtc->primary->state->fb); intel_crtc = to_intel_crtc(crtc); - if (!crtc->state->active || !obj) { + if (!intel_crtc->active || !obj) { DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n", pipe_name(intel_crtc->pipe)); continue; @@ -581,7 +581,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, intel_crtc = to_intel_crtc(crtc); - if (!crtc->state->active) { + if (!intel_crtc->active) { DRM_DEBUG_KMS("pipe %c not active, skipping\n", pipe_name(intel_crtc->pipe)); continue; @@ -644,7 +644,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, for_each_crtc(dev, crtc) { intel_crtc = to_intel_crtc(crtc); - if (!crtc->state->active) + if (!intel_crtc->active) continue; WARN(!crtc->primary->fb,