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 0743337..727c4cc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3300,20 +3300,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); @@ -3325,24 +3316,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) @@ -13243,10 +13237,9 @@ static int intel_atomic_check(struct drm_device *dev, if (ret) return ret; - if (i915.fastboot && - intel_pipe_config_compare(state->dev, - to_intel_crtc_state(crtc->state), - pipe_config, true)) { + if (intel_pipe_config_compare(state->dev, + to_intel_crtc_state(crtc->state), + pipe_config, false)) { crtc_state->mode_changed = false; to_intel_crtc_state(crtc_state)->update_pipe = true; } @@ -13801,8 +13794,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, @@ -13838,7 +13837,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 7ccde58..371bfa8 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -559,7 +559,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; @@ -584,7 +584,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; @@ -647,7 +647,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,