diff mbox

[1/5] drm/i915: Read HDCP R0 thrice in case of mismatch

Message ID 1519665159-28639-2-git-send-email-ramalingam.c@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ramalingam C Feb. 26, 2018, 5:12 p.m. UTC
As per DP spec when R0 mismatch is detected, HDCP source supported
re-read the R0 atleast twice.

And For HDMI and DP minimum wait required for the R0 availability is
100mSec. So this patch changes the wait time to 100mSec but retries
twice with the time interval of 100mSec for each attempt.

DP CTS Test: 1A-06.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_hdcp.c | 34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

Comments

Sean Paul Feb. 26, 2018, 5:37 p.m. UTC | #1
On Mon, Feb 26, 2018 at 10:42:35PM +0530, Ramalingam C wrote:
> As per DP spec when R0 mismatch is detected, HDCP source supported
> re-read the R0 atleast twice.
> 
> And For HDMI and DP minimum wait required for the R0 availability is
> 100mSec. So this patch changes the wait time to 100mSec but retries
> twice with the time interval of 100mSec for each attempt.

"R0' must be available for the HDCP Transmitter to read within 100
milliseconds from the time that the HDCP Transmitter finishes writing Aksv to
the video receiver."

100ms is a minimum, waiting for 300ms is quite generous.

The retry is to account for link errors, so there's no need to include the wait
in the retry loop.

Sean

> 
> DP CTS Test: 1A-06.
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_hdcp.c | 34 ++++++++++++++++++++++------------
>  1 file changed, 22 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
> index 14ca5d3057a7..730681d2dbfb 100644
> --- a/drivers/gpu/drm/i915/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> @@ -496,25 +496,35 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
>  	}
>  
>  	/*
> -	 * Wait for R0' to become available. The spec says 100ms from Aksv, but
> -	 * some monitors can take longer than this. We'll set the timeout at
> -	 * 300ms just to be sure.
> +	 * Wait for R0' to become available. The spec says minimum 100ms from
> +	 * Aksv, but some monitors can take longer than this. So we are
> +	 * combinely waiting for 300mSec just to be sure in case of HDMI.
> +	 * DP HDCP Spec mandates the two more reattempt to read R0, incase
> +	 * of R0 mismatch.
>  	 *
>  	 * On DP, there's an R0_READY bit available but no such bit
>  	 * exists on HDMI. Since the upper-bound is the same, we'll just do
>  	 * the stupid thing instead of polling on one and not the other.
>  	 */
> -	wait_remaining_ms_from_jiffies(r0_prime_gen_start, 300);
>  
> -	ri.reg = 0;
> -	ret = shim->read_ri_prime(intel_dig_port, ri.shim);
> -	if (ret)
> -		return ret;
> -	I915_WRITE(PORT_HDCP_RPRIME(port), ri.reg);
> +	tries = 3;
> +	for (i = 0; i < tries; i++) {
> +		wait_remaining_ms_from_jiffies(r0_prime_gen_start,
> +					       100 * (i + 1));
>  
> -	/* Wait for Ri prime match */
> -	if (wait_for(I915_READ(PORT_HDCP_STATUS(port)) &
> -		     (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)) {
> +		ri.reg = 0;
> +		ret = shim->read_ri_prime(intel_dig_port, ri.shim);
> +		if (ret)
> +			return ret;
> +		I915_WRITE(PORT_HDCP_RPRIME(port), ri.reg);
> +
> +		/* Wait for Ri prime match */
> +		if (!wait_for(I915_READ(PORT_HDCP_STATUS(port)) &
> +		    (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1))
> +			break;
> +	}
> +
> +	if (i == tries) {
>  		DRM_ERROR("Timed out waiting for Ri prime match (%x)\n",
>  			  I915_READ(PORT_HDCP_STATUS(port)));
>  		return -ETIMEDOUT;
> -- 
> 2.7.4
>
Ramalingam C Feb. 27, 2018, 11:38 a.m. UTC | #2
On Monday 26 February 2018 11:07 PM, Sean Paul wrote:
> On Mon, Feb 26, 2018 at 10:42:35PM +0530, Ramalingam C wrote:
>> As per DP spec when R0 mismatch is detected, HDCP source supported
>> re-read the R0 atleast twice.
>>
>> And For HDMI and DP minimum wait required for the R0 availability is
>> 100mSec. So this patch changes the wait time to 100mSec but retries
>> twice with the time interval of 100mSec for each attempt.
> "R0' must be available for the HDCP Transmitter to read within 100
> milliseconds from the time that the HDCP Transmitter finishes writing Aksv to
> the video receiver."
>
> 100ms is a minimum, waiting for 300ms is quite generous.

Yes Even with this patch, total wait time for R0 will be 300 mSec only. Splitted into 3 100mSec wait one in each loop.
First loop waits for 100mSec from AKSV write, second loop waits for 200mSec from AKSV write and
third is 300mSec from AKSV write.

This way if a monitor prepares the R0 in 100 mSec, we wont simply wait for 300mSec.
And also we fulfill DP compliance expectation of three attempts to read valid R0.

--Ram

>
> The retry is to account for link errors, so there's no need to include the wait
> in the retry loop.
>
> Sean
>
>> DP CTS Test: 1A-06.
>>
>> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_hdcp.c | 34 ++++++++++++++++++++++------------
>>   1 file changed, 22 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
>> index 14ca5d3057a7..730681d2dbfb 100644
>> --- a/drivers/gpu/drm/i915/intel_hdcp.c
>> +++ b/drivers/gpu/drm/i915/intel_hdcp.c
>> @@ -496,25 +496,35 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
>>   	}
>>   
>>   	/*
>> -	 * Wait for R0' to become available. The spec says 100ms from Aksv, but
>> -	 * some monitors can take longer than this. We'll set the timeout at
>> -	 * 300ms just to be sure.
>> +	 * Wait for R0' to become available. The spec says minimum 100ms from
>> +	 * Aksv, but some monitors can take longer than this. So we are
>> +	 * combinely waiting for 300mSec just to be sure in case of HDMI.
>> +	 * DP HDCP Spec mandates the two more reattempt to read R0, incase
>> +	 * of R0 mismatch.
>>   	 *
>>   	 * On DP, there's an R0_READY bit available but no such bit
>>   	 * exists on HDMI. Since the upper-bound is the same, we'll just do
>>   	 * the stupid thing instead of polling on one and not the other.
>>   	 */
>> -	wait_remaining_ms_from_jiffies(r0_prime_gen_start, 300);
>>   
>> -	ri.reg = 0;
>> -	ret = shim->read_ri_prime(intel_dig_port, ri.shim);
>> -	if (ret)
>> -		return ret;
>> -	I915_WRITE(PORT_HDCP_RPRIME(port), ri.reg);
>> +	tries = 3;
>> +	for (i = 0; i < tries; i++) {
>> +		wait_remaining_ms_from_jiffies(r0_prime_gen_start,
>> +					       100 * (i + 1));
>>   
>> -	/* Wait for Ri prime match */
>> -	if (wait_for(I915_READ(PORT_HDCP_STATUS(port)) &
>> -		     (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)) {
>> +		ri.reg = 0;
>> +		ret = shim->read_ri_prime(intel_dig_port, ri.shim);
>> +		if (ret)
>> +			return ret;
>> +		I915_WRITE(PORT_HDCP_RPRIME(port), ri.reg);
>> +
>> +		/* Wait for Ri prime match */
>> +		if (!wait_for(I915_READ(PORT_HDCP_STATUS(port)) &
>> +		    (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1))
>> +			break;
>> +	}
>> +
>> +	if (i == tries) {
>>   		DRM_ERROR("Timed out waiting for Ri prime match (%x)\n",
>>   			  I915_READ(PORT_HDCP_STATUS(port)));
>>   		return -ETIMEDOUT;
>> -- 
>> 2.7.4
>>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 14ca5d3057a7..730681d2dbfb 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -496,25 +496,35 @@  static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
 	}
 
 	/*
-	 * Wait for R0' to become available. The spec says 100ms from Aksv, but
-	 * some monitors can take longer than this. We'll set the timeout at
-	 * 300ms just to be sure.
+	 * Wait for R0' to become available. The spec says minimum 100ms from
+	 * Aksv, but some monitors can take longer than this. So we are
+	 * combinely waiting for 300mSec just to be sure in case of HDMI.
+	 * DP HDCP Spec mandates the two more reattempt to read R0, incase
+	 * of R0 mismatch.
 	 *
 	 * On DP, there's an R0_READY bit available but no such bit
 	 * exists on HDMI. Since the upper-bound is the same, we'll just do
 	 * the stupid thing instead of polling on one and not the other.
 	 */
-	wait_remaining_ms_from_jiffies(r0_prime_gen_start, 300);
 
-	ri.reg = 0;
-	ret = shim->read_ri_prime(intel_dig_port, ri.shim);
-	if (ret)
-		return ret;
-	I915_WRITE(PORT_HDCP_RPRIME(port), ri.reg);
+	tries = 3;
+	for (i = 0; i < tries; i++) {
+		wait_remaining_ms_from_jiffies(r0_prime_gen_start,
+					       100 * (i + 1));
 
-	/* Wait for Ri prime match */
-	if (wait_for(I915_READ(PORT_HDCP_STATUS(port)) &
-		     (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)) {
+		ri.reg = 0;
+		ret = shim->read_ri_prime(intel_dig_port, ri.shim);
+		if (ret)
+			return ret;
+		I915_WRITE(PORT_HDCP_RPRIME(port), ri.reg);
+
+		/* Wait for Ri prime match */
+		if (!wait_for(I915_READ(PORT_HDCP_STATUS(port)) &
+		    (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1))
+			break;
+	}
+
+	if (i == tries) {
 		DRM_ERROR("Timed out waiting for Ri prime match (%x)\n",
 			  I915_READ(PORT_HDCP_STATUS(port)));
 		return -ETIMEDOUT;