diff mbox

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

Message ID 1518617638-21684-25-git-send-email-ramalingam.c@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ramalingam C Feb. 14, 2018, 2:13 p.m. UTC
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@intel.com>
---
 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(-)

Comments

Sean Paul Feb. 22, 2018, 3:46 p.m. UTC | #1
On Wed, Feb 14, 2018 at 07:43:39PM +0530, Ramalingam C wrote:
> 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
> 

But it's not. Please introduce code in the same patch as when it's used.

> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  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
>
Ramalingam C Feb. 26, 2018, 5:49 a.m. UTC | #2
On Thursday 22 February 2018 09:16 PM, Sean Paul wrote:
> On Wed, Feb 14, 2018 at 07:43:39PM +0530, Ramalingam C wrote:
>> 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
>>
> But it's not. Please introduce code in the same patch as when it's used.
Wanted to keep this as independent preparation patch for both versions.
Anyway i will squash it with the 2.2 patch that needs this implementation.

Thanks
--Ram
>
>> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
>> ---
>>   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
>>
diff mbox

Patch

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;