Commit d210d8c0 authored by Jouni Högander's avatar Jouni Högander

drm/i915/psr: Modify intel_dp_get_su_granularity to support panel replay

Currently intel_dp_get_su_granularity doesn't support panel replay.
This fix modifies it to support panel replay as well.

v4:
  - use drm_dp_dpcd_readb instead of drm_dp_dpcd_read
  - ensure return value is 0 if drm_dp_dpcd_readb fails
v3: use correct offset for DP_PANEL_PANEL_REPLAY_CAPABILITY
v2: rely on PSR definitions on common bits
Signed-off-by: default avatarJouni Högander <jouni.hogander@intel.com>
Reviewed-by: default avatarAnimesh Manna <animesh.manna@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240510093823.3146455-8-jouni.hogander@intel.com
parent 3a745dfc
...@@ -468,6 +468,40 @@ static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp) ...@@ -468,6 +468,40 @@ static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp)
return val; return val;
} }
static u8 intel_dp_get_su_capability(struct intel_dp *intel_dp)
{
u8 su_capability = 0;
if (intel_dp->psr.sink_panel_replay_su_support)
drm_dp_dpcd_readb(&intel_dp->aux,
DP_PANEL_PANEL_REPLAY_CAPABILITY,
&su_capability);
else
su_capability = intel_dp->psr_dpcd[1];
return su_capability;
}
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_PSR2_SU_X_GRANULARITY;
}
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_PSR2_SU_Y_GRANULARITY;
}
/*
* Note: Bits related to granularity are same in panel replay and psr
* registers. Rely on PSR definitions on these "common" bits.
*/
static void intel_dp_get_su_granularity(struct intel_dp *intel_dp) static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
{ {
struct drm_i915_private *i915 = dp_to_i915(intel_dp); struct drm_i915_private *i915 = dp_to_i915(intel_dp);
...@@ -475,18 +509,29 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp) ...@@ -475,18 +509,29 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
u16 w; u16 w;
u8 y; u8 y;
/* If sink don't have specific granularity requirements set legacy ones */ /*
if (!(intel_dp->psr_dpcd[1] & DP_PSR2_SU_GRANULARITY_REQUIRED)) { * TODO: Do we need to take into account panel supporting both PSR and
* Panel replay?
*/
/*
* If sink don't have specific granularity requirements set legacy
* ones.
*/
if (!(intel_dp_get_su_capability(intel_dp) &
DP_PSR2_SU_GRANULARITY_REQUIRED)) {
/* As PSR2 HW sends full lines, we do not care about x granularity */ /* As PSR2 HW sends full lines, we do not care about x granularity */
w = 4; w = 4;
y = 4; y = 4;
goto exit; goto exit;
} }
r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_X_GRANULARITY, &w, 2); r = drm_dp_dpcd_read(&intel_dp->aux,
intel_dp_get_su_x_granularity_offset(intel_dp),
&w, 2);
if (r != 2) if (r != 2)
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
"Unable to read DP_PSR2_SU_X_GRANULARITY\n"); "Unable to read selective update x granularity\n");
/* /*
* Spec says that if the value read is 0 the default granularity should * Spec says that if the value read is 0 the default granularity should
* be used instead. * be used instead.
...@@ -494,10 +539,12 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp) ...@@ -494,10 +539,12 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
if (r != 2 || w == 0) if (r != 2 || w == 0)
w = 4; w = 4;
r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_Y_GRANULARITY, &y, 1); r = drm_dp_dpcd_read(&intel_dp->aux,
intel_dp_get_su_y_granularity_offset(intel_dp),
&y, 1);
if (r != 1) { if (r != 1) {
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
"Unable to read DP_PSR2_SU_Y_GRANULARITY\n"); "Unable to read selective update y granularity\n");
y = 4; y = 4;
} }
if (y == 0) if (y == 0)
...@@ -590,7 +637,8 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) ...@@ -590,7 +637,8 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
if (intel_dp->psr_dpcd[0]) if (intel_dp->psr_dpcd[0])
_psr_init_dpcd(intel_dp); _psr_init_dpcd(intel_dp);
if (intel_dp->psr.sink_psr2_support) if (intel_dp->psr.sink_psr2_support ||
intel_dp->psr.sink_panel_replay_su_support)
intel_dp_get_su_granularity(intel_dp); intel_dp_get_su_granularity(intel_dp);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment