Re: [Intel-gfx] [PATCH v5] drm/i915: Enable HDCP 1.4 and 2.2 on Gen12+

2019-07-09 Thread Sharma, Shashank

Regards

Shashank

On 7/9/2019 7:39 AM, Ramalingam C wrote:

 From Gen12 onwards, HDCP HW block is implemented within transcoders.
Till Gen11 HDCP HW block was part of DDI.

Hence required changes in HW programming is handled here.

v2:
   _MMIO_TRANS is used [Lucas and Daniel]
   platform check is moved into the caller [Lucas]
v3:
   platform check is moved into a macro [Shashank]
v4:
   Few optimizations in the coding [Shashank]
v5:
   Fixed alignment in macro definition in i915_reg.h [Shashank]
   unused variables "reg" is removed.

Signed-off-by: Ramalingam C 
---
  drivers/gpu/drm/i915/display/intel_hdcp.c | 133 +-
  drivers/gpu/drm/i915/display/intel_hdmi.c |   9 +-
  drivers/gpu/drm/i915/i915_reg.h   | 120 +--
  drivers/gpu/drm/i915/intel_drv.h  |   8 ++
  4 files changed, 207 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index bc3a94d491c4..23dc3ad4ba4c 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -17,6 +17,7 @@
  #include "intel_drv.h"
  #include "intel_hdcp.h"
  #include "intel_sideband.h"
+#include "intel_connector.h"
  
  #define KEY_LOAD_TRIES	5

  #define ENCRYPT_STATUS_CHANGE_TIMEOUT_MS  50
@@ -104,24 +105,17 @@ bool intel_hdcp2_capable(struct intel_connector 
*connector)
return capable;
  }
  
-static inline bool intel_hdcp_in_use(struct intel_connector *connector)

+static inline bool intel_hdcp_in_use(struct drm_i915_private *dev_priv,
+enum pipe pipe, enum port port)
  {
-   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;
+   return I915_READ(HDCP_STATUS(dev_priv, pipe, port)) & HDCP_STATUS_ENC;
  }
  
-static inline bool intel_hdcp2_in_use(struct intel_connector *connector)

+static inline bool intel_hdcp2_in_use(struct drm_i915_private *dev_priv,
+ enum pipe pipe, enum port port)
  {
-   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-   enum port port = connector->encoder->port;
-   u32 reg;
-
-   reg = I915_READ(HDCP2_STATUS_DDI(port));
-   return reg & LINK_ENCRYPTION_STATUS;
+   return I915_READ(HDCP2_STATUS(dev_priv, pipe, port)) &
+  LINK_ENCRYPTION_STATUS;
  }
  
  static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *intel_dig_port,

@@ -253,9 +247,28 @@ static int intel_write_sha_text(struct drm_i915_private 
*dev_priv, u32 sha_text)
  }
  
  static

-u32 intel_hdcp_get_repeater_ctl(struct intel_digital_port *intel_dig_port)
+u32 intel_hdcp_get_repeater_ctl(struct drm_i915_private *dev_priv,
+   enum pipe pipe, enum port port)
  {
-   enum port port = intel_dig_port->base.port;
+   if (INTEL_GEN(dev_priv) >= 12) {
+   switch (pipe) {
+   case PIPE_A:
+   return HDCP_TRANSA_REP_PRESENT |
+  HDCP_TRANSA_SHA1_M0;
+   case PIPE_B:
+   return HDCP_TRANSB_REP_PRESENT |
+  HDCP_TRANSB_SHA1_M0;
+   case PIPE_C:
+   return HDCP_TRANSC_REP_PRESENT |
+  HDCP_TRANSC_SHA1_M0;
+   /* FIXME: Add a case for PIPE_D */
+   default:
+   DRM_ERROR("Unknown pipe %d\n", pipe);
+   break;
+   }
+   return -EINVAL;
+   }
+
switch (port) {
case PORT_A:
return HDCP_DDIA_REP_PRESENT | HDCP_DDIA_SHA1_M0;
@@ -268,18 +281,21 @@ u32 intel_hdcp_get_repeater_ctl(struct intel_digital_port 
*intel_dig_port)
case PORT_E:
return HDCP_DDIE_REP_PRESENT | HDCP_DDIE_SHA1_M0;
default:
+   DRM_ERROR("Unknown port %d\n", port);
break;
}
-   DRM_ERROR("Unknown port %d\n", port);
return -EINVAL;
  }
  
  static

-int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port,
+int intel_hdcp_validate_v_prime(struct intel_connector *connector,
const struct intel_hdcp_shim *shim,
u8 *ksv_fifo, u8 num_downstream, u8 *bstatus)
  {
+   struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
struct drm_i915_private *dev_priv;
+   enum pipe pipe = connector->hdcp.pipe;
+   enum port port = intel_dig_port->base.port;
u32 vprime, sha_text, sha_leftovers, rep_ctl;
int ret, i, j, sha_idx;
  
@@ -306,7 +322,7 @@ int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port,

sha_idx = 0;
sha_text = 0;
sha_leftovers = 0;
-   

[Intel-gfx] [PATCH v5] drm/i915: Enable HDCP 1.4 and 2.2 on Gen12+

2019-07-09 Thread Ramalingam C
From Gen12 onwards, HDCP HW block is implemented within transcoders.
Till Gen11 HDCP HW block was part of DDI.

Hence required changes in HW programming is handled here.

v2:
  _MMIO_TRANS is used [Lucas and Daniel]
  platform check is moved into the caller [Lucas]
v3:
  platform check is moved into a macro [Shashank]
v4:
  Few optimizations in the coding [Shashank]
v5:
  Fixed alignment in macro definition in i915_reg.h [Shashank]
  unused variables "reg" is removed.

Signed-off-by: Ramalingam C 
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 133 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c |   9 +-
 drivers/gpu/drm/i915/i915_reg.h   | 120 +--
 drivers/gpu/drm/i915/intel_drv.h  |   8 ++
 4 files changed, 207 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c 
b/drivers/gpu/drm/i915/display/intel_hdcp.c
index bc3a94d491c4..23dc3ad4ba4c 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -17,6 +17,7 @@
 #include "intel_drv.h"
 #include "intel_hdcp.h"
 #include "intel_sideband.h"
+#include "intel_connector.h"
 
 #define KEY_LOAD_TRIES 5
 #define ENCRYPT_STATUS_CHANGE_TIMEOUT_MS   50
@@ -104,24 +105,17 @@ bool intel_hdcp2_capable(struct intel_connector 
*connector)
return capable;
 }
 
-static inline bool intel_hdcp_in_use(struct intel_connector *connector)
+static inline bool intel_hdcp_in_use(struct drm_i915_private *dev_priv,
+enum pipe pipe, enum port port)
 {
-   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;
+   return I915_READ(HDCP_STATUS(dev_priv, pipe, port)) & HDCP_STATUS_ENC;
 }
 
-static inline bool intel_hdcp2_in_use(struct intel_connector *connector)
+static inline bool intel_hdcp2_in_use(struct drm_i915_private *dev_priv,
+ enum pipe pipe, enum port port)
 {
-   struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-   enum port port = connector->encoder->port;
-   u32 reg;
-
-   reg = I915_READ(HDCP2_STATUS_DDI(port));
-   return reg & LINK_ENCRYPTION_STATUS;
+   return I915_READ(HDCP2_STATUS(dev_priv, pipe, port)) &
+  LINK_ENCRYPTION_STATUS;
 }
 
 static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *intel_dig_port,
@@ -253,9 +247,28 @@ static int intel_write_sha_text(struct drm_i915_private 
*dev_priv, u32 sha_text)
 }
 
 static
-u32 intel_hdcp_get_repeater_ctl(struct intel_digital_port *intel_dig_port)
+u32 intel_hdcp_get_repeater_ctl(struct drm_i915_private *dev_priv,
+   enum pipe pipe, enum port port)
 {
-   enum port port = intel_dig_port->base.port;
+   if (INTEL_GEN(dev_priv) >= 12) {
+   switch (pipe) {
+   case PIPE_A:
+   return HDCP_TRANSA_REP_PRESENT |
+  HDCP_TRANSA_SHA1_M0;
+   case PIPE_B:
+   return HDCP_TRANSB_REP_PRESENT |
+  HDCP_TRANSB_SHA1_M0;
+   case PIPE_C:
+   return HDCP_TRANSC_REP_PRESENT |
+  HDCP_TRANSC_SHA1_M0;
+   /* FIXME: Add a case for PIPE_D */
+   default:
+   DRM_ERROR("Unknown pipe %d\n", pipe);
+   break;
+   }
+   return -EINVAL;
+   }
+
switch (port) {
case PORT_A:
return HDCP_DDIA_REP_PRESENT | HDCP_DDIA_SHA1_M0;
@@ -268,18 +281,21 @@ u32 intel_hdcp_get_repeater_ctl(struct intel_digital_port 
*intel_dig_port)
case PORT_E:
return HDCP_DDIE_REP_PRESENT | HDCP_DDIE_SHA1_M0;
default:
+   DRM_ERROR("Unknown port %d\n", port);
break;
}
-   DRM_ERROR("Unknown port %d\n", port);
return -EINVAL;
 }
 
 static
-int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port,
+int intel_hdcp_validate_v_prime(struct intel_connector *connector,
const struct intel_hdcp_shim *shim,
u8 *ksv_fifo, u8 num_downstream, u8 *bstatus)
 {
+   struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
struct drm_i915_private *dev_priv;
+   enum pipe pipe = connector->hdcp.pipe;
+   enum port port = intel_dig_port->base.port;
u32 vprime, sha_text, sha_leftovers, rep_ctl;
int ret, i, j, sha_idx;
 
@@ -306,7 +322,7 @@ int intel_hdcp_validate_v_prime(struct intel_digital_port 
*intel_dig_port,
sha_idx = 0;
sha_text = 0;
sha_leftovers = 0;
-   rep_ctl = intel_hdcp_get_repeater_ctl(intel_dig_port);
+   rep_ctl = intel_hdcp_get_repeater_ctl(de