Skip to content

Commit

Permalink
drm/i915: Add support for enabling link status and recovery
Browse files Browse the repository at this point in the history
In this patch enables support for detecting link failures between
PCON and HDMI sink in i915 driver. HDMI link loss indication to
upstream DP source is indicated via IRQ_HPD. This is followed by
reading of HDMI link configuration status (HDMI_TX_LINK_ACTIVE_STATUS).
If the PCON → HDMI 2.1 link status is off; reinitiate frl link
training to recover. Also, report HDMI FRL link error count range for
each individual FRL active lane is indicated by
DOWNSTREAM_HDMI_ERROR_STATUS_LN registers.

v2: Checked for dpcd read and write failures and added debug message.
(Uma Shankar)

v3: Rearranged code to re-start FRL link training or fall back to
TMDS mode.

v4: Resused function to check frl which inturn restarts FRL and
fallback to TMDS mode.

Signed-off-by: Swati Sharma <swati2.sharma@intel.com>
Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com> (v2)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201218103723.30844-12-ankit.k.nautiyal@intel.com
  • Loading branch information
Swati Sharma authored and Jani Nikula committed Dec 22, 2020
1 parent 4f3dd47 commit 9488a03
Showing 1 changed file with 50 additions and 3 deletions.
53 changes: 50 additions & 3 deletions drivers/gpu/drm/i915/display/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -6001,6 +6001,28 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
return link_ok;
}

static void
intel_dp_handle_hdmi_link_status_change(struct intel_dp *intel_dp)
{
bool is_active;
u8 buf = 0;

is_active = drm_dp_pcon_hdmi_link_active(&intel_dp->aux);
if (intel_dp->frl.is_trained && !is_active) {
if (drm_dp_dpcd_readb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, &buf) < 0)
return;

buf &= ~DP_PCON_ENABLE_HDMI_LINK;
if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_PCON_HDMI_LINK_CONFIG_1, buf) < 0)
return;

drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, &intel_dp->attached_connector->base);

/* Restart FRL training or fall back to TMDS mode */
intel_dp_check_frl_training(intel_dp);
}
}

static bool
intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
{
Expand Down Expand Up @@ -6366,7 +6388,7 @@ intel_dp_hotplug(struct intel_encoder *encoder,
return state;
}

static void intel_dp_check_service_irq(struct intel_dp *intel_dp)
static void intel_dp_check_device_service_irq(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 val;
Expand All @@ -6390,6 +6412,30 @@ static void intel_dp_check_service_irq(struct intel_dp *intel_dp)
drm_dbg_kms(&i915->drm, "Sink specific irq unhandled\n");
}

static void intel_dp_check_link_service_irq(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 val;

if (intel_dp->dpcd[DP_DPCD_REV] < 0x11)
return;

if (drm_dp_dpcd_readb(&intel_dp->aux,
DP_LINK_SERVICE_IRQ_VECTOR_ESI0, &val) != 1 || !val) {
drm_dbg_kms(&i915->drm, "Error in reading link service irq vector\n");
return;
}

if (drm_dp_dpcd_writeb(&intel_dp->aux,
DP_LINK_SERVICE_IRQ_VECTOR_ESI0, val) != 1) {
drm_dbg_kms(&i915->drm, "Error in writing link service irq vector\n");
return;
}

if (val & HDMI_LINK_STATUS_CHANGED)
intel_dp_handle_hdmi_link_status_change(intel_dp);
}

/*
* According to DP spec
* 5.1.2:
Expand Down Expand Up @@ -6429,7 +6475,8 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
return false;
}

intel_dp_check_service_irq(intel_dp);
intel_dp_check_device_service_irq(intel_dp);
intel_dp_check_link_service_irq(intel_dp);

/* Handle CEC interrupts, if any */
drm_dp_cec_irq(&intel_dp->aux);
Expand Down Expand Up @@ -6859,7 +6906,7 @@ intel_dp_detect(struct drm_connector *connector,
to_intel_connector(connector)->detect_edid)
status = connector_status_connected;

intel_dp_check_service_irq(intel_dp);
intel_dp_check_device_service_irq(intel_dp);

out:
if (status != connector_status_connected && !intel_dp->is_mst)
Expand Down

0 comments on commit 9488a03

Please sign in to comment.