diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_psr.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_psr.c | 79 |
1 files changed, 49 insertions, 30 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 430ad4ef71466..8bee2f592ae7d 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -37,6 +37,7 @@ #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_irq.h" +#include "intel_display_regs.h" #include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dmc.h" @@ -516,7 +517,7 @@ static u8 intel_dp_get_su_capability(struct intel_dp *intel_dp) if (intel_dp->psr.sink_panel_replay_su_support) drm_dp_dpcd_readb(&intel_dp->aux, - DP_PANEL_PANEL_REPLAY_CAPABILITY, + DP_PANEL_REPLAY_CAP_CAPABILITY, &su_capability); else su_capability = intel_dp->psr_dpcd[1]; @@ -528,7 +529,7 @@ static unsigned int intel_dp_get_su_x_granularity_offset(struct intel_dp *intel_dp) { return intel_dp->psr.sink_panel_replay_su_support ? - DP_PANEL_PANEL_REPLAY_X_GRANULARITY : + DP_PANEL_REPLAY_CAP_X_GRANULARITY : DP_PSR2_SU_X_GRANULARITY; } @@ -536,7 +537,7 @@ static unsigned int intel_dp_get_su_y_granularity_offset(struct intel_dp *intel_dp) { return intel_dp->psr.sink_panel_replay_su_support ? - DP_PANEL_PANEL_REPLAY_Y_GRANULARITY : + DP_PANEL_REPLAY_CAP_Y_GRANULARITY : DP_PSR2_SU_Y_GRANULARITY; } @@ -608,7 +609,8 @@ static void _panel_replay_init_dpcd(struct intel_dp *intel_dp) return; } - if (!(intel_dp->pr_dpcd & DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT)) { + if (!(intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] & + DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT)) { drm_dbg_kms(display->drm, "Panel doesn't support early transport, eDP Panel Replay not possible\n"); return; @@ -617,7 +619,8 @@ static void _panel_replay_init_dpcd(struct intel_dp *intel_dp) intel_dp->psr.sink_panel_replay_support = true; - if (intel_dp->pr_dpcd & DP_PANEL_REPLAY_SU_SUPPORT) + if (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] & + DP_PANEL_REPLAY_SU_SUPPORT) intel_dp->psr.sink_panel_replay_su_support = true; drm_dbg_kms(display->drm, @@ -676,10 +679,12 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) { drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp->psr_dpcd, sizeof(intel_dp->psr_dpcd)); - drm_dp_dpcd_readb(&intel_dp->aux, DP_PANEL_REPLAY_CAP, - &intel_dp->pr_dpcd); - if (intel_dp->pr_dpcd & DP_PANEL_REPLAY_SUPPORT) + drm_dp_dpcd_read(&intel_dp->aux, DP_PANEL_REPLAY_CAP_SUPPORT, + &intel_dp->pr_dpcd, sizeof(intel_dp->pr_dpcd)); + + if (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] & + DP_PANEL_REPLAY_SUPPORT) _panel_replay_init_dpcd(intel_dp); if (intel_dp->psr_dpcd[0]) @@ -736,7 +741,8 @@ static bool psr2_su_region_et_valid(struct intel_dp *intel_dp, bool panel_replay return false; return panel_replay ? - intel_dp->pr_dpcd & DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT : + intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] & + DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT : intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_ET_SUPPORTED && psr2_su_region_et_global_enabled(intel_dp); } @@ -1574,6 +1580,12 @@ static bool _psr_compute_config(struct intel_dp *intel_dp, if (!CAN_PSR(intel_dp)) return false; + /* + * Currently PSR doesn't work reliably with VRR enabled. + */ + if (crtc_state->vrr.enable) + return false; + entry_setup_frames = intel_psr_entry_setup_frames(intel_dp, adjusted_mode); if (entry_setup_frames >= 0) { @@ -1691,12 +1703,6 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, return; } - /* - * Currently PSR/PR doesn't work reliably with VRR enabled. - */ - if (crtc_state->vrr.enable) - return; - crtc_state->has_panel_replay = _panel_replay_compute_config(intel_dp, crtc_state, conn_state); @@ -3916,7 +3922,8 @@ static void intel_psr_sink_capability(struct intel_dp *intel_dp, seq_printf(m, ", Panel Replay = %s", str_yes_no(psr->sink_panel_replay_support)); seq_printf(m, ", Panel Replay Selective Update = %s", str_yes_no(psr->sink_panel_replay_su_support)); - if (intel_dp->pr_dpcd & DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT) + if (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_SUPPORT)] & + DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT) seq_printf(m, " (Early Transport)"); seq_printf(m, "\n"); } @@ -4021,24 +4028,30 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp) int frame; /* - * Reading all 3 registers before hand to minimize crossing a - * frame boundary between register reads + * PSR2_SU_STATUS register has been tied-off since DG2/ADL-P + * (it returns zeros only) and it has been removed on Xe2_LPD. */ - for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame += 3) { - val = intel_de_read(display, - PSR2_SU_STATUS(display, cpu_transcoder, frame)); - su_frames_val[frame / 3] = val; - } + if (DISPLAY_VER(display) < 13) { + /* + * Reading all 3 registers before hand to minimize crossing a + * frame boundary between register reads + */ + for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame += 3) { + val = intel_de_read(display, + PSR2_SU_STATUS(display, cpu_transcoder, frame)); + su_frames_val[frame / 3] = val; + } - seq_puts(m, "Frame:\tPSR2 SU blocks:\n"); + seq_puts(m, "Frame:\tPSR2 SU blocks:\n"); - for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame++) { - u32 su_blocks; + for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame++) { + u32 su_blocks; - su_blocks = su_frames_val[frame / 3] & - PSR2_SU_STATUS_MASK(frame); - su_blocks = su_blocks >> PSR2_SU_STATUS_SHIFT(frame); - seq_printf(m, "%d\t%d\n", frame, su_blocks); + su_blocks = su_frames_val[frame / 3] & + PSR2_SU_STATUS_MASK(frame); + su_blocks = su_blocks >> PSR2_SU_STATUS_SHIFT(frame); + seq_printf(m, "%d\t%d\n", frame, su_blocks); + } } seq_printf(m, "PSR2 selective fetch: %s\n", @@ -4234,3 +4247,9 @@ bool intel_psr_needs_alpm(struct intel_dp *intel_dp, const struct intel_crtc_sta return intel_dp_is_edp(intel_dp) && (crtc_state->has_sel_update || crtc_state->has_panel_replay); } + +bool intel_psr_needs_alpm_aux_less(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + return intel_dp_is_edp(intel_dp) && crtc_state->has_panel_replay; +} |