DP HDCP asserts the CP_IRQ to indicate the msg availability and auth state change at the panel. Implements a completion structure to communicate the cp_irq assertion and provides a function to wait for cp_irq with a timeout. This can be used for implementation of both HDCP1.4 and HDCP2.2 Signed-off-by: Ramalingam C <ramalingam.c@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_dp.c | 28 ++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_drv.h | 3 +++ drivers/gpu/drm/i915/intel_hdcp.c | 1 + 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 80476689754f..8847f1a36504 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4402,6 +4402,7 @@ static bool intel_dp_short_pulse(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); + struct intel_connector *connector = intel_dp->attached_connector; u8 sink_irq_vector = 0; u8 old_sink_count = intel_dp->sink_count; bool ret; @@ -4436,8 +4437,13 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) if (sink_irq_vector & DP_AUTOMATED_TEST_REQUEST) intel_dp_handle_test_request(intel_dp); - if (sink_irq_vector & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ)) - DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); + if (sink_irq_vector & DP_CP_IRQ) { + if (connector->hdcp) + complete(&connector->hdcp->cp_irq_recved); + } + + if (sink_irq_vector & DP_SINK_SPECIFIC_IRQ) + DRM_DEBUG_DRIVER("Sink specific irq unhandled\n"); } intel_dp_check_link_status(intel_dp); @@ -5049,6 +5055,24 @@ void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) pps_unlock(intel_dp); } +static int wait_for_cp_irq(struct completion *cp_irq_recved, int timeout) +{ + long ret; + + if (completion_done(cp_irq_recved)) + reinit_completion(cp_irq_recved); + + ret = wait_for_completion_interruptible_timeout(cp_irq_recved, + msecs_to_jiffies( + timeout)); + reinit_completion(cp_irq_recved); + if (ret < 0) + return (int)ret; + else if (!ret) + return -ETIMEDOUT; + return 0; +} + static int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port, u8 *an) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5b170ff7ec14..1c0d324c1044 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -384,6 +384,9 @@ struct intel_hdcp { struct delayed_work hdcp_check_work; struct work_struct hdcp_prop_work; struct work_struct hdcp_enable_work; + + /* To indicate the assertion of CP_IRQ */ + struct completion cp_irq_recved; }; struct intel_connector { diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index 9147fb17a9fc..31e1af5b43ec 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -695,6 +695,7 @@ int intel_hdcp_init(struct intel_connector *connector, INIT_WORK(&hdcp->hdcp_prop_work, intel_hdcp_prop_work); INIT_WORK(&hdcp->hdcp_enable_work, intel_hdcp_enable_work); + init_completion(&hdcp->cp_irq_recved); connector->hdcp = hdcp; return 0; -- 2.7.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx