Re: [PATCH v9 08/39] drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking
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
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
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
"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