Re: [Intel-gfx] [PATCH v5] drm/i915: Enable HDCP 1.4 and 2.2 on Gen12+
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+
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