RE: [PATCH v3 12/16] drm/i915/hdcp: MST streams support in hdcp port_data

2020-10-26 Thread Shankar, Uma



> -Original Message-
> From: Anshuman Gupta 
> Sent: Friday, October 23, 2020 5:51 PM
> To: intel-...@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: seanp...@chromium.org; Nikula, Jani ; C,
> Ramalingam ; Li, Juston ;
> Shankar, Uma ; Gupta, Anshuman
> 
> Subject: [PATCH v3 12/16] drm/i915/hdcp: MST streams support in hdcp
> port_data
> 
> Add support for multiple mst stream in hdcp port data which will be used by
> RepeaterAuthStreamManage msg and HDCP 2.2 security f/w for m' validation.
> 
> v2:
> Init the hdcp port data k for HDMI/DP SST strem.

Nit: Typo in stream.

> 
> Cc: Ramalingam C 
> Signed-off-by: Anshuman Gupta 
> ---
>  .../drm/i915/display/intel_display_types.h|   4 +-
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 103 +++---
>  2 files changed, 93 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 749c3a7e0b45..24e0067c2e7c 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1445,10 +1445,12 @@ struct intel_digital_port {
>   enum phy_fia tc_phy_fia;
>   u8 tc_phy_fia_idx;
> 
> - /* protects num_hdcp_streams reference count, port_data */
> + /* protects num_hdcp_streams reference count, port_data and
> port_auth
> +*/
>   struct mutex hdcp_mutex;
>   /* the number of pipes using HDCP signalling out of this port */
>   unsigned int num_hdcp_streams;
> + /* port HDCP auth status */
> + bool port_auth;
>   /* HDCP port data need to pass to security f/w */
>   struct hdcp_port_data port_data;
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c
> b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 207fa17129ae..41c6892d959a 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -26,6 +26,64 @@
>  #define KEY_LOAD_TRIES   5
>  #define HDCP2_LC_RETRY_CNT   3
> 
> +static int intel_conn_to_vcpi(struct intel_connector *connector) {
> + /* For HDMI this is forced to be 0x0. For DP SST also this is 0x0. */
> + return connector->port  ? connector->port->vcpi.vcpi : 0;
> +}
> +
> +static int
> +intel_hdcp_required_content_stream(struct intel_digital_port *dig_port)
> +{
> + struct drm_connector_list_iter conn_iter;
> + struct intel_digital_port *conn_dig_port;
> + struct intel_connector *connector;
> + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
> + struct hdcp_port_data *data = &dig_port->port_data;
> + bool enforce_type0 = false;
> + int k;
> +
> + if (dig_port->port_auth)
> + return 0;
> +
> + drm_connector_list_iter_begin(&i915->drm, &conn_iter);
> + for_each_intel_connector_iter(connector, &conn_iter) {
> + if (!intel_encoder_is_mst(intel_attached_encoder(connector)))
> + continue;
> +
> + conn_dig_port = intel_attached_dig_port(connector);
> + if (conn_dig_port != dig_port)
> + continue;
> +
> + if (connector->base.status == connector_status_disconnected)
> + continue;
> +
> + if (!enforce_type0 && !intel_hdcp2_capable(connector))
> + enforce_type0 = true;
> +
> + data->streams[data->k].stream_id =
> intel_conn_to_vcpi(connector);
> + data->k++;
> +
> + /* if there is only one active stream */
> + if (dig_port->dp.active_mst_links <= 1)
> + break;
> + }
> + drm_connector_list_iter_end(&conn_iter);
> +
> + if (drm_WARN_ON(&i915->drm, data->k > INTEL_NUM_PIPES(i915) ||
> data->k == 0))
> + return -EINVAL;
> +
> + /*
> +  * Apply common protection level across all streams in DP MST Topology.
> +  * Use highest supported content type for all streams in DP MST
> Topology.
> +  */
> + for (k = 0; k < data->k; k++)
> + data->streams[k].stream_type =
> + enforce_type0 ? DRM_MODE_HDCP_CONTENT_TYPE0 :
> +DRM_MODE_HDCP_CONTENT_TYPE1;
> +
> + return 0;
> +}
> +
>  static
>  bool intel_hdcp_is_ksv_valid(u8 *ksv)
>  {
> @@ -1296,6 +1354,7 @@ static int hdcp2_authenticate_port(struct
> intel_connector *connector)
>   if (ret < 0)
>   drm_dbg_kms(&dev_priv->drm, "Enable hdcp auth failed. %d\n",
>

[PATCH v3 12/16] drm/i915/hdcp: MST streams support in hdcp port_data

2020-10-23 Thread Anshuman Gupta
Add support for multiple mst stream in hdcp port data
which will be used by RepeaterAuthStreamManage msg and
HDCP 2.2 security f/w for m' validation.

v2:
Init the hdcp port data k for HDMI/DP SST strem.

Cc: Ramalingam C 
Signed-off-by: Anshuman Gupta 
---
 .../drm/i915/display/intel_display_types.h|   4 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 103 +++---
 2 files changed, 93 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 749c3a7e0b45..24e0067c2e7c 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1445,10 +1445,12 @@ struct intel_digital_port {
enum phy_fia tc_phy_fia;
u8 tc_phy_fia_idx;
 
-   /* protects num_hdcp_streams reference count, port_data */
+   /* protects num_hdcp_streams reference count, port_data and port_auth */
struct mutex hdcp_mutex;
/* the number of pipes using HDCP signalling out of this port */
unsigned int num_hdcp_streams;
+   /* port HDCP auth status */
+   bool port_auth;
/* HDCP port data need to pass to security f/w */
struct hdcp_port_data port_data;
 
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 207fa17129ae..41c6892d959a 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -26,6 +26,64 @@
 #define KEY_LOAD_TRIES 5
 #define HDCP2_LC_RETRY_CNT 3
 
+static int intel_conn_to_vcpi(struct intel_connector *connector)
+{
+   /* For HDMI this is forced to be 0x0. For DP SST also this is 0x0. */
+   return connector->port  ? connector->port->vcpi.vcpi : 0;
+}
+
+static int
+intel_hdcp_required_content_stream(struct intel_digital_port *dig_port)
+{
+   struct drm_connector_list_iter conn_iter;
+   struct intel_digital_port *conn_dig_port;
+   struct intel_connector *connector;
+   struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+   struct hdcp_port_data *data = &dig_port->port_data;
+   bool enforce_type0 = false;
+   int k;
+
+   if (dig_port->port_auth)
+   return 0;
+
+   drm_connector_list_iter_begin(&i915->drm, &conn_iter);
+   for_each_intel_connector_iter(connector, &conn_iter) {
+   if (!intel_encoder_is_mst(intel_attached_encoder(connector)))
+   continue;
+
+   conn_dig_port = intel_attached_dig_port(connector);
+   if (conn_dig_port != dig_port)
+   continue;
+
+   if (connector->base.status == connector_status_disconnected)
+   continue;
+
+   if (!enforce_type0 && !intel_hdcp2_capable(connector))
+   enforce_type0 = true;
+
+   data->streams[data->k].stream_id = 
intel_conn_to_vcpi(connector);
+   data->k++;
+
+   /* if there is only one active stream */
+   if (dig_port->dp.active_mst_links <= 1)
+   break;
+   }
+   drm_connector_list_iter_end(&conn_iter);
+
+   if (drm_WARN_ON(&i915->drm, data->k > INTEL_NUM_PIPES(i915) || data->k 
== 0))
+   return -EINVAL;
+
+   /*
+* Apply common protection level across all streams in DP MST Topology.
+* Use highest supported content type for all streams in DP MST 
Topology.
+*/
+   for (k = 0; k < data->k; k++)
+   data->streams[k].stream_type =
+   enforce_type0 ? DRM_MODE_HDCP_CONTENT_TYPE0 : 
DRM_MODE_HDCP_CONTENT_TYPE1;
+
+   return 0;
+}
+
 static
 bool intel_hdcp_is_ksv_valid(u8 *ksv)
 {
@@ -1296,6 +1354,7 @@ static int hdcp2_authenticate_port(struct intel_connector 
*connector)
if (ret < 0)
drm_dbg_kms(&dev_priv->drm, "Enable hdcp auth failed. %d\n",
ret);
+
mutex_unlock(&dev_priv->hdcp_comp_mutex);
 
return ret;
@@ -1477,13 +1536,14 @@ static
 int _hdcp2_propagate_stream_management_info(struct intel_connector *connector)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
+   struct hdcp_port_data *data = &dig_port->port_data;
struct intel_hdcp *hdcp = &connector->hdcp;
union {
struct hdcp2_rep_stream_manage stream_manage;
struct hdcp2_rep_stream_ready stream_ready;
} msgs;
const struct intel_hdcp_shim *shim = hdcp->shim;
-   int ret;
+   int ret, streams_size_delta, i;
 
if (connector->hdcp.seq_num_m > HDCP_2_2_SEQ_NUM_MAX)
return -ERANGE;
@@ -1493,15 +1553,18 @@ int _hdcp2_propagate_stream_management_info(struct 
intel_connector *connector)
drm_hdcp_cpu_to_be24(msgs.stream_manage.seq_num_m, hdcp->seq_num_m);
 
/* K no of streams i

[PATCH v3 12/16] drm/i915/hdcp: MST streams support in hdcp port_data

2020-10-22 Thread Anshuman Gupta
Add support for multiple mst stream in hdcp port data
which will be used by RepeaterAuthStreamManage msg and
HDCP 2.2 security f/w for m' validation.

v2:
Init the hdcp port data k for HDMI/DP SST strem.

Cc: Ramalingam C 
Signed-off-by: Anshuman Gupta 
---
 .../drm/i915/display/intel_display_types.h|   4 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 100 +++---
 2 files changed, 90 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 749c3a7e0b45..24e0067c2e7c 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1445,10 +1445,12 @@ struct intel_digital_port {
enum phy_fia tc_phy_fia;
u8 tc_phy_fia_idx;
 
-   /* protects num_hdcp_streams reference count, port_data */
+   /* protects num_hdcp_streams reference count, port_data and port_auth */
struct mutex hdcp_mutex;
/* the number of pipes using HDCP signalling out of this port */
unsigned int num_hdcp_streams;
+   /* port HDCP auth status */
+   bool port_auth;
/* HDCP port data need to pass to security f/w */
struct hdcp_port_data port_data;
 
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 207fa17129ae..2e719df1e5b1 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -26,6 +26,62 @@
 #define KEY_LOAD_TRIES 5
 #define HDCP2_LC_RETRY_CNT 3
 
+static int intel_conn_to_vcpi(struct intel_connector *connector)
+{
+   /* For HDMI this is forced to be 0x0. For DP SST also this is 0x0. */
+   return connector->port  ? connector->port->vcpi.vcpi : 0;
+}
+
+static int
+intel_hdcp_required_content_stream(struct intel_digital_port *dig_port)
+{
+   struct drm_connector_list_iter conn_iter;
+   struct intel_digital_port *conn_dig_port;
+   struct intel_connector *connector;
+   struct intel_hdcp *hdcp;
+   struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+   struct hdcp_port_data *data = &dig_port->port_data;
+   bool enforce_type0 = false;
+   int k;
+
+   if (dig_port->port_auth)
+   return 0;
+
+   drm_connector_list_iter_begin(&i915->drm, &conn_iter);
+   for_each_intel_connector_iter(connector, &conn_iter) {
+   if (!intel_encoder_is_mst(intel_attached_encoder(connector)))
+   continue;
+
+   conn_dig_port = intel_attached_dig_port(connector);
+   if (conn_dig_port != dig_port)
+   continue;
+
+   if (connector->base.status == connector_status_disconnected)
+   continue;
+
+   hdcp = &connector->hdcp;
+   if (!enforce_type0 && (hdcp->content_type && 
!intel_hdcp2_capable(connector)))
+   enforce_type0 = true;
+
+   data->streams[data->k].stream_id = 
intel_conn_to_vcpi(connector);
+   data->k++;
+
+   /* if there is only one active stream */
+   if (dig_port->dp.active_mst_links <= 1)
+   break;
+   }
+   drm_connector_list_iter_end(&conn_iter);
+
+   if (drm_WARN_ON(&i915->drm, data->k > INTEL_NUM_PIPES(i915) || data->k 
== 0))
+   return -EINVAL;
+
+   for (k = 0; k < data->k; k++)
+   data->streams[k].stream_type =
+   enforce_type0 ? DRM_MODE_HDCP_CONTENT_TYPE0 : 
hdcp->content_type;
+
+   return 0;
+}
+
 static
 bool intel_hdcp_is_ksv_valid(u8 *ksv)
 {
@@ -1296,6 +1352,7 @@ static int hdcp2_authenticate_port(struct intel_connector 
*connector)
if (ret < 0)
drm_dbg_kms(&dev_priv->drm, "Enable hdcp auth failed. %d\n",
ret);
+
mutex_unlock(&dev_priv->hdcp_comp_mutex);
 
return ret;
@@ -1477,13 +1534,14 @@ static
 int _hdcp2_propagate_stream_management_info(struct intel_connector *connector)
 {
struct intel_digital_port *dig_port = 
intel_attached_dig_port(connector);
+   struct hdcp_port_data *data = &dig_port->port_data;
struct intel_hdcp *hdcp = &connector->hdcp;
union {
struct hdcp2_rep_stream_manage stream_manage;
struct hdcp2_rep_stream_ready stream_ready;
} msgs;
const struct intel_hdcp_shim *shim = hdcp->shim;
-   int ret;
+   int ret, streams_size_delta, i;
 
if (connector->hdcp.seq_num_m > HDCP_2_2_SEQ_NUM_MAX)
return -ERANGE;
@@ -1493,15 +1551,18 @@ int _hdcp2_propagate_stream_management_info(struct 
intel_connector *connector)
drm_hdcp_cpu_to_be24(msgs.stream_manage.seq_num_m, hdcp->seq_num_m);
 
/* K no of streams is fixed as 1. Stored as big-endian. */
-   msgs.stream_manage.k = cpu_to_be16(1);
+   ms