Re: [PATCH v9 08/39] drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking

2018-12-20 Thread Daniel Vetter
On Thu, Dec 20, 2018 at 04:59:13PM +0530, C, Ramalingam wrote:
> 
> On 12/19/2018 9:18 PM, Daniel Vetter wrote:
> > On Thu, Dec 13, 2018 at 09:31:10AM +0530, Ramalingam C wrote:
> > > "hdcp_encrypted" flag is defined to denote the HDCP1.4 encryption status.
> > > This SW tracking is used to determine the need for real hdcp1.4 disable
> > > and hdcp_check_link upon CP_IRQ.
> > > 
> > > On CP_IRQ we filter the CP_IRQ related to the states like Link failure
> > > and reauthentication req etc and handle them in hdcp_check_link.
> > > CP_IRQ corresponding to the authentication msg availability are ignored.
> > > 
> > > WARN_ON is added for the abrupt stop of HDCP encryption of a port.
> > > 
> > > Signed-off-by: Ramalingam C 
> > > ---
> > >   drivers/gpu/drm/i915/intel_dp.c   |  2 +-
> > >   drivers/gpu/drm/i915/intel_drv.h  |  5 ++-
> > >   drivers/gpu/drm/i915/intel_hdcp.c | 89 
> > > ++-
> > >   3 files changed, 74 insertions(+), 22 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_dp.c 
> > > b/drivers/gpu/drm/i915/intel_dp.c
> > > index aba884c64879..89315e15fb34 100644
> > > --- a/drivers/gpu/drm/i915/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > > @@ -4758,7 +4758,7 @@ static void intel_dp_check_service_irq(struct 
> > > intel_dp *intel_dp)
> > >   intel_dp_handle_test_request(intel_dp);
> > >   if (val & DP_CP_IRQ)
> > > - intel_hdcp_check_link(intel_dp->attached_connector);
> > > + intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
> > >   if (val & DP_SINK_SPECIFIC_IRQ)
> > >   DRM_DEBUG_DRIVER("Sink specific irq unhandled\n");
> > > diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> > > b/drivers/gpu/drm/i915/intel_drv.h
> > > index 191b6e0f086c..decd0346c6a7 100644
> > > --- a/drivers/gpu/drm/i915/intel_drv.h
> > > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > > @@ -393,6 +393,9 @@ struct intel_hdcp {
> > >   struct delayed_work check_work;
> > >   struct work_struct prop_work;
> > > + /* HDCP1.4 Encryption status */
> > > + u8 hdcp_encrypted;
> > Another bool I guess? Or unsigned : 1;
> as per #intel-gfx discussion I will fallback to bool.
> > 
> > > +
> > >   /* HDCP2.2 related definitions */
> > >   /* Flag indicates whether this connector supports HDCP2.2 or 
> > > not. */
> > >   u8 hdcp2_supported;
> > > @@ -2058,10 +2061,10 @@ int intel_hdcp_init(struct intel_connector 
> > > *connector,
> > >   bool hdcp2_supported);
> > >   int intel_hdcp_enable(struct intel_connector *connector);
> > >   int intel_hdcp_disable(struct intel_connector *connector);
> > > -int intel_hdcp_check_link(struct intel_connector *connector);
> > >   bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port 
> > > port);
> > >   bool intel_hdcp_capable(struct intel_connector *connector);
> > >   bool is_hdcp2_supported(struct drm_i915_private *dev_priv);
> > > +void intel_hdcp_handle_cp_irq(struct intel_connector *connector);
> > >   /* intel_psr.c */
> > >   #define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && 
> > > dev_priv->psr.sink_support)
> > > diff --git a/drivers/gpu/drm/i915/intel_hdcp.c 
> > > b/drivers/gpu/drm/i915/intel_hdcp.c
> > > index 9405fce07b93..2b7814a6f12b 100644
> > > --- a/drivers/gpu/drm/i915/intel_hdcp.c
> > > +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> > > @@ -75,6 +75,16 @@ bool intel_hdcp_capable(struct intel_connector 
> > > *connector)
> > >   return capable;
> > >   }
> > > +static inline bool intel_hdcp_in_use(struct intel_connector *connector)
> > > +{
> > > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> > > + enum port port = connector->encoder->port;
> > > + u32 reg;
> > > +
> > > + reg = I915_READ(PORT_HDCP_STATUS(port));
> > > + return reg & HDCP_STATUS_ENC;
> > > +}
> > > +
> > >   static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port 
> > > *intel_dig_port,
> > >   const struct intel_hdcp_shim *shim)
> > >   {
> > > @@ -669,6 +679,7 @@ static int _intel_hdcp_disable(struct intel_connector 
> > > *connector)
> > >   DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
> > > connector->base.name, connector->base.base.id);
> > > + hdcp->hdcp_encrypted = 0;
> > >   I915_WRITE(PORT_HDCP_CONF(port), 0);
> > >   if (intel_wait_for_register(dev_priv, PORT_HDCP_STATUS(port), 
> > > ~0, 0,
> > >   ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
> > > @@ -714,8 +725,10 @@ 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);
> > > - if (!ret)
> > > + if (!ret) {
> > > + 

Re: [PATCH v9 08/39] drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking

2018-12-20 Thread C, Ramalingam


On 12/19/2018 9:18 PM, Daniel Vetter wrote:

On Thu, Dec 13, 2018 at 09:31:10AM +0530, Ramalingam C wrote:

"hdcp_encrypted" flag is defined to denote the HDCP1.4 encryption status.
This SW tracking is used to determine the need for real hdcp1.4 disable
and hdcp_check_link upon CP_IRQ.

On CP_IRQ we filter the CP_IRQ related to the states like Link failure
and reauthentication req etc and handle them in hdcp_check_link.
CP_IRQ corresponding to the authentication msg availability are ignored.

WARN_ON is added for the abrupt stop of HDCP encryption of a port.

Signed-off-by: Ramalingam C 
---
  drivers/gpu/drm/i915/intel_dp.c   |  2 +-
  drivers/gpu/drm/i915/intel_drv.h  |  5 ++-
  drivers/gpu/drm/i915/intel_hdcp.c | 89 ++-
  3 files changed, 74 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index aba884c64879..89315e15fb34 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4758,7 +4758,7 @@ static void intel_dp_check_service_irq(struct intel_dp 
*intel_dp)
intel_dp_handle_test_request(intel_dp);
  
  	if (val & DP_CP_IRQ)

-   intel_hdcp_check_link(intel_dp->attached_connector);
+   intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
  
  	if (val & DP_SINK_SPECIFIC_IRQ)

DRM_DEBUG_DRIVER("Sink specific irq unhandled\n");
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 191b6e0f086c..decd0346c6a7 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -393,6 +393,9 @@ struct intel_hdcp {
struct delayed_work check_work;
struct work_struct prop_work;
  
+	/* HDCP1.4 Encryption status */

+   u8 hdcp_encrypted;

Another bool I guess? Or unsigned : 1;

as per #intel-gfx discussion I will fallback to bool.



+
/* HDCP2.2 related definitions */
/* Flag indicates whether this connector supports HDCP2.2 or not. */
u8 hdcp2_supported;
@@ -2058,10 +2061,10 @@ int intel_hdcp_init(struct intel_connector *connector,
bool hdcp2_supported);
  int intel_hdcp_enable(struct intel_connector *connector);
  int intel_hdcp_disable(struct intel_connector *connector);
-int intel_hdcp_check_link(struct intel_connector *connector);
  bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
  bool intel_hdcp_capable(struct intel_connector *connector);
  bool is_hdcp2_supported(struct drm_i915_private *dev_priv);
+void intel_hdcp_handle_cp_irq(struct intel_connector *connector);
  
  /* intel_psr.c */

  #define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c 
b/drivers/gpu/drm/i915/intel_hdcp.c
index 9405fce07b93..2b7814a6f12b 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -75,6 +75,16 @@ bool intel_hdcp_capable(struct intel_connector *connector)
return capable;
  }
  
+static inline bool intel_hdcp_in_use(struct intel_connector *connector)

+{
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   enum port port = connector->encoder->port;
+   u32 reg;
+
+   reg = I915_READ(PORT_HDCP_STATUS(port));
+   return reg & HDCP_STATUS_ENC;
+}
+
  static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *intel_dig_port,
const struct intel_hdcp_shim *shim)
  {
@@ -669,6 +679,7 @@ static int _intel_hdcp_disable(struct intel_connector 
*connector)
DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
  connector->base.name, connector->base.base.id);
  
+	hdcp->hdcp_encrypted = 0;

I915_WRITE(PORT_HDCP_CONF(port), 0);
if (intel_wait_for_register(dev_priv, PORT_HDCP_STATUS(port), ~0, 0,
ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
@@ -714,8 +725,10 @@ 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);
-   if (!ret)
+   if (!ret) {
+   hdcp->hdcp_encrypted = 1;
return 0;
+   }
  
  		DRM_DEBUG_KMS("HDCP Auth failure (%d)\n", ret);
  
@@ -742,16 +755,17 @@ int intel_hdcp_check_link(struct intel_connector *connector)

enum port port = intel_dig_port->base.port;
int ret = 0;
  
-	if (!hdcp->shim)

-   return -ENOENT;
-
mutex_lock(>mutex);
  
-	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)

+   /* Check_link valid only when HDCP1.4 is enabled */
+   if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_ENABLED ||
+   !hdcp->hdcp_encrypted) {
+   ret = -EINVAL;
goto out;
+ 

Re: [PATCH v9 08/39] drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking

2018-12-19 Thread Daniel Vetter
On Thu, Dec 13, 2018 at 09:31:10AM +0530, Ramalingam C wrote:
> "hdcp_encrypted" flag is defined to denote the HDCP1.4 encryption status.
> This SW tracking is used to determine the need for real hdcp1.4 disable
> and hdcp_check_link upon CP_IRQ.
> 
> On CP_IRQ we filter the CP_IRQ related to the states like Link failure
> and reauthentication req etc and handle them in hdcp_check_link.
> CP_IRQ corresponding to the authentication msg availability are ignored.
> 
> WARN_ON is added for the abrupt stop of HDCP encryption of a port.
> 
> Signed-off-by: Ramalingam C 
> ---
>  drivers/gpu/drm/i915/intel_dp.c   |  2 +-
>  drivers/gpu/drm/i915/intel_drv.h  |  5 ++-
>  drivers/gpu/drm/i915/intel_hdcp.c | 89 
> ++-
>  3 files changed, 74 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index aba884c64879..89315e15fb34 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4758,7 +4758,7 @@ static void intel_dp_check_service_irq(struct intel_dp 
> *intel_dp)
>   intel_dp_handle_test_request(intel_dp);
>  
>   if (val & DP_CP_IRQ)
> - intel_hdcp_check_link(intel_dp->attached_connector);
> + intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
>  
>   if (val & DP_SINK_SPECIFIC_IRQ)
>   DRM_DEBUG_DRIVER("Sink specific irq unhandled\n");
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index 191b6e0f086c..decd0346c6a7 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -393,6 +393,9 @@ struct intel_hdcp {
>   struct delayed_work check_work;
>   struct work_struct prop_work;
>  
> + /* HDCP1.4 Encryption status */
> + u8 hdcp_encrypted;

Another bool I guess? Or unsigned : 1;

> +
>   /* HDCP2.2 related definitions */
>   /* Flag indicates whether this connector supports HDCP2.2 or not. */
>   u8 hdcp2_supported;
> @@ -2058,10 +2061,10 @@ int intel_hdcp_init(struct intel_connector *connector,
>   bool hdcp2_supported);
>  int intel_hdcp_enable(struct intel_connector *connector);
>  int intel_hdcp_disable(struct intel_connector *connector);
> -int intel_hdcp_check_link(struct intel_connector *connector);
>  bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
>  bool intel_hdcp_capable(struct intel_connector *connector);
>  bool is_hdcp2_supported(struct drm_i915_private *dev_priv);
> +void intel_hdcp_handle_cp_irq(struct intel_connector *connector);
>  
>  /* intel_psr.c */
>  #define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
> diff --git a/drivers/gpu/drm/i915/intel_hdcp.c 
> b/drivers/gpu/drm/i915/intel_hdcp.c
> index 9405fce07b93..2b7814a6f12b 100644
> --- a/drivers/gpu/drm/i915/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> @@ -75,6 +75,16 @@ bool intel_hdcp_capable(struct intel_connector *connector)
>   return capable;
>  }
>  
> +static inline bool intel_hdcp_in_use(struct intel_connector *connector)
> +{
> + struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> + enum port port = connector->encoder->port;
> + u32 reg;
> +
> + reg = I915_READ(PORT_HDCP_STATUS(port));
> + return reg & HDCP_STATUS_ENC;
> +}
> +
>  static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port 
> *intel_dig_port,
>   const struct intel_hdcp_shim *shim)
>  {
> @@ -669,6 +679,7 @@ static int _intel_hdcp_disable(struct intel_connector 
> *connector)
>   DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
> connector->base.name, connector->base.base.id);
>  
> + hdcp->hdcp_encrypted = 0;
>   I915_WRITE(PORT_HDCP_CONF(port), 0);
>   if (intel_wait_for_register(dev_priv, PORT_HDCP_STATUS(port), ~0, 0,
>   ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
> @@ -714,8 +725,10 @@ 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);
> - if (!ret)
> + if (!ret) {
> + hdcp->hdcp_encrypted = 1;
>   return 0;
> + }
>  
>   DRM_DEBUG_KMS("HDCP Auth failure (%d)\n", ret);
>  
> @@ -742,16 +755,17 @@ int intel_hdcp_check_link(struct intel_connector 
> *connector)
>   enum port port = intel_dig_port->base.port;
>   int ret = 0;
>  
> - if (!hdcp->shim)
> - return -ENOENT;
> -
>   mutex_lock(>mutex);
>  
> - if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
> + /* Check_link valid only when HDCP1.4 is enabled */
> + if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_ENABLED ||
> + !hdcp->hdcp_encrypted) {
> +  

[PATCH v9 08/39] drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking

2018-12-12 Thread Ramalingam C
"hdcp_encrypted" flag is defined to denote the HDCP1.4 encryption status.
This SW tracking is used to determine the need for real hdcp1.4 disable
and hdcp_check_link upon CP_IRQ.

On CP_IRQ we filter the CP_IRQ related to the states like Link failure
and reauthentication req etc and handle them in hdcp_check_link.
CP_IRQ corresponding to the authentication msg availability are ignored.

WARN_ON is added for the abrupt stop of HDCP encryption of a port.

Signed-off-by: Ramalingam C 
---
 drivers/gpu/drm/i915/intel_dp.c   |  2 +-
 drivers/gpu/drm/i915/intel_drv.h  |  5 ++-
 drivers/gpu/drm/i915/intel_hdcp.c | 89 ++-
 3 files changed, 74 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index aba884c64879..89315e15fb34 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4758,7 +4758,7 @@ static void intel_dp_check_service_irq(struct intel_dp 
*intel_dp)
intel_dp_handle_test_request(intel_dp);
 
if (val & DP_CP_IRQ)
-   intel_hdcp_check_link(intel_dp->attached_connector);
+   intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
 
if (val & DP_SINK_SPECIFIC_IRQ)
DRM_DEBUG_DRIVER("Sink specific irq unhandled\n");
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 191b6e0f086c..decd0346c6a7 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -393,6 +393,9 @@ struct intel_hdcp {
struct delayed_work check_work;
struct work_struct prop_work;
 
+   /* HDCP1.4 Encryption status */
+   u8 hdcp_encrypted;
+
/* HDCP2.2 related definitions */
/* Flag indicates whether this connector supports HDCP2.2 or not. */
u8 hdcp2_supported;
@@ -2058,10 +2061,10 @@ int intel_hdcp_init(struct intel_connector *connector,
bool hdcp2_supported);
 int intel_hdcp_enable(struct intel_connector *connector);
 int intel_hdcp_disable(struct intel_connector *connector);
-int intel_hdcp_check_link(struct intel_connector *connector);
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
 bool intel_hdcp_capable(struct intel_connector *connector);
 bool is_hdcp2_supported(struct drm_i915_private *dev_priv);
+void intel_hdcp_handle_cp_irq(struct intel_connector *connector);
 
 /* intel_psr.c */
 #define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c 
b/drivers/gpu/drm/i915/intel_hdcp.c
index 9405fce07b93..2b7814a6f12b 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -75,6 +75,16 @@ bool intel_hdcp_capable(struct intel_connector *connector)
return capable;
 }
 
+static inline bool intel_hdcp_in_use(struct intel_connector *connector)
+{
+   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   enum port port = connector->encoder->port;
+   u32 reg;
+
+   reg = I915_READ(PORT_HDCP_STATUS(port));
+   return reg & HDCP_STATUS_ENC;
+}
+
 static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *intel_dig_port,
const struct intel_hdcp_shim *shim)
 {
@@ -669,6 +679,7 @@ static int _intel_hdcp_disable(struct intel_connector 
*connector)
DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
  connector->base.name, connector->base.base.id);
 
+   hdcp->hdcp_encrypted = 0;
I915_WRITE(PORT_HDCP_CONF(port), 0);
if (intel_wait_for_register(dev_priv, PORT_HDCP_STATUS(port), ~0, 0,
ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
@@ -714,8 +725,10 @@ 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);
-   if (!ret)
+   if (!ret) {
+   hdcp->hdcp_encrypted = 1;
return 0;
+   }
 
DRM_DEBUG_KMS("HDCP Auth failure (%d)\n", ret);
 
@@ -742,16 +755,17 @@ int intel_hdcp_check_link(struct intel_connector 
*connector)
enum port port = intel_dig_port->base.port;
int ret = 0;
 
-   if (!hdcp->shim)
-   return -ENOENT;
-
mutex_lock(>mutex);
 
-   if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+   /* Check_link valid only when HDCP1.4 is enabled */
+   if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_ENABLED ||
+   !hdcp->hdcp_encrypted) {
+   ret = -EINVAL;
goto out;
+   }
 
-   if (!(I915_READ(PORT_HDCP_STATUS(port)) & HDCP_STATUS_ENC)) {
-   DRM_ERROR("%s:%d HDCP check failed: link is not encrypted,%x\n",
+   if