diff options
author | Joonas Lahtinen <joonas.lahtinen@linux.intel.com> | 2022-04-12 11:28:42 +0300 |
---|---|---|
committer | Joonas Lahtinen <joonas.lahtinen@linux.intel.com> | 2022-04-12 11:28:42 +0300 |
commit | c16c8bfa09d5f318c1bd65698d058d3739970c24 (patch) | |
tree | a3ac5a1cad695c93d698cfff0b7629fd1a2ff79c /drivers/gpu/drm/i915/display | |
parent | 8e7e5c077cd57ee9a36d58c65f07257dc49a88d5 (diff) | |
parent | b85ffe47c4ec172214a38b7e7087c60582c488f0 (diff) |
Merge drm/drm-next into drm-intel-gt-next
Pull in TTM changes needed for DG2 CCS enabling from Ram.
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/display')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_atomic.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_atomic_plane.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_bw.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_crtc.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_display.c | 122 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_display_types.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_dp.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_hdmi.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_pps.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_pps.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_psr.c | 20 |
11 files changed, 141 insertions, 41 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index e0667d163266..40da7910f845 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -262,6 +262,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) crtc_state->preload_luts = false; crtc_state->inherited = false; crtc_state->wm.need_postvbl_update = false; + crtc_state->do_async_flip = false; crtc_state->fb_bits = 0; crtc_state->update_planes = 0; crtc_state->dsb = NULL; diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index c53aa6a4c7a0..5712688232fb 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -110,7 +110,6 @@ intel_plane_duplicate_state(struct drm_plane *plane) intel_state->ggtt_vma = NULL; intel_state->dpt_vma = NULL; intel_state->flags = 0; - intel_state->do_async_flip = false; /* add reference to fb */ if (intel_state->hw.fb) @@ -506,7 +505,7 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr new_crtc_state->disable_lp_wm = true; if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state)) - new_plane_state->do_async_flip = true; + new_crtc_state->do_async_flip = true; return 0; } @@ -678,7 +677,7 @@ void intel_plane_update_arm(struct intel_plane *plane, trace_intel_plane_update_arm(&plane->base, crtc); - if (plane_state->do_async_flip) + if (crtc_state->do_async_flip && plane->async_flip) plane->async_flip(plane, crtc_state, plane_state, true); else plane->update_arm(plane, crtc_state, plane_state); @@ -703,7 +702,7 @@ void intel_crtc_planes_update_noarm(struct intel_atomic_state *state, struct intel_plane *plane; int i; - if (new_crtc_state->uapi.async_flip) + if (new_crtc_state->do_async_flip) return; /* diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index ad1564ca7269..adf58c58513b 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -992,7 +992,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) * cause. */ if (!intel_can_enable_sagv(dev_priv, new_bw_state)) { - allowed_points = BIT(max_bw_point); + allowed_points &= ADLS_PSF_PT_MASK; + allowed_points |= BIT(max_bw_point); drm_dbg_kms(&dev_priv->drm, "No SAGV, using single QGV point %d\n", max_bw_point); } diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 08ee3e17ee5c..65827481c1b1 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -485,7 +485,7 @@ void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI); DEFINE_WAIT(wait); - if (new_crtc_state->uapi.async_flip) + if (new_crtc_state->do_async_flip) return; if (intel_crtc_needs_vblank_work(new_crtc_state)) @@ -630,7 +630,7 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) ktime_t end_vbl_time = ktime_get(); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - if (new_crtc_state->uapi.async_flip) + if (new_crtc_state->do_async_flip) return; trace_intel_pipe_update_end(crtc, end_vbl_count, scanline_end); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 80b19c304c43..7dfeb458aa65 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -346,7 +346,10 @@ static enum pipe bigjoiner_master_pipe(const struct intel_crtc_state *crtc_state u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state *crtc_state) { - return crtc_state->bigjoiner_pipes & ~BIT(bigjoiner_master_pipe(crtc_state)); + if (crtc_state->bigjoiner_pipes) + return crtc_state->bigjoiner_pipes & ~BIT(bigjoiner_master_pipe(crtc_state)); + else + return 0; } bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state) @@ -1260,10 +1263,8 @@ static void intel_crtc_enable_flip_done(struct intel_atomic_state *state, int i; for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - if (plane->enable_flip_done && - plane->pipe == crtc->pipe && - update_planes & BIT(plane->id) && - plane_state->do_async_flip) + if (plane->pipe == crtc->pipe && + update_planes & BIT(plane->id)) plane->enable_flip_done(plane); } } @@ -1279,10 +1280,8 @@ static void intel_crtc_disable_flip_done(struct intel_atomic_state *state, int i; for_each_new_intel_plane_in_state(state, plane, plane_state, i) { - if (plane->disable_flip_done && - plane->pipe == crtc->pipe && - update_planes & BIT(plane->id) && - plane_state->do_async_flip) + if (plane->pipe == crtc->pipe && + update_planes & BIT(plane->id)) plane->disable_flip_done(plane); } } @@ -7398,7 +7397,7 @@ static void kill_bigjoiner_slave(struct intel_atomic_state *state, * Correspondingly, support is currently added for primary plane only. * * Async flip can only change the plane surface address, so anything else - * changing is rejected from the intel_atomic_check_async() function. + * changing is rejected from the intel_async_flip_check_hw() function. * Once this check is cleared, flip done interrupt is enabled using * the intel_crtc_enable_flip_done() function. * @@ -7408,7 +7407,65 @@ static void kill_bigjoiner_slave(struct intel_atomic_state *state, * correspond to the last vblank and have no relation to the actual time when * the flip done event was sent. */ -static int intel_atomic_check_async(struct intel_atomic_state *state, struct intel_crtc *crtc) +static int intel_async_flip_check_uapi(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct drm_i915_private *i915 = to_i915(state->base.dev); + const struct intel_crtc_state *new_crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + const struct intel_plane_state *old_plane_state; + struct intel_plane_state *new_plane_state; + struct intel_plane *plane; + int i; + + if (!new_crtc_state->uapi.async_flip) + return 0; + + if (!new_crtc_state->uapi.active) { + drm_dbg_kms(&i915->drm, + "[CRTC:%d:%s] not active\n", + crtc->base.base.id, crtc->base.name); + return -EINVAL; + } + + if (intel_crtc_needs_modeset(new_crtc_state)) { + drm_dbg_kms(&i915->drm, + "[CRTC:%d:%s] modeset required\n", + crtc->base.base.id, crtc->base.name); + return -EINVAL; + } + + for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, + new_plane_state, i) { + if (plane->pipe != crtc->pipe) + continue; + + /* + * TODO: Async flip is only supported through the page flip IOCTL + * as of now. So support currently added for primary plane only. + * Support for other planes on platforms on which supports + * this(vlv/chv and icl+) should be added when async flip is + * enabled in the atomic IOCTL path. + */ + if (!plane->async_flip) { + drm_dbg_kms(&i915->drm, + "[PLANE:%d:%s] async flip not supported\n", + plane->base.base.id, plane->base.name); + return -EINVAL; + } + + if (!old_plane_state->uapi.fb || !new_plane_state->uapi.fb) { + drm_dbg_kms(&i915->drm, + "[PLANE:%d:%s] no old or new framebuffer\n", + plane->base.base.id, plane->base.name); + return -EINVAL; + } + } + + return 0; +} + +static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct drm_i915_private *i915 = to_i915(state->base.dev); const struct intel_crtc_state *old_crtc_state, *new_crtc_state; @@ -7419,6 +7476,9 @@ static int intel_atomic_check_async(struct intel_atomic_state *state, struct int old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); + if (!new_crtc_state->uapi.async_flip) + return 0; + if (intel_crtc_needs_modeset(new_crtc_state)) { drm_dbg_kms(&i915->drm, "Modeset Required. Async flip not supported\n"); return -EINVAL; @@ -7440,16 +7500,26 @@ static int intel_atomic_check_async(struct intel_atomic_state *state, struct int continue; /* - * TODO: Async flip is only supported through the page flip IOCTL - * as of now. So support currently added for primary plane only. - * Support for other planes on platforms on which supports - * this(vlv/chv and icl+) should be added when async flip is - * enabled in the atomic IOCTL path. + * Only async flip capable planes should be in the state + * if we're really about to ask the hardware to perform + * an async flip. We should never get this far otherwise. */ - if (!plane->async_flip) + if (drm_WARN_ON(&i915->drm, + new_crtc_state->do_async_flip && !plane->async_flip)) return -EINVAL; /* + * Only check async flip capable planes other planes + * may be involved in the initial commit due to + * the wm0/ddb optimization. + * + * TODO maybe should track which planes actually + * were requested to do the async flip... + */ + if (!plane->async_flip) + continue; + + /* * FIXME: This check is kept generic for all platforms. * Need to verify this for all gen9 platforms to enable * this selectively if required. @@ -7613,6 +7683,12 @@ static int intel_atomic_check(struct drm_device *dev, if (ret) goto fail; + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + ret = intel_async_flip_check_uapi(state, crtc); + if (ret) + return ret; + } + ret = intel_bigjoiner_add_affected_crtcs(state); if (ret) goto fail; @@ -7769,11 +7845,9 @@ static int intel_atomic_check(struct drm_device *dev, for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { - if (new_crtc_state->uapi.async_flip) { - ret = intel_atomic_check_async(state, crtc); - if (ret) - goto fail; - } + ret = intel_async_flip_check_hw(state, crtc); + if (ret) + goto fail; if (!intel_crtc_needs_modeset(new_crtc_state) && !new_crtc_state->update_pipe) @@ -8395,7 +8469,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_dbuf_pre_plane_update(state); for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { - if (new_crtc_state->uapi.async_flip) + if (new_crtc_state->do_async_flip) intel_crtc_enable_flip_done(state, crtc); } @@ -8421,7 +8495,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) drm_atomic_helper_wait_for_flip_done(dev, &state->base); for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { - if (new_crtc_state->uapi.async_flip) + if (new_crtc_state->do_async_flip) intel_crtc_disable_flip_done(state, crtc); } diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index b50d0e6efe21..776b3e6662f2 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -613,9 +613,6 @@ struct intel_plane_state { struct intel_fb_view view; - /* Indicates if async flip is required */ - bool do_async_flip; - /* Plane pxp decryption state */ bool decrypt; @@ -951,6 +948,9 @@ struct intel_crtc_state { bool preload_luts; bool inherited; /* state inherited from BIOS? */ + /* Ask the hardware to actually async flip? */ + bool do_async_flip; + /* Pipe source size (ie. panel fitter input size) * All planes will be positioned inside this space, * and get clipped at the edges. */ diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 1046e7fe310a..d667657e3606 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4863,7 +4863,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd) struct intel_dp *intel_dp = &dig_port->dp; if (dig_port->base.type == INTEL_OUTPUT_EDP && - (long_hpd || !intel_pps_have_power(intel_dp))) { + (long_hpd || !intel_pps_have_panel_power_or_vdd(intel_dp))) { /* * vdd off can generate a long/short pulse on eDP which * would require vdd on to handle it, and thus we diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 1aa5bdc7b0dc..6512f014cad4 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -1836,6 +1836,7 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, bool has_hdmi_sink) { struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); + enum phy phy = intel_port_to_phy(dev_priv, hdmi_to_dig_port(hdmi)->base.port); if (clock < 25000) return MODE_CLOCK_LOW; @@ -1856,6 +1857,14 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, if (IS_CHERRYVIEW(dev_priv) && clock > 216000 && clock < 240000) return MODE_CLOCK_RANGE; + /* ICL+ combo PHY PLL can't generate 500-533.2 MHz */ + if (intel_phy_is_combo(dev_priv, phy) && clock > 500000 && clock < 533200) + return MODE_CLOCK_RANGE; + + /* ICL+ TC PHY PLL can't generate 500-532.8 MHz */ + if (intel_phy_is_tc(dev_priv, phy) && clock > 500000 && clock < 532800) + return MODE_CLOCK_RANGE; + /* * SNPS PHYs' MPLLB table-based programming can only handle a fixed * set of link rates. diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index 9c986e8932f8..64bd4ca0edd4 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -1075,14 +1075,14 @@ static void intel_pps_vdd_sanitize(struct intel_dp *intel_dp) edp_panel_vdd_schedule_off(intel_dp); } -bool intel_pps_have_power(struct intel_dp *intel_dp) +bool intel_pps_have_panel_power_or_vdd(struct intel_dp *intel_dp) { intel_wakeref_t wakeref; bool have_power = false; with_intel_pps_lock(intel_dp, wakeref) { - have_power = edp_have_panel_power(intel_dp) && - edp_have_panel_vdd(intel_dp); + have_power = edp_have_panel_power(intel_dp) || + edp_have_panel_vdd(intel_dp); } return have_power; diff --git a/drivers/gpu/drm/i915/display/intel_pps.h b/drivers/gpu/drm/i915/display/intel_pps.h index fbb47f6f453e..e64144659d31 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.h +++ b/drivers/gpu/drm/i915/display/intel_pps.h @@ -37,7 +37,7 @@ void intel_pps_vdd_on(struct intel_dp *intel_dp); void intel_pps_on(struct intel_dp *intel_dp); void intel_pps_off(struct intel_dp *intel_dp); void intel_pps_vdd_off_sync(struct intel_dp *intel_dp); -bool intel_pps_have_power(struct intel_dp *intel_dp); +bool intel_pps_have_panel_power_or_vdd(struct intel_dp *intel_dp); void intel_pps_wait_power_cycle(struct intel_dp *intel_dp); void intel_pps_init(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 2e0b092f4b6b..bff8c2d73cdf 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1439,6 +1439,13 @@ static inline u32 man_trk_ctl_single_full_frame_bit_get(struct drm_i915_private PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME; } +static inline u32 man_trk_ctl_partial_frame_bit_get(struct drm_i915_private *dev_priv) +{ + return IS_ALDERLAKE_P(dev_priv) ? + ADLP_PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE : + PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE; +} + static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -1543,7 +1550,13 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - u32 val = PSR2_MAN_TRK_CTL_ENABLE; + u32 val = 0; + + if (!IS_ALDERLAKE_P(dev_priv)) + val = PSR2_MAN_TRK_CTL_ENABLE; + + /* SF partial frame enable has to be set even on full update */ + val |= man_trk_ctl_partial_frame_bit_get(dev_priv); if (full_update) { /* @@ -1563,7 +1576,6 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, } else { drm_WARN_ON(crtc_state->uapi.crtc->dev, clip->y1 % 4 || clip->y2 % 4); - val |= PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE; val |= PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1 / 4 + 1); val |= PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2 / 4 + 1); } @@ -1837,6 +1849,9 @@ static void _intel_psr_post_plane_update(const struct intel_atomic_state *state, mutex_lock(&psr->lock); + if (psr->sink_not_reliable) + goto exit; + drm_WARN_ON(&dev_priv->drm, psr->enabled && !crtc_state->active_planes); /* Only enable if there is active planes */ @@ -1847,6 +1862,7 @@ static void _intel_psr_post_plane_update(const struct intel_atomic_state *state, if (crtc_state->crc_enabled && psr->enabled) psr_force_hw_tracking_exit(intel_dp); +exit: mutex_unlock(&psr->lock); } } |