From: Ramalingam C <ramalingam.c@intel.com>
To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
daniel.vetter@ffwll.ch, tomas.winkler@intel.com,
uma.shankar@intel.com
Subject: [PATCH v10 08/40] drm/i915: Enable and Disable of HDCP2.2
Date: Thu, 31 Jan 2019 12:29:24 +0530 [thread overview]
Message-ID: <1548917996-28081-9-git-send-email-ramalingam.c@intel.com> (raw)
In-Reply-To: <1548917996-28081-1-git-send-email-ramalingam.c@intel.com>
Considering that HDCP2.2 is more secure than HDCP1.4, When a setup
supports HDCP2.2 and HDCP1.4, HDCP2.2 will be enabled.
When HDCP2.2 enabling fails and HDCP1.4 is supported, HDCP1.4 is
enabled.
This change implements a sequence of enabling and disabling of
HDCP2.2 authentication and HDCP2.2 port encryption.
v2:
Included few optimization suggestions [Chris Wilson]
Commit message is updated as per the rebased version.
intel_wait_for_register is used instead of wait_for. [Chris Wilson]
v3:
Extra comment added and Style issue fixed [Uma]
v4:
Rebased as part of patch reordering.
HDCP2 encryption status is tracked.
HW state check is moved into WARN_ON [Daniel]
v5:
Redefined the mei service functions as per comp redesign.
Merged patches related to hdcp2.2 enabling and disabling [Sean Paul].
Required shim functionality is defined [Sean Paul]
v6:
Return values are handles [Uma]
Realigned the code.
Check for comp_master is removed.
v7:
HDCP2.2 is attempted only if mei interface is up.
Adjust to the new interface
Avoid bool usage in struct [Tomas]
v8:
mei_binded status check is removed.
%s/hdcp2_in_use/hdcp2_encrypted
v9:
bool is used in struct intel_hdcp. [Daniel]
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
drivers/gpu/drm/i915/intel_drv.h | 7 ++
drivers/gpu/drm/i915/intel_hdcp.c | 202 +++++++++++++++++++++++++++++++++++---
2 files changed, 195 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 13a41e8cf4ff..31c7a4577ca9 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -389,6 +389,10 @@ struct intel_hdcp_shim {
/* HDCP adaptation(DP/HDMI) required on the port */
enum hdcp_wired_protocol protocol;
+
+ /* Detects whether Panel is HDCP2.2 capable */
+ int (*hdcp_2_2_capable)(struct intel_digital_port *intel_dig_port,
+ bool *capable);
};
struct intel_hdcp {
@@ -406,6 +410,9 @@ struct intel_hdcp {
/* Flag indicates whether this connector supports HDCP2.2 or not. */
bool hdcp2_supported;
+ /* HDCP2.2 Encryption status */
+ bool hdcp2_encrypted;
+
/*
* Content Stream Type defined by content owner. TYPE0(0x0) content can
* flow in the link protected by HDCP2.2 or HDCP1.4, where as TYPE1(0x1)
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index c1b057f1501b..fbf8b7893bfa 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -74,6 +74,23 @@ bool intel_hdcp_capable(struct intel_connector *connector)
return capable;
}
+/* Is HDCP2.2 capable on Platform and Sink */
+static bool intel_hdcp2_capable(struct intel_connector *connector)
+{
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ bool capable = false;
+
+ /* I915 support for HDCP2.2 */
+ if (!hdcp->hdcp2_supported)
+ return false;
+
+ /* Sink's capability for HDCP2.2 */
+ hdcp->shim->hdcp_2_2_capable(intel_dig_port, &capable);
+
+ return capable;
+}
+
static inline bool intel_hdcp_in_use(struct intel_connector *connector)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -1094,8 +1111,7 @@ int hdcp2_authenticate_port(struct intel_connector *connector)
return ret;
}
-static __attribute__((unused))
-int hdcp2_close_mei_session(struct intel_connector *connector)
+static int hdcp2_close_mei_session(struct intel_connector *connector)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct i915_hdcp_comp_master *comp;
@@ -1116,12 +1132,157 @@ int hdcp2_close_mei_session(struct intel_connector *connector)
return ret;
}
-static __attribute__((unused))
-int hdcp2_deauthenticate_port(struct intel_connector *connector)
+static int hdcp2_deauthenticate_port(struct intel_connector *connector)
{
return hdcp2_close_mei_session(connector);
}
+static int hdcp2_authenticate_sink(struct intel_connector *connector)
+{
+ DRM_ERROR("Sink authentication is done in subsequent patches\n");
+
+ return -EINVAL;
+}
+
+static int hdcp2_enable_encryption(struct intel_connector *connector)
+{
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ enum port port = connector->encoder->port;
+ int ret;
+
+ WARN_ON(I915_READ(HDCP2_STATUS_DDI(port)) & LINK_ENCRYPTION_STATUS);
+
+ if (hdcp->shim->toggle_signalling) {
+ ret = hdcp->shim->toggle_signalling(intel_dig_port, true);
+ if (ret) {
+ DRM_ERROR("Failed to enable HDCP signalling. %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ if (I915_READ(HDCP2_STATUS_DDI(port)) & LINK_AUTH_STATUS) {
+ /* Link is Authenticated. Now set for Encryption */
+ I915_WRITE(HDCP2_CTL_DDI(port),
+ I915_READ(HDCP2_CTL_DDI(port)) |
+ CTL_LINK_ENCRYPTION_REQ);
+ }
+
+ ret = intel_wait_for_register(dev_priv, HDCP2_STATUS_DDI(port),
+ LINK_ENCRYPTION_STATUS,
+ LINK_ENCRYPTION_STATUS,
+ ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
+
+ return ret;
+}
+
+static int hdcp2_disable_encryption(struct intel_connector *connector)
+{
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ enum port port = connector->encoder->port;
+ int ret;
+
+ WARN_ON(!(I915_READ(HDCP2_STATUS_DDI(port)) & LINK_ENCRYPTION_STATUS));
+
+ I915_WRITE(HDCP2_CTL_DDI(port),
+ I915_READ(HDCP2_CTL_DDI(port)) & ~CTL_LINK_ENCRYPTION_REQ);
+
+ ret = intel_wait_for_register(dev_priv, HDCP2_STATUS_DDI(port),
+ LINK_ENCRYPTION_STATUS, 0x0,
+ ENCRYPT_STATUS_CHANGE_TIMEOUT_MS);
+ if (ret == -ETIMEDOUT)
+ DRM_DEBUG_KMS("Disable Encryption Timedout");
+
+ if (hdcp->shim->toggle_signalling) {
+ ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
+ if (ret) {
+ DRM_ERROR("Failed to disable HDCP signalling. %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static int hdcp2_authenticate_and_encrypt(struct intel_connector *connector)
+{
+ int ret, i, tries = 3;
+
+ for (i = 0; i < tries; i++) {
+ ret = hdcp2_authenticate_sink(connector);
+ if (!ret)
+ break;
+
+ /* Clearing the mei hdcp session */
+ DRM_DEBUG_KMS("HDCP2.2 Auth %d of %d Failed.(%d)\n",
+ i + 1, tries, ret);
+ if (hdcp2_deauthenticate_port(connector) < 0)
+ DRM_DEBUG_KMS("Port deauth failed.\n");
+ }
+
+ if (i != tries) {
+ /*
+ * Ensuring the required 200mSec min time interval between
+ * Session Key Exchange and encryption.
+ */
+ msleep(HDCP_2_2_DELAY_BEFORE_ENCRYPTION_EN);
+ ret = hdcp2_enable_encryption(connector);
+ if (ret < 0) {
+ DRM_DEBUG_KMS("Encryption Enable Failed.(%d)\n", ret);
+ if (hdcp2_deauthenticate_port(connector) < 0)
+ DRM_DEBUG_KMS("Port deauth failed.\n");
+ }
+ }
+
+ return ret;
+}
+
+static int _intel_hdcp2_enable(struct intel_connector *connector)
+{
+ struct intel_hdcp *hdcp = &connector->hdcp;
+ int ret;
+
+ DRM_DEBUG_KMS("[%s:%d] HDCP2.2 is being enabled. Type: %d\n",
+ connector->base.name, connector->base.base.id,
+ hdcp->content_type);
+
+ ret = hdcp2_authenticate_and_encrypt(connector);
+ if (ret) {
+ DRM_DEBUG_KMS("HDCP2 Type%d Enabling Failed. (%d)\n",
+ hdcp->content_type, ret);
+ return ret;
+ }
+
+ DRM_DEBUG_KMS("[%s:%d] HDCP2.2 is enabled. Type %d\n",
+ connector->base.name, connector->base.base.id,
+ hdcp->content_type);
+
+ hdcp->hdcp2_encrypted = true;
+ return 0;
+}
+
+static int _intel_hdcp2_disable(struct intel_connector *connector)
+{
+ int ret;
+
+ DRM_DEBUG_KMS("[%s:%d] HDCP2.2 is being Disabled\n",
+ connector->base.name, connector->base.base.id);
+
+ ret = hdcp2_disable_encryption(connector);
+
+ if (hdcp2_deauthenticate_port(connector) < 0)
+ DRM_DEBUG_KMS("Port deauth failed.\n");
+
+ connector->hdcp.hdcp2_encrypted = false;
+
+ return ret;
+}
+
static void intel_hdcp_check_work(struct work_struct *work)
{
struct intel_hdcp *hdcp = container_of(to_delayed_work(work),
@@ -1270,22 +1431,33 @@ int intel_hdcp_init(struct intel_connector *connector,
int intel_hdcp_enable(struct intel_connector *connector)
{
struct intel_hdcp *hdcp = &connector->hdcp;
- int ret;
+ int ret = -EINVAL;
if (!hdcp->shim)
return -ENOENT;
mutex_lock(&hdcp->mutex);
- ret = _intel_hdcp_enable(connector);
- if (ret)
- goto out;
+ /*
+ * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
+ * is capable of HDCP2.2, it is preferred to use HDCP2.2.
+ */
+ if (intel_hdcp2_capable(connector))
+ ret = _intel_hdcp2_enable(connector);
+
+ /* When HDCP2.2 fails, HDCP1.4 will be attempted */
+ if (ret && intel_hdcp_capable(connector)) {
+ ret = _intel_hdcp_enable(connector);
+ if (!ret)
+ schedule_delayed_work(&hdcp->check_work,
+ DRM_HDCP_CHECK_PERIOD_MS);
+ }
+
+ if (!ret) {
+ hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
+ schedule_work(&hdcp->prop_work);
+ }
- hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
- schedule_work(&hdcp->prop_work);
- schedule_delayed_work(&hdcp->check_work,
- DRM_HDCP_CHECK_PERIOD_MS);
-out:
mutex_unlock(&hdcp->mutex);
return ret;
}
@@ -1302,7 +1474,9 @@ int intel_hdcp_disable(struct intel_connector *connector)
if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
hdcp->value = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
- if (hdcp->hdcp_encrypted)
+ if (hdcp->hdcp2_encrypted)
+ ret = _intel_hdcp2_disable(connector);
+ else if (hdcp->hdcp_encrypted)
ret = _intel_hdcp_disable(connector);
}
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2019-01-31 6:59 UTC|newest]
Thread overview: 109+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-31 6:59 [PATCH v10 00/40] drm/i915: Implement HDCP2.2 Ramalingam C
2019-01-31 6:59 ` [PATCH v10 01/40] components: multiple components for a device Ramalingam C
2019-01-31 7:50 ` Greg Kroah-Hartman
2019-01-31 8:00 ` Daniel Vetter
2019-01-31 8:12 ` Greg Kroah-Hartman
2019-01-31 8:39 ` Daniel Vetter
2019-02-06 16:45 ` [PATCH 1/3] component: Add documentation Daniel Vetter
2019-02-06 16:45 ` [PATCH 2/3] components: multiple components for a device Daniel Vetter
2019-02-06 22:57 ` Rafael J. Wysocki
2019-02-07 22:35 ` Daniel Vetter
2019-02-07 22:40 ` Daniel Vetter
2019-02-07 22:48 ` Rafael J. Wysocki
2019-02-06 16:45 ` [PATCH 3/3] drm/doc: document recommended component helper usage Daniel Vetter
2019-01-31 6:59 ` [PATCH v10 02/40] i915/snd_hdac: I915 subcomponent for the snd_hdac Ramalingam C
2019-02-04 15:00 ` Daniel Vetter
2019-02-04 15:09 ` Takashi Iwai
2019-01-31 6:59 ` [PATCH v10 03/40] drm/i915: Gathering the HDCP1.4 routines together Ramalingam C
2019-02-04 13:11 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 04/40] drm: header for i915 - MEI_HDCP interface Ramalingam C
2019-02-04 13:24 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 05/40] drm/i915: Initialize HDCP2.2 Ramalingam C
2019-02-04 13:29 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 06/40] drm/i915: MEI interface definition Ramalingam C
2019-01-31 8:17 ` Daniel Vetter
2019-01-31 13:39 ` C, Ramalingam
2019-01-31 6:59 ` [PATCH v10 07/40] drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking Ramalingam C
2019-01-31 7:56 ` Daniel Vetter
2019-01-31 13:41 ` C, Ramalingam
2019-02-04 14:09 ` Shankar, Uma
2019-02-04 14:43 ` C, Ramalingam
2019-01-31 6:59 ` Ramalingam C [this message]
2019-02-04 14:17 ` [PATCH v10 08/40] drm/i915: Enable and Disable of HDCP2.2 Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 09/40] drm/i915: Implement HDCP2.2 receiver authentication Ramalingam C
2019-02-04 14:20 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 10/40] drm: helper functions for hdcp2 seq_num to from u32 Ramalingam C
2019-02-04 14:20 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 11/40] drm/i915: Implement HDCP2.2 repeater authentication Ramalingam C
2019-02-04 14:21 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 12/40] drm: HDCP2.2 link check period Ramalingam C
2019-02-04 14:24 ` Shankar, Uma
2019-02-04 14:50 ` C, Ramalingam
2019-01-31 6:59 ` [PATCH v10 13/40] drm/i915: Implement HDCP2.2 link integrity check Ramalingam C
2019-02-04 14:28 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 14/40] drm/i915: Handle HDCP2.2 downstream topology change Ramalingam C
2019-02-04 14:31 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 15/40] drm: removing the DP Errata msg and its msg id Ramalingam C
2019-01-31 8:02 ` Daniel Vetter
2019-02-04 14:35 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 16/40] drm/i915: Implement the HDCP2.2 support for DP Ramalingam C
2019-02-04 16:02 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 17/40] drm/i915: Implement the HDCP2.2 support for HDMI Ramalingam C
2019-02-04 16:03 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 18/40] drm/i915: CP_IRQ handling for DP HDCP2.2 msgs Ramalingam C
2019-01-31 8:08 ` Daniel Vetter
2019-01-31 12:50 ` Daniel Vetter
2019-01-31 6:59 ` [PATCH v10 19/40] drm/i915: Add HDCP2.2 support for DP connectors Ramalingam C
2019-02-04 16:08 ` Winkler, Tomas
2019-01-31 6:59 ` [PATCH v10 20/40] drm/i915: Add HDCP2.2 support for HDMI connectors Ramalingam C
2019-02-04 16:04 ` Winkler, Tomas
2019-02-04 16:11 ` C, Ramalingam
2019-01-31 6:59 ` [PATCH v10 21/40] mei: bus: whitelist hdcp client Ramalingam C
2019-01-31 6:59 ` [PATCH v10 22/40] mei: bus: export to_mei_cl_device for mei client device drivers Ramalingam C
2019-01-31 6:59 ` [PATCH v10 23/40] misc/mei/hdcp: Client driver for HDCP application Ramalingam C
2019-02-05 12:33 ` Winkler, Tomas
2019-01-31 6:59 ` [PATCH v10 24/40] misc/mei/hdcp: Define ME FW interface for HDCP2.2 Ramalingam C
2019-02-04 16:07 ` Shankar, Uma
2019-02-05 13:01 ` Winkler, Tomas
2019-01-31 6:59 ` [PATCH v10 25/40] misc/mei/hdcp: Initiate Wired HDCP2.2 Tx Session Ramalingam C
2019-02-04 16:09 ` Shankar, Uma
2019-02-05 13:09 ` Winkler, Tomas
2019-02-05 14:13 ` C, Ramalingam
2019-02-06 10:27 ` Winkler, Tomas
2019-02-06 21:14 ` C, Ramalingam
2019-01-31 6:59 ` [PATCH v10 26/40] misc/mei/hdcp: Verify Receiver Cert and prepare km Ramalingam C
2019-02-04 16:10 ` Shankar, Uma
2019-02-06 8:28 ` Winkler, Tomas
2019-01-31 6:59 ` [PATCH v10 27/40] misc/mei/hdcp: Verify H_prime Ramalingam C
2019-02-04 16:11 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 28/40] misc/mei/hdcp: Store the HDCP Pairing info Ramalingam C
2019-02-04 16:13 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 29/40] misc/mei/hdcp: Initiate Locality check Ramalingam C
2019-02-04 16:16 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 30/40] misc/mei/hdcp: Verify L_prime Ramalingam C
2019-02-04 16:16 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 31/40] misc/mei/hdcp: Prepare Session Key Ramalingam C
2019-02-04 16:17 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 32/40] misc/mei/hdcp: Repeater topology verification and ack Ramalingam C
2019-02-04 16:17 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 33/40] misc/mei/hdcp: Verify M_prime Ramalingam C
2019-02-04 16:18 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 34/40] misc/mei/hdcp: Enabling the HDCP authentication Ramalingam C
2019-02-04 16:19 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 35/40] misc/mei/hdcp: Closing wired HDCP2.2 Tx Session Ramalingam C
2019-02-04 16:20 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 36/40] misc/mei/hdcp: Component framework for I915 Interface Ramalingam C
2019-01-31 8:23 ` Daniel Vetter
2019-02-04 16:27 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 37/40] drm/i915: Commit CP without modeset Ramalingam C
2019-01-31 8:32 ` Daniel Vetter
2019-02-04 8:39 ` C, Ramalingam
2019-01-31 6:59 ` [PATCH v10 38/40] drm/i915: Fix KBL HDCP2.2 encrypt status signalling Ramalingam C
2019-02-04 15:32 ` C, Ramalingam
2019-02-05 8:54 ` Daniel Vetter
2019-02-04 16:35 ` Shankar, Uma
2019-01-31 6:59 ` [PATCH v10 39/40] FOR_TEST: i915/Kconfig: Select mei_hdcp by I915 Ramalingam C
2019-01-31 6:59 ` [PATCH v10 40/40] FOR_TESTING_ONLY: debugfs: Excluding the LSPCon for HDCP1.4 Ramalingam C
2019-01-31 7:38 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Implement HDCP2.2 (rev13) Patchwork
2019-01-31 8:16 ` ✓ Fi.CI.BAT: success " Patchwork
2019-01-31 18:42 ` ✓ Fi.CI.IGT: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1548917996-28081-9-git-send-email-ramalingam.c@intel.com \
--to=ramalingam.c@intel.com \
--cc=daniel.vetter@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-gfx@lists.freedesktop.org \
--cc=tomas.winkler@intel.com \
--cc=uma.shankar@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox