[PATCH 24/43] drm/i915: wait for cp_irq

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux