Skip to content

Commit 9ce5884

Browse files
committed
drm/i915/display: Only keep PSR enabled if there is active planes
PSR always had a requirement to only be enabled if there is active planes but not following that never caused any issues. But that changes in Alderlake-P, leaving PSR enabled without active planes causes transcoder/port underruns. Similar behavior was fixed during the pipe disable sequence by commit 84030ad ("drm/i915/display: Disable audio, DRRS and PSR before planes"). intel_dp_compute_psr_vsc_sdp() had to move from intel_psr_enable_locked() to intel_psr_compute_config() because we need to be able to disable/enable PSR from atomic states without connector and encoder state. Reviewed-by: Gwan-gyeong Mun <[email protected]> Cc: Ville Syrjälä <[email protected]> Cc: Gwan-gyeong Mun <[email protected]> Signed-off-by: José Roberto de Souza <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 73262db commit 9ce5884

File tree

7 files changed

+98
-80
lines changed

7 files changed

+98
-80
lines changed

drivers/gpu/drm/i915/display/intel_ddi.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3034,7 +3034,6 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
30343034
intel_dp_stop_link_train(intel_dp, crtc_state);
30353035

30363036
intel_edp_backlight_on(crtc_state, conn_state);
3037-
intel_psr_enable(intel_dp, crtc_state, conn_state);
30383037

30393038
if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink)
30403039
intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
@@ -3255,7 +3254,6 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state,
32553254

32563255
intel_ddi_set_dp_msa(crtc_state, conn_state);
32573256

3258-
intel_psr_update(intel_dp, crtc_state, conn_state);
32593257
intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
32603258
intel_drrs_update(intel_dp, crtc_state);
32613259

drivers/gpu/drm/i915/display/intel_display.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8098,10 +8098,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
80988098
if (bp_gamma)
80998099
PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, hw.gamma_lut, bp_gamma);
81008100

8101-
PIPE_CONF_CHECK_BOOL(has_psr);
8102-
PIPE_CONF_CHECK_BOOL(has_psr2);
8103-
PIPE_CONF_CHECK_BOOL(enable_psr2_sel_fetch);
8104-
PIPE_CONF_CHECK_I(dc3co_exitline);
8101+
if (current_config->active_planes) {
8102+
PIPE_CONF_CHECK_BOOL(has_psr);
8103+
PIPE_CONF_CHECK_BOOL(has_psr2);
8104+
PIPE_CONF_CHECK_BOOL(enable_psr2_sel_fetch);
8105+
PIPE_CONF_CHECK_I(dc3co_exitline);
8106+
}
81058107
}
81068108

81078109
PIPE_CONF_CHECK_BOOL(double_wide);
@@ -8158,7 +8160,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
81588160
PIPE_CONF_CHECK_I(min_voltage_level);
81598161
}
81608162

8161-
if (fastset && (current_config->has_psr || pipe_config->has_psr))
8163+
if (current_config->has_psr || pipe_config->has_psr)
81628164
PIPE_CONF_CHECK_X_WITH_MASK(infoframes.enable,
81638165
~intel_hdmi_infoframe_enable(DP_SDP_VSC));
81648166
else
@@ -10212,6 +10214,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
1021210214
intel_encoders_update_prepare(state);
1021310215

1021410216
intel_dbuf_pre_plane_update(state);
10217+
intel_psr_pre_plane_update(state);
1021510218

1021610219
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
1021710220
if (new_crtc_state->uapi.async_flip)
@@ -10275,6 +10278,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
1027510278
}
1027610279

1027710280
intel_dbuf_post_plane_update(state);
10281+
intel_psr_post_plane_update(state);
1027810282

1027910283
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
1028010284
intel_post_plane_update(state, crtc);

drivers/gpu/drm/i915/display/intel_display_types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1054,12 +1054,14 @@ struct intel_crtc_state {
10541054
struct intel_link_m_n dp_m2_n2;
10551055
bool has_drrs;
10561056

1057+
/* PSR is supported but might not be enabled due the lack of enabled planes */
10571058
bool has_psr;
10581059
bool has_psr2;
10591060
bool enable_psr2_sel_fetch;
10601061
bool req_psr2_sdp_prior_scanline;
10611062
u32 dc3co_exitline;
10621063
u16 su_y_granularity;
1064+
struct drm_dp_vsc_sdp psr_vsc;
10631065

10641066
/*
10651067
* Frequence the dpll for the port should run at. Differs from the
@@ -1523,7 +1525,6 @@ struct intel_psr {
15231525
u32 dc3co_exitline;
15241526
u32 dc3co_exit_delay;
15251527
struct delayed_work dc3co_work;
1526-
struct drm_dp_vsc_sdp vsc;
15271528
};
15281529

15291530
struct intel_dp {

drivers/gpu/drm/i915/display/intel_dp.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,7 +1674,7 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp,
16741674
{
16751675
vsc->sdp_type = DP_SDP_VSC;
16761676

1677-
if (intel_dp->psr.psr2_enabled) {
1677+
if (crtc_state->has_psr2) {
16781678
if (intel_dp->psr.colorimetry_support &&
16791679
intel_dp_needs_vsc_sdp(crtc_state, conn_state)) {
16801680
/* [PSR2, +Colorimetry] */
@@ -1828,7 +1828,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
18281828
g4x_dp_set_clock(encoder, pipe_config);
18291829

18301830
intel_vrr_compute_config(pipe_config, conn_state);
1831-
intel_psr_compute_config(intel_dp, pipe_config);
1831+
intel_psr_compute_config(intel_dp, pipe_config, conn_state);
18321832
intel_drrs_compute_config(intel_dp, pipe_config, output_bpp,
18331833
constant_n);
18341834
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
@@ -2888,7 +2888,7 @@ static void intel_write_dp_sdp(struct intel_encoder *encoder,
28882888

28892889
void intel_write_dp_vsc_sdp(struct intel_encoder *encoder,
28902890
const struct intel_crtc_state *crtc_state,
2891-
struct drm_dp_vsc_sdp *vsc)
2891+
const struct drm_dp_vsc_sdp *vsc)
28922892
{
28932893
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
28942894
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);

drivers/gpu/drm/i915/display/intel_dp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp,
8888
struct drm_dp_vsc_sdp *vsc);
8989
void intel_write_dp_vsc_sdp(struct intel_encoder *encoder,
9090
const struct intel_crtc_state *crtc_state,
91-
struct drm_dp_vsc_sdp *vsc);
91+
const struct drm_dp_vsc_sdp *vsc);
9292
void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable,
9393
const struct intel_crtc_state *crtc_state,
9494
const struct drm_connector_state *conn_state);

drivers/gpu/drm/i915/display/intel_psr.c

Lines changed: 79 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,8 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
950950
}
951951

952952
void intel_psr_compute_config(struct intel_dp *intel_dp,
953-
struct intel_crtc_state *crtc_state)
953+
struct intel_crtc_state *crtc_state,
954+
struct drm_connector_state *conn_state)
954955
{
955956
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
956957
const struct drm_display_mode *adjusted_mode =
@@ -1002,7 +1003,10 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
10021003

10031004
crtc_state->has_psr = true;
10041005
crtc_state->has_psr2 = intel_psr2_config_valid(intel_dp, crtc_state);
1006+
10051007
crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC);
1008+
intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state, conn_state,
1009+
&crtc_state->psr_vsc);
10061010
}
10071011

10081012
void intel_psr_get_config(struct intel_encoder *encoder,
@@ -1182,8 +1186,7 @@ static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
11821186
}
11831187

11841188
static void intel_psr_enable_locked(struct intel_dp *intel_dp,
1185-
const struct intel_crtc_state *crtc_state,
1186-
const struct drm_connector_state *conn_state)
1189+
const struct intel_crtc_state *crtc_state)
11871190
{
11881191
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
11891192
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -1210,9 +1213,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
12101213

12111214
drm_dbg_kms(&dev_priv->drm, "Enabling PSR%s\n",
12121215
intel_dp->psr.psr2_enabled ? "2" : "1");
1213-
intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state, conn_state,
1214-
&intel_dp->psr.vsc);
1215-
intel_write_dp_vsc_sdp(encoder, crtc_state, &intel_dp->psr.vsc);
1216+
intel_write_dp_vsc_sdp(encoder, crtc_state, &crtc_state->psr_vsc);
12161217
intel_snps_phy_update_psr_power_state(dev_priv, phy, true);
12171218
intel_psr_enable_sink(intel_dp);
12181219
intel_psr_enable_source(intel_dp);
@@ -1222,33 +1223,6 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
12221223
intel_psr_activate(intel_dp);
12231224
}
12241225

1225-
/**
1226-
* intel_psr_enable - Enable PSR
1227-
* @intel_dp: Intel DP
1228-
* @crtc_state: new CRTC state
1229-
* @conn_state: new CONNECTOR state
1230-
*
1231-
* This function can only be called after the pipe is fully trained and enabled.
1232-
*/
1233-
void intel_psr_enable(struct intel_dp *intel_dp,
1234-
const struct intel_crtc_state *crtc_state,
1235-
const struct drm_connector_state *conn_state)
1236-
{
1237-
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
1238-
1239-
if (!CAN_PSR(intel_dp))
1240-
return;
1241-
1242-
if (!crtc_state->has_psr)
1243-
return;
1244-
1245-
drm_WARN_ON(&dev_priv->drm, dev_priv->drrs.dp);
1246-
1247-
mutex_lock(&intel_dp->psr.lock);
1248-
intel_psr_enable_locked(intel_dp, crtc_state, conn_state);
1249-
mutex_unlock(&intel_dp->psr.lock);
1250-
}
1251-
12521226
static void intel_psr_exit(struct intel_dp *intel_dp)
12531227
{
12541228
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -1734,48 +1708,92 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
17341708
return 0;
17351709
}
17361710

1737-
/**
1738-
* intel_psr_update - Update PSR state
1739-
* @intel_dp: Intel DP
1740-
* @crtc_state: new CRTC state
1741-
* @conn_state: new CONNECTOR state
1742-
*
1743-
* This functions will update PSR states, disabling, enabling or switching PSR
1744-
* version when executing fastsets. For full modeset, intel_psr_disable() and
1745-
* intel_psr_enable() should be called instead.
1746-
*/
1747-
void intel_psr_update(struct intel_dp *intel_dp,
1748-
const struct intel_crtc_state *crtc_state,
1749-
const struct drm_connector_state *conn_state)
1711+
static void _intel_psr_pre_plane_update(const struct intel_atomic_state *state,
1712+
const struct intel_crtc_state *crtc_state)
17501713
{
1751-
struct intel_psr *psr = &intel_dp->psr;
1752-
bool enable, psr2_enable;
1714+
struct intel_encoder *encoder;
17531715

1754-
if (!CAN_PSR(intel_dp))
1716+
for_each_intel_encoder_mask_with_psr(state->base.dev, encoder,
1717+
crtc_state->uapi.encoder_mask) {
1718+
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1719+
struct intel_psr *psr = &intel_dp->psr;
1720+
bool needs_to_disable = false;
1721+
1722+
mutex_lock(&psr->lock);
1723+
1724+
/*
1725+
* Reasons to disable:
1726+
* - PSR disabled in new state
1727+
* - All planes will go inactive
1728+
* - Changing between PSR versions
1729+
*/
1730+
needs_to_disable |= !crtc_state->has_psr;
1731+
needs_to_disable |= !crtc_state->active_planes;
1732+
needs_to_disable |= crtc_state->has_psr2 != psr->psr2_enabled;
1733+
1734+
if (psr->enabled && needs_to_disable)
1735+
intel_psr_disable_locked(intel_dp);
1736+
1737+
mutex_unlock(&psr->lock);
1738+
}
1739+
}
1740+
1741+
void intel_psr_pre_plane_update(const struct intel_atomic_state *state)
1742+
{
1743+
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
1744+
struct intel_crtc_state *crtc_state;
1745+
struct intel_crtc *crtc;
1746+
int i;
1747+
1748+
if (!HAS_PSR(dev_priv))
17551749
return;
17561750

1757-
mutex_lock(&intel_dp->psr.lock);
1751+
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
1752+
_intel_psr_pre_plane_update(state, crtc_state);
1753+
}
17581754

1759-
enable = crtc_state->has_psr;
1760-
psr2_enable = crtc_state->has_psr2;
1755+
static void _intel_psr_post_plane_update(const struct intel_atomic_state *state,
1756+
const struct intel_crtc_state *crtc_state)
1757+
{
1758+
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
1759+
struct intel_encoder *encoder;
1760+
1761+
if (!crtc_state->has_psr)
1762+
return;
1763+
1764+
for_each_intel_encoder_mask_with_psr(state->base.dev, encoder,
1765+
crtc_state->uapi.encoder_mask) {
1766+
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1767+
struct intel_psr *psr = &intel_dp->psr;
1768+
1769+
mutex_lock(&psr->lock);
1770+
1771+
drm_WARN_ON(&dev_priv->drm, psr->enabled && !crtc_state->active_planes);
1772+
1773+
/* Only enable if there is active planes */
1774+
if (!psr->enabled && crtc_state->active_planes)
1775+
intel_psr_enable_locked(intel_dp, crtc_state);
17611776

1762-
if (enable == psr->enabled && psr2_enable == psr->psr2_enabled &&
1763-
crtc_state->enable_psr2_sel_fetch == psr->psr2_sel_fetch_enabled) {
17641777
/* Force a PSR exit when enabling CRC to avoid CRC timeouts */
17651778
if (crtc_state->crc_enabled && psr->enabled)
17661779
psr_force_hw_tracking_exit(intel_dp);
17671780

1768-
goto unlock;
1781+
mutex_unlock(&psr->lock);
17691782
}
1783+
}
17701784

1771-
if (psr->enabled)
1772-
intel_psr_disable_locked(intel_dp);
1785+
void intel_psr_post_plane_update(const struct intel_atomic_state *state)
1786+
{
1787+
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
1788+
struct intel_crtc_state *crtc_state;
1789+
struct intel_crtc *crtc;
1790+
int i;
17731791

1774-
if (enable)
1775-
intel_psr_enable_locked(intel_dp, crtc_state, conn_state);
1792+
if (!HAS_PSR(dev_priv))
1793+
return;
17761794

1777-
unlock:
1778-
mutex_unlock(&intel_dp->psr.lock);
1795+
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
1796+
_intel_psr_post_plane_update(state, crtc_state);
17791797
}
17801798

17811799
/**

drivers/gpu/drm/i915/display/intel_psr.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,10 @@ struct intel_plane;
2020
struct intel_encoder;
2121

2222
void intel_psr_init_dpcd(struct intel_dp *intel_dp);
23-
void intel_psr_enable(struct intel_dp *intel_dp,
24-
const struct intel_crtc_state *crtc_state,
25-
const struct drm_connector_state *conn_state);
23+
void intel_psr_pre_plane_update(const struct intel_atomic_state *state);
24+
void intel_psr_post_plane_update(const struct intel_atomic_state *state);
2625
void intel_psr_disable(struct intel_dp *intel_dp,
2726
const struct intel_crtc_state *old_crtc_state);
28-
void intel_psr_update(struct intel_dp *intel_dp,
29-
const struct intel_crtc_state *crtc_state,
30-
const struct drm_connector_state *conn_state);
3127
int intel_psr_debug_set(struct intel_dp *intel_dp, u64 value);
3228
void intel_psr_invalidate(struct drm_i915_private *dev_priv,
3329
unsigned frontbuffer_bits,
@@ -37,7 +33,8 @@ void intel_psr_flush(struct drm_i915_private *dev_priv,
3733
enum fb_op_origin origin);
3834
void intel_psr_init(struct intel_dp *intel_dp);
3935
void intel_psr_compute_config(struct intel_dp *intel_dp,
40-
struct intel_crtc_state *crtc_state);
36+
struct intel_crtc_state *crtc_state,
37+
struct drm_connector_state *conn_state);
4138
void intel_psr_get_config(struct intel_encoder *encoder,
4239
struct intel_crtc_state *pipe_config);
4340
void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir);

0 commit comments

Comments
 (0)