Skip to content

Commit 234b402

Browse files
elongbugzehortigoza
authored andcommitted
drm/i915/display: Introduce new intel_psr_pause/resume function
This introduces the following function that can exit and activate a psr source when intel_psr is already enabled. - intel_psr_pause(): Pause current PSR. It deactivates current psr state. - intel_psr_resume(): Resume paused PSR. It activates paused psr state. v2: Address Jose's review comment. - Remove unneeded changes around the intel_psr_enable(). - Add intel_psr_post_exit() which processes waiting until PSR is idle and WA for SelectiveFetch. v3: Address Jose's review comment. - Rename intel_psr_post_exit() to intel_psr_wait_exit_locked(). - Move WA_1408330847 to intel_psr_disable_locked() - If the PSR is paused by an explicit intel_psr_paused() call, make the intel_psr_flush() not to activate PSR. v4: Address Jose's review comment. - In order to avoid the scenario of PSR is not active but there is a scheduled psr->work, it changes the check routine of intel_psr_pause() for PSR's enablement from "psr->active" to "psr->enable". Cc: José Roberto de Souza <[email protected]> Cc: Stanislav Lisovskiy <[email protected]> Cc: Ville Syrjälä <[email protected]> Signed-off-by: Gwan-gyeong Mun <[email protected]> Signed-off-by: Matt Roper <[email protected]> Reviewed-by: José Roberto de Souza <[email protected]> Signed-off-by: José Roberto de Souza <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 31b77c7 commit 234b402

File tree

3 files changed

+86
-11
lines changed

3 files changed

+86
-11
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,6 +1482,7 @@ struct intel_psr {
14821482
bool sink_support;
14831483
bool source_support;
14841484
bool enabled;
1485+
bool paused;
14851486
enum pipe pipe;
14861487
enum transcoder transcoder;
14871488
bool active;

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

Lines changed: 83 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
11131113
intel_psr_enable_sink(intel_dp);
11141114
intel_psr_enable_source(intel_dp);
11151115
intel_dp->psr.enabled = true;
1116+
intel_dp->psr.paused = false;
11161117

11171118
intel_psr_activate(intel_dp);
11181119
}
@@ -1182,22 +1183,12 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
11821183
intel_dp->psr.active = false;
11831184
}
11841185

1185-
static void intel_psr_disable_locked(struct intel_dp *intel_dp)
1186+
static void intel_psr_wait_exit_locked(struct intel_dp *intel_dp)
11861187
{
11871188
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
11881189
i915_reg_t psr_status;
11891190
u32 psr_status_mask;
11901191

1191-
lockdep_assert_held(&intel_dp->psr.lock);
1192-
1193-
if (!intel_dp->psr.enabled)
1194-
return;
1195-
1196-
drm_dbg_kms(&dev_priv->drm, "Disabling PSR%s\n",
1197-
intel_dp->psr.psr2_enabled ? "2" : "1");
1198-
1199-
intel_psr_exit(intel_dp);
1200-
12011192
if (intel_dp->psr.psr2_enabled) {
12021193
psr_status = EDP_PSR2_STATUS(intel_dp->psr.transcoder);
12031194
psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
@@ -1210,6 +1201,22 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
12101201
if (intel_de_wait_for_clear(dev_priv, psr_status,
12111202
psr_status_mask, 2000))
12121203
drm_err(&dev_priv->drm, "Timed out waiting PSR idle state\n");
1204+
}
1205+
1206+
static void intel_psr_disable_locked(struct intel_dp *intel_dp)
1207+
{
1208+
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
1209+
1210+
lockdep_assert_held(&intel_dp->psr.lock);
1211+
1212+
if (!intel_dp->psr.enabled)
1213+
return;
1214+
1215+
drm_dbg_kms(&dev_priv->drm, "Disabling PSR%s\n",
1216+
intel_dp->psr.psr2_enabled ? "2" : "1");
1217+
1218+
intel_psr_exit(intel_dp);
1219+
intel_psr_wait_exit_locked(intel_dp);
12131220

12141221
/* WA 1408330847 */
12151222
if (intel_dp->psr.psr2_sel_fetch_enabled &&
@@ -1254,6 +1261,61 @@ void intel_psr_disable(struct intel_dp *intel_dp,
12541261
cancel_delayed_work_sync(&intel_dp->psr.dc3co_work);
12551262
}
12561263

1264+
/**
1265+
* intel_psr_pause - Pause PSR
1266+
* @intel_dp: Intel DP
1267+
*
1268+
* This function need to be called after enabling psr.
1269+
*/
1270+
void intel_psr_pause(struct intel_dp *intel_dp)
1271+
{
1272+
struct intel_psr *psr = &intel_dp->psr;
1273+
1274+
if (!CAN_PSR(intel_dp))
1275+
return;
1276+
1277+
mutex_lock(&psr->lock);
1278+
1279+
if (!psr->enabled) {
1280+
mutex_unlock(&psr->lock);
1281+
return;
1282+
}
1283+
1284+
intel_psr_exit(intel_dp);
1285+
intel_psr_wait_exit_locked(intel_dp);
1286+
psr->paused = true;
1287+
1288+
mutex_unlock(&psr->lock);
1289+
1290+
cancel_work_sync(&psr->work);
1291+
cancel_delayed_work_sync(&psr->dc3co_work);
1292+
}
1293+
1294+
/**
1295+
* intel_psr_resume - Resume PSR
1296+
* @intel_dp: Intel DP
1297+
*
1298+
* This function need to be called after pausing psr.
1299+
*/
1300+
void intel_psr_resume(struct intel_dp *intel_dp)
1301+
{
1302+
struct intel_psr *psr = &intel_dp->psr;
1303+
1304+
if (!CAN_PSR(intel_dp))
1305+
return;
1306+
1307+
mutex_lock(&psr->lock);
1308+
1309+
if (!psr->paused)
1310+
goto unlock;
1311+
1312+
psr->paused = false;
1313+
intel_psr_activate(intel_dp);
1314+
1315+
unlock:
1316+
mutex_unlock(&psr->lock);
1317+
}
1318+
12571319
static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
12581320
{
12591321
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -1908,6 +1970,16 @@ void intel_psr_flush(struct drm_i915_private *dev_priv,
19081970
INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
19091971
intel_dp->psr.busy_frontbuffer_bits &= ~pipe_frontbuffer_bits;
19101972

1973+
/*
1974+
* If the PSR is paused by an explicit intel_psr_paused() call,
1975+
* we have to ensure that the PSR is not activated until
1976+
* intel_psr_resume() is called.
1977+
*/
1978+
if (intel_dp->psr.paused) {
1979+
mutex_unlock(&intel_dp->psr.lock);
1980+
continue;
1981+
}
1982+
19111983
/* By definition flush = invalidate + flush */
19121984
if (pipe_frontbuffer_bits)
19131985
psr_force_hw_tracking_exit(intel_dp);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,7 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane,
5151
const struct intel_crtc_state *crtc_state,
5252
const struct intel_plane_state *plane_state,
5353
int color_plane);
54+
void intel_psr_pause(struct intel_dp *intel_dp);
55+
void intel_psr_resume(struct intel_dp *intel_dp);
5456

5557
#endif /* __INTEL_PSR_H__ */

0 commit comments

Comments
 (0)