Commit ef75c25e authored by Animesh Manna's avatar Animesh Manna

drm/i915/panelreplay: Debugfs support for panel replay

Add debugfs support which will print source and sink status
per connector basis. Existing i915_psr_status and
i915_psr_sink_status will be used to get the source and
sink status of panel replay.

v1: Initial version. [rb-ed by Arun]
v2: Added check for DP 2.0 and connector type in connector_debugfs_add().
v3: Optimization and cosmetic changes. [Jouni]

Cc: Jouni Högander <jouni.hogander@intel.com>
Cc: Arun R Murthy <arun.r.murthy@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: default avatarArun R Murthy <arun.r.murthy@intel.com>
Signed-off-by: default avatarAnimesh Manna <animesh.manna@intel.com>
Reviewed-by: default avatarJouni Högander <jouni.hogander@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231108072303.3414118-7-animesh.manna@intel.com
parent 8a4353d0
......@@ -2865,12 +2865,19 @@ static int psr_get_status_and_error_status(struct intel_dp *intel_dp,
{
struct drm_dp_aux *aux = &intel_dp->aux;
int ret;
unsigned int offset;
ret = drm_dp_dpcd_readb(aux, DP_PSR_STATUS, status);
offset = intel_dp->psr.panel_replay_enabled ?
DP_SINK_DEVICE_PR_AND_FRAME_LOCK_STATUS : DP_PSR_STATUS;
ret = drm_dp_dpcd_readb(aux, offset, status);
if (ret != 1)
return ret;
ret = drm_dp_dpcd_readb(aux, DP_PSR_ERROR_STATUS, error_status);
offset = intel_dp->psr.panel_replay_enabled ?
DP_PANEL_REPLAY_ERROR_STATUS : DP_PSR_ERROR_STATUS;
ret = drm_dp_dpcd_readb(aux, offset, error_status);
if (ret != 1)
return ret;
......@@ -3091,7 +3098,7 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
status = live_status[status_val];
}
seq_printf(m, "Source PSR status: %s [0x%08x]\n", status, val);
seq_printf(m, "Source PSR/PanelReplay status: %s [0x%08x]\n", status, val);
}
static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
......@@ -3104,18 +3111,22 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
bool enabled;
u32 val;
seq_printf(m, "Sink support: %s", str_yes_no(psr->sink_support));
seq_printf(m, "Sink support: PSR = %s",
str_yes_no(psr->sink_support));
if (psr->sink_support)
seq_printf(m, " [0x%02x]", intel_dp->psr_dpcd[0]);
seq_puts(m, "\n");
seq_printf(m, ", Panel Replay = %s\n", str_yes_no(psr->sink_panel_replay_support));
if (!psr->sink_support)
if (!(psr->sink_support || psr->sink_panel_replay_support))
return 0;
wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
mutex_lock(&psr->lock);
if (psr->enabled)
if (psr->panel_replay_enabled)
status = "Panel Replay Enabled";
else if (psr->enabled)
status = psr->psr2_enabled ? "PSR2 enabled" : "PSR1 enabled";
else
status = "disabled";
......@@ -3128,14 +3139,17 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
goto unlock;
}
if (psr->psr2_enabled) {
if (psr->panel_replay_enabled) {
val = intel_de_read(dev_priv, TRANS_DP2_CTL(cpu_transcoder));
enabled = val & TRANS_DP2_PANEL_REPLAY_ENABLE;
} else if (psr->psr2_enabled) {
val = intel_de_read(dev_priv, EDP_PSR2_CTL(cpu_transcoder));
enabled = val & EDP_PSR2_ENABLE;
} else {
val = intel_de_read(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder));
enabled = val & EDP_PSR_ENABLE;
}
seq_printf(m, "Source PSR ctl: %s [0x%08x]\n",
seq_printf(m, "Source PSR/PanelReplay ctl: %s [0x%08x]\n",
str_enabled_disabled(enabled), val);
psr_source_status(intel_dp, m);
seq_printf(m, "Busy frontbuffer bits: 0x%08x\n",
......@@ -3273,6 +3287,16 @@ void intel_psr_debugfs_register(struct drm_i915_private *i915)
i915, &i915_edp_psr_status_fops);
}
static const char *psr_mode_str(struct intel_dp *intel_dp)
{
if (intel_dp->psr.panel_replay_enabled)
return "PANEL-REPLAY";
else if (intel_dp->psr.enabled)
return "PSR";
return "unknown";
}
static int i915_psr_sink_status_show(struct seq_file *m, void *data)
{
struct intel_connector *connector = m->private;
......@@ -3287,12 +3311,19 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
"reserved",
"sink internal error",
};
static const char * const panel_replay_status[] = {
"Sink device frame is locked to the Source device",
"Sink device is coasting, using the VTotal target",
"Sink device is governing the frame rate (frame rate unlock is granted)",
"Sink device in the process of re-locking with the Source device",
};
const char *str;
int ret;
u8 status, error_status;
u32 idx;
if (!CAN_PSR(intel_dp)) {
seq_puts(m, "PSR Unsupported\n");
if (!(CAN_PSR(intel_dp) || CAN_PANEL_REPLAY(intel_dp))) {
seq_puts(m, "PSR/Panel-Replay Unsupported\n");
return -ENODEV;
}
......@@ -3303,15 +3334,20 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
if (ret)
return ret;
status &= DP_PSR_SINK_STATE_MASK;
if (status < ARRAY_SIZE(sink_status))
str = sink_status[status];
else
str = "unknown";
str = "unknown";
if (intel_dp->psr.panel_replay_enabled) {
idx = (status & DP_SINK_FRAME_LOCKED_MASK) >> DP_SINK_FRAME_LOCKED_SHIFT;
if (idx < ARRAY_SIZE(panel_replay_status))
str = panel_replay_status[idx];
} else if (intel_dp->psr.enabled) {
idx = status & DP_PSR_SINK_STATE_MASK;
if (idx < ARRAY_SIZE(sink_status))
str = sink_status[idx];
}
seq_printf(m, "Sink PSR status: 0x%x [%s]\n", status, str);
seq_printf(m, "Sink %s status: 0x%x [%s]\n", psr_mode_str(intel_dp), status, str);
seq_printf(m, "Sink PSR error status: 0x%x", error_status);
seq_printf(m, "Sink %s error status: 0x%x", psr_mode_str(intel_dp), error_status);
if (error_status & (DP_PSR_RFB_STORAGE_ERROR |
DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR |
......@@ -3320,11 +3356,11 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
else
seq_puts(m, "\n");
if (error_status & DP_PSR_RFB_STORAGE_ERROR)
seq_puts(m, "\tPSR RFB storage error\n");
seq_printf(m, "\t%s RFB storage error\n", psr_mode_str(intel_dp));
if (error_status & DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR)
seq_puts(m, "\tPSR VSC SDP uncorrectable error\n");
seq_printf(m, "\t%s VSC SDP uncorrectable error\n", psr_mode_str(intel_dp));
if (error_status & DP_PSR_LINK_CRC_ERROR)
seq_puts(m, "\tPSR Link CRC error\n");
seq_printf(m, "\t%s Link CRC error\n", psr_mode_str(intel_dp));
return ret;
}
......@@ -3344,13 +3380,16 @@ void intel_psr_connector_debugfs_add(struct intel_connector *connector)
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct dentry *root = connector->base.debugfs_entry;
if (connector->base.connector_type != DRM_MODE_CONNECTOR_eDP)
return;
if (connector->base.connector_type != DRM_MODE_CONNECTOR_eDP) {
if (!(HAS_DP20(i915) &&
connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort))
return;
}
debugfs_create_file("i915_psr_sink_status", 0444, root,
connector, &i915_psr_sink_status_fops);
if (HAS_PSR(i915))
if (HAS_PSR(i915) || HAS_DP20(i915))
debugfs_create_file("i915_psr_status", 0444, root,
connector, &i915_psr_status_fops);
}
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