diff mbox series

[v4,13/13] drm/i915: Populate downstream info for HDCP

Message ID 20190405084302.5548-14-ramalingam.c@intel.com (mailing list archive)
State New, archived
Headers show
Series HDCP2.2 Phase II | expand

Commit Message

Ramalingam C April 5, 2019, 8:43 a.m. UTC
Implements drm blob property content_protection_downstream_info
property on HDCP capable connectors.

Downstream topology info is gathered across authentication stages
and stored in intel_hdcp. When HDCP authentication is complete,
new blob with latest downstream topology information is updated to
content_protection_downstream_info property.

v2:
  %s/cp_downstream/content_protection_downstream [daniel]
v3:
  %s/content_protection_downstream/hdcp_topology [daniel]
v4:
  Rebased.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h  |  2 +
 drivers/gpu/drm/i915/intel_hdcp.c | 87 ++++++++++++++++++++++++++-----
 include/drm/drm_hdcp.h            |  1 +
 3 files changed, 76 insertions(+), 14 deletions(-)

Comments

Ramalingam C April 5, 2019, 12:03 p.m. UTC | #1
On 2019-04-05 at 14:13:02 +0530, Ramalingam C wrote:
> Implements drm blob property content_protection_downstream_info
> property on HDCP capable connectors.
> 
> Downstream topology info is gathered across authentication stages
> and stored in intel_hdcp. When HDCP authentication is complete,
> new blob with latest downstream topology information is updated to
> content_protection_downstream_info property.
> 
> v2:
>   %s/cp_downstream/content_protection_downstream [daniel]
> v3:
>   %s/content_protection_downstream/hdcp_topology [daniel]
> v4:
>   Rebased.
Daniel,

Hope I have done enough explicit padding struct hdcp_topology_info.
Please correct me if i am still missing something.

For populating the structure for the blob, as you sugegsted this patch
is not using the separate functions. IMHO I feel usage is very minimal,
separate functions might not be justified here. Hope you are fine with
that.

-Ram
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_drv.h  |  2 +
>  drivers/gpu/drm/i915/intel_hdcp.c | 87 ++++++++++++++++++++++++++-----
>  include/drm/drm_hdcp.h            |  1 +
>  3 files changed, 76 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index e387e842f414..6a321a56ce42 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -482,6 +482,8 @@ struct intel_hdcp {
>  	wait_queue_head_t cp_irq_queue;
>  	atomic_t cp_irq_count;
>  	int cp_irq_count_cached;
> +
> +	struct hdcp_topology_info *topology_info;
>  };
>  
>  struct intel_connector {
> diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
> index f70f1e98e4ae..6993bb9ecd0b 100644
> --- a/drivers/gpu/drm/i915/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> @@ -490,9 +490,10 @@ int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port,
>  
>  /* Implements Part 2 of the HDCP authorization procedure */
>  static
> -int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
> -			       const struct intel_hdcp_shim *shim)
> +int intel_hdcp_auth_downstream(struct intel_hdcp *hdcp,
> +			       struct intel_digital_port *intel_dig_port)
>  {
> +	const struct intel_hdcp_shim *shim = hdcp->shim;
>  	u8 bstatus[2], num_downstream, *ksv_fifo;
>  	int ret, i, tries = 3;
>  
> @@ -523,6 +524,9 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
>  	if (num_downstream == 0)
>  		return -EINVAL;
>  
> +	hdcp->topology_info->device_count = num_downstream;
> +	hdcp->topology_info->depth = DRM_HDCP_DEPTH(bstatus[1]);
> +
>  	ksv_fifo = kcalloc(DRM_HDCP_KSV_LEN, num_downstream, GFP_KERNEL);
>  	if (!ksv_fifo)
>  		return -ENOMEM;
> @@ -536,6 +540,8 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
>  		return -EPERM;
>  	}
>  
> +	memcpy(hdcp->topology_info->ksv_list, ksv_fifo,
> +	       num_downstream * DRM_HDCP_KSV_LEN);
>  	/*
>  	 * When V prime mismatches, DP Spec mandates re-read of
>  	 * V prime atleast twice.
> @@ -562,9 +568,11 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
>  }
>  
>  /* Implements Part 1 of the HDCP authorization procedure */
> -static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
> -			   const struct intel_hdcp_shim *shim)
> +static int intel_hdcp_auth(struct intel_connector *connector)
>  {
> +	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
> +	struct intel_hdcp *hdcp = &connector->hdcp;
> +	const struct intel_hdcp_shim *shim = hdcp->shim;
>  	struct drm_i915_private *dev_priv;
>  	enum port port;
>  	unsigned long r0_prime_gen_start;
> @@ -635,15 +643,20 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
>  		return -EPERM;
>  	}
>  
> +	hdcp->topology_info->ver_in_force = DRM_MODE_HDCP14_IN_FORCE;
> +	memcpy(hdcp->topology_info->bksv, bksv.shim, DRM_MODE_HDCP_KSV_LEN);
> +
>  	I915_WRITE(PORT_HDCP_BKSVLO(port), bksv.reg[0]);
>  	I915_WRITE(PORT_HDCP_BKSVHI(port), bksv.reg[1]);
>  
>  	ret = shim->repeater_present(intel_dig_port, &repeater_present);
>  	if (ret)
>  		return ret;
> -	if (repeater_present)
> +	if (repeater_present) {
>  		I915_WRITE(HDCP_REP_CTL,
>  			   intel_hdcp_get_repeater_ctl(intel_dig_port));
> +		hdcp->topology_info->is_repeater = true;
> +	}
>  
>  	ret = shim->toggle_signalling(intel_dig_port, true);
>  	if (ret)
> @@ -708,7 +721,7 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
>  	 */
>  
>  	if (repeater_present)
> -		return intel_hdcp_auth_downstream(intel_dig_port, shim);
> +		return intel_hdcp_auth_downstream(hdcp, intel_dig_port);
>  
>  	DRM_DEBUG_KMS("HDCP is enabled (no repeater present)\n");
>  	return 0;
> @@ -739,13 +752,18 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
>  		return ret;
>  	}
>  
> +	memset(hdcp->topology_info, 0, sizeof(struct hdcp_topology_info));
> +
> +	if (drm_connector_update_hdcp_topology_property(&connector->base,
> +						connector->hdcp.topology_info))
> +		DRM_ERROR("Downstream_info update failed.\n");
> +
>  	DRM_DEBUG_KMS("HDCP is disabled\n");
>  	return 0;
>  }
>  
>  static int _intel_hdcp_enable(struct intel_connector *connector)
>  {
> -	struct intel_hdcp *hdcp = &connector->hdcp;
>  	struct drm_i915_private *dev_priv = connector->base.dev->dev_private;
>  	int i, ret, tries = 3;
>  
> @@ -770,9 +788,13 @@ static int _intel_hdcp_enable(struct intel_connector *connector)
>  
>  	/* Incase of authentication failures, HDCP spec expects reauth. */
>  	for (i = 0; i < tries; i++) {
> -		ret = intel_hdcp_auth(conn_to_dig_port(connector), hdcp->shim);
> +		ret = intel_hdcp_auth(connector);
>  		if (!ret) {
> -			hdcp->hdcp_encrypted = true;
> +			connector->hdcp.hdcp_encrypted = true;
> +			if (drm_connector_update_hdcp_topology_property(
> +					&connector->base,
> +					connector->hdcp.topology_info))
> +				DRM_ERROR("Downstream_info update failed.\n");
>  			return 0;
>  		}
>  
> @@ -1206,6 +1228,12 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
>  		return -EPERM;
>  	}
>  
> +	hdcp->topology_info->ver_in_force = DRM_MODE_HDCP22_IN_FORCE;
> +	hdcp->topology_info->content_type = hdcp->content_type;
> +	memcpy(hdcp->topology_info->bksv, msgs.send_cert.cert_rx.receiver_id,
> +	       HDCP_2_2_RECEIVER_ID_LEN);
> +	hdcp->topology_info->is_repeater = hdcp->is_repeater;
> +
>  	/*
>  	 * Here msgs.no_stored_km will hold msgs corresponding to the km
>  	 * stored also.
> @@ -1397,6 +1425,11 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
>  		return -EPERM;
>  	}
>  
> +	hdcp->topology_info->device_count = device_cnt;
> +	hdcp->topology_info->depth = HDCP_2_2_DEPTH(rx_info[0]);
> +	memcpy(hdcp->topology_info->ksv_list, msgs.recvid_list.receiver_ids,
> +	       device_cnt * HDCP_2_2_RECEIVER_ID_LEN);
> +
>  	ret = hdcp2_verify_rep_topology_prepare_ack(connector,
>  						    &msgs.recvid_list,
>  						    &msgs.rep_ack);
> @@ -1583,6 +1616,12 @@ static int _intel_hdcp2_enable(struct intel_connector *connector)
>  	if (ret) {
>  		DRM_DEBUG_KMS("HDCP2 Type%d  Enabling Failed. (%d)\n",
>  			      hdcp->content_type, ret);
> +
> +		memset(hdcp->topology_info, 0,
> +		       sizeof(struct hdcp_topology_info));
> +		drm_connector_update_hdcp_topology_property(&connector->base,
> +							  hdcp->topology_info);
> +
>  		return ret;
>  	}
>  
> @@ -1590,12 +1629,16 @@ static int _intel_hdcp2_enable(struct intel_connector *connector)
>  		      connector->base.name, connector->base.base.id,
>  		      hdcp->content_type);
>  
> +	drm_connector_update_hdcp_topology_property(&connector->base,
> +						    hdcp->topology_info);
>  	hdcp->hdcp2_encrypted = true;
> +
>  	return 0;
>  }
>  
>  static int _intel_hdcp2_disable(struct intel_connector *connector)
>  {
> +	struct intel_hdcp *hdcp = &connector->hdcp;
>  	int ret;
>  
>  	DRM_DEBUG_KMS("[%s:%d] HDCP2.2 is being Disabled\n",
> @@ -1606,8 +1649,11 @@ static int _intel_hdcp2_disable(struct intel_connector *connector)
>  	if (hdcp2_deauthenticate_port(connector) < 0)
>  		DRM_DEBUG_KMS("Port deauth failed.\n");
>  
> -	connector->hdcp.hdcp2_encrypted = false;
> +	hdcp->hdcp2_encrypted = false;
>  
> +	memset(hdcp->topology_info, 0, sizeof(struct hdcp_topology_info));
> +	drm_connector_update_hdcp_topology_property(&connector->base,
> +						    hdcp->topology_info);
>  	return ret;
>  }
>  
> @@ -1824,10 +1870,17 @@ int intel_hdcp_init(struct intel_connector *connector,
>  	ret =
>  	drm_connector_attach_content_protection_property(&connector->base,
>  							 hdcp->hdcp2_supported);
> -	if (ret) {
> -		hdcp->hdcp2_supported = false;
> -		kfree(hdcp->port_data.streams);
> -		return ret;
> +	if (ret)
> +		goto err_exit;
> +
> +	ret = drm_connector_attach_hdcp_topology_property(&connector->base);
> +	if (ret)
> +		goto err_exit;
> +
> +	hdcp->topology_info = kzalloc(sizeof(*hdcp->topology_info), GFP_KERNEL);
> +	if (!hdcp->topology_info) {
> +		ret = -ENOMEM;
> +		goto err_exit;
>  	}
>  
>  	hdcp->shim = shim;
> @@ -1837,6 +1890,12 @@ int intel_hdcp_init(struct intel_connector *connector,
>  	init_waitqueue_head(&hdcp->cp_irq_queue);
>  
>  	return 0;
> +
> +err_exit:
> +	hdcp->hdcp2_supported = false;
> +	kfree(hdcp->port_data.streams);
> +
> +	return ret;
>  }
>  
>  int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
> diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> index fdd65a14f4db..330e34715aa4 100644
> --- a/include/drm/drm_hdcp.h
> +++ b/include/drm/drm_hdcp.h
> @@ -23,6 +23,7 @@
>  #define DRM_HDCP_V_PRIME_PART_LEN		4
>  #define DRM_HDCP_V_PRIME_NUM_PARTS		5
>  #define DRM_HDCP_NUM_DOWNSTREAM(x)		(x & 0x7f)
> +#define DRM_HDCP_DEPTH(x)			((x) & 0x7)
>  #define DRM_HDCP_MAX_CASCADE_EXCEEDED(x)	(x & BIT(3))
>  #define DRM_HDCP_MAX_DEVICE_EXCEEDED(x)		(x & BIT(7))
>  
> -- 
> 2.19.1
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e387e842f414..6a321a56ce42 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -482,6 +482,8 @@  struct intel_hdcp {
 	wait_queue_head_t cp_irq_queue;
 	atomic_t cp_irq_count;
 	int cp_irq_count_cached;
+
+	struct hdcp_topology_info *topology_info;
 };
 
 struct intel_connector {
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index f70f1e98e4ae..6993bb9ecd0b 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -490,9 +490,10 @@  int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port,
 
 /* Implements Part 2 of the HDCP authorization procedure */
 static
-int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
-			       const struct intel_hdcp_shim *shim)
+int intel_hdcp_auth_downstream(struct intel_hdcp *hdcp,
+			       struct intel_digital_port *intel_dig_port)
 {
+	const struct intel_hdcp_shim *shim = hdcp->shim;
 	u8 bstatus[2], num_downstream, *ksv_fifo;
 	int ret, i, tries = 3;
 
@@ -523,6 +524,9 @@  int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
 	if (num_downstream == 0)
 		return -EINVAL;
 
+	hdcp->topology_info->device_count = num_downstream;
+	hdcp->topology_info->depth = DRM_HDCP_DEPTH(bstatus[1]);
+
 	ksv_fifo = kcalloc(DRM_HDCP_KSV_LEN, num_downstream, GFP_KERNEL);
 	if (!ksv_fifo)
 		return -ENOMEM;
@@ -536,6 +540,8 @@  int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
 		return -EPERM;
 	}
 
+	memcpy(hdcp->topology_info->ksv_list, ksv_fifo,
+	       num_downstream * DRM_HDCP_KSV_LEN);
 	/*
 	 * When V prime mismatches, DP Spec mandates re-read of
 	 * V prime atleast twice.
@@ -562,9 +568,11 @@  int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
 }
 
 /* Implements Part 1 of the HDCP authorization procedure */
-static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
-			   const struct intel_hdcp_shim *shim)
+static int intel_hdcp_auth(struct intel_connector *connector)
 {
+	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+	struct intel_hdcp *hdcp = &connector->hdcp;
+	const struct intel_hdcp_shim *shim = hdcp->shim;
 	struct drm_i915_private *dev_priv;
 	enum port port;
 	unsigned long r0_prime_gen_start;
@@ -635,15 +643,20 @@  static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
 		return -EPERM;
 	}
 
+	hdcp->topology_info->ver_in_force = DRM_MODE_HDCP14_IN_FORCE;
+	memcpy(hdcp->topology_info->bksv, bksv.shim, DRM_MODE_HDCP_KSV_LEN);
+
 	I915_WRITE(PORT_HDCP_BKSVLO(port), bksv.reg[0]);
 	I915_WRITE(PORT_HDCP_BKSVHI(port), bksv.reg[1]);
 
 	ret = shim->repeater_present(intel_dig_port, &repeater_present);
 	if (ret)
 		return ret;
-	if (repeater_present)
+	if (repeater_present) {
 		I915_WRITE(HDCP_REP_CTL,
 			   intel_hdcp_get_repeater_ctl(intel_dig_port));
+		hdcp->topology_info->is_repeater = true;
+	}
 
 	ret = shim->toggle_signalling(intel_dig_port, true);
 	if (ret)
@@ -708,7 +721,7 @@  static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
 	 */
 
 	if (repeater_present)
-		return intel_hdcp_auth_downstream(intel_dig_port, shim);
+		return intel_hdcp_auth_downstream(hdcp, intel_dig_port);
 
 	DRM_DEBUG_KMS("HDCP is enabled (no repeater present)\n");
 	return 0;
@@ -739,13 +752,18 @@  static int _intel_hdcp_disable(struct intel_connector *connector)
 		return ret;
 	}
 
+	memset(hdcp->topology_info, 0, sizeof(struct hdcp_topology_info));
+
+	if (drm_connector_update_hdcp_topology_property(&connector->base,
+						connector->hdcp.topology_info))
+		DRM_ERROR("Downstream_info update failed.\n");
+
 	DRM_DEBUG_KMS("HDCP is disabled\n");
 	return 0;
 }
 
 static int _intel_hdcp_enable(struct intel_connector *connector)
 {
-	struct intel_hdcp *hdcp = &connector->hdcp;
 	struct drm_i915_private *dev_priv = connector->base.dev->dev_private;
 	int i, ret, tries = 3;
 
@@ -770,9 +788,13 @@  static int _intel_hdcp_enable(struct intel_connector *connector)
 
 	/* Incase of authentication failures, HDCP spec expects reauth. */
 	for (i = 0; i < tries; i++) {
-		ret = intel_hdcp_auth(conn_to_dig_port(connector), hdcp->shim);
+		ret = intel_hdcp_auth(connector);
 		if (!ret) {
-			hdcp->hdcp_encrypted = true;
+			connector->hdcp.hdcp_encrypted = true;
+			if (drm_connector_update_hdcp_topology_property(
+					&connector->base,
+					connector->hdcp.topology_info))
+				DRM_ERROR("Downstream_info update failed.\n");
 			return 0;
 		}
 
@@ -1206,6 +1228,12 @@  static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
 		return -EPERM;
 	}
 
+	hdcp->topology_info->ver_in_force = DRM_MODE_HDCP22_IN_FORCE;
+	hdcp->topology_info->content_type = hdcp->content_type;
+	memcpy(hdcp->topology_info->bksv, msgs.send_cert.cert_rx.receiver_id,
+	       HDCP_2_2_RECEIVER_ID_LEN);
+	hdcp->topology_info->is_repeater = hdcp->is_repeater;
+
 	/*
 	 * Here msgs.no_stored_km will hold msgs corresponding to the km
 	 * stored also.
@@ -1397,6 +1425,11 @@  int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
 		return -EPERM;
 	}
 
+	hdcp->topology_info->device_count = device_cnt;
+	hdcp->topology_info->depth = HDCP_2_2_DEPTH(rx_info[0]);
+	memcpy(hdcp->topology_info->ksv_list, msgs.recvid_list.receiver_ids,
+	       device_cnt * HDCP_2_2_RECEIVER_ID_LEN);
+
 	ret = hdcp2_verify_rep_topology_prepare_ack(connector,
 						    &msgs.recvid_list,
 						    &msgs.rep_ack);
@@ -1583,6 +1616,12 @@  static int _intel_hdcp2_enable(struct intel_connector *connector)
 	if (ret) {
 		DRM_DEBUG_KMS("HDCP2 Type%d  Enabling Failed. (%d)\n",
 			      hdcp->content_type, ret);
+
+		memset(hdcp->topology_info, 0,
+		       sizeof(struct hdcp_topology_info));
+		drm_connector_update_hdcp_topology_property(&connector->base,
+							  hdcp->topology_info);
+
 		return ret;
 	}
 
@@ -1590,12 +1629,16 @@  static int _intel_hdcp2_enable(struct intel_connector *connector)
 		      connector->base.name, connector->base.base.id,
 		      hdcp->content_type);
 
+	drm_connector_update_hdcp_topology_property(&connector->base,
+						    hdcp->topology_info);
 	hdcp->hdcp2_encrypted = true;
+
 	return 0;
 }
 
 static int _intel_hdcp2_disable(struct intel_connector *connector)
 {
+	struct intel_hdcp *hdcp = &connector->hdcp;
 	int ret;
 
 	DRM_DEBUG_KMS("[%s:%d] HDCP2.2 is being Disabled\n",
@@ -1606,8 +1649,11 @@  static int _intel_hdcp2_disable(struct intel_connector *connector)
 	if (hdcp2_deauthenticate_port(connector) < 0)
 		DRM_DEBUG_KMS("Port deauth failed.\n");
 
-	connector->hdcp.hdcp2_encrypted = false;
+	hdcp->hdcp2_encrypted = false;
 
+	memset(hdcp->topology_info, 0, sizeof(struct hdcp_topology_info));
+	drm_connector_update_hdcp_topology_property(&connector->base,
+						    hdcp->topology_info);
 	return ret;
 }
 
@@ -1824,10 +1870,17 @@  int intel_hdcp_init(struct intel_connector *connector,
 	ret =
 	drm_connector_attach_content_protection_property(&connector->base,
 							 hdcp->hdcp2_supported);
-	if (ret) {
-		hdcp->hdcp2_supported = false;
-		kfree(hdcp->port_data.streams);
-		return ret;
+	if (ret)
+		goto err_exit;
+
+	ret = drm_connector_attach_hdcp_topology_property(&connector->base);
+	if (ret)
+		goto err_exit;
+
+	hdcp->topology_info = kzalloc(sizeof(*hdcp->topology_info), GFP_KERNEL);
+	if (!hdcp->topology_info) {
+		ret = -ENOMEM;
+		goto err_exit;
 	}
 
 	hdcp->shim = shim;
@@ -1837,6 +1890,12 @@  int intel_hdcp_init(struct intel_connector *connector,
 	init_waitqueue_head(&hdcp->cp_irq_queue);
 
 	return 0;
+
+err_exit:
+	hdcp->hdcp2_supported = false;
+	kfree(hdcp->port_data.streams);
+
+	return ret;
 }
 
 int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index fdd65a14f4db..330e34715aa4 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -23,6 +23,7 @@ 
 #define DRM_HDCP_V_PRIME_PART_LEN		4
 #define DRM_HDCP_V_PRIME_NUM_PARTS		5
 #define DRM_HDCP_NUM_DOWNSTREAM(x)		(x & 0x7f)
+#define DRM_HDCP_DEPTH(x)			((x) & 0x7)
 #define DRM_HDCP_MAX_CASCADE_EXCEEDED(x)	(x & BIT(3))
 #define DRM_HDCP_MAX_DEVICE_EXCEEDED(x)		(x & BIT(7))