218 lines
6.9 KiB
Diff
218 lines
6.9 KiB
Diff
From b89820de7ae4fe0574cd230e25d410b8d6f37a63 Mon Sep 17 00:00:00 2001
|
|
From: "Romli, Khairul Anuar" <khairul.anuar.romli@intel.com>
|
|
Date: Tue, 9 Oct 2018 19:02:37 +0800
|
|
Subject: [PATCH 697/743] drm/i915: Passing the intel_connector to HDCP auth
|
|
|
|
Reference of Intel_connector is needed at generic authentication flow
|
|
for upcoming revocation check and downstream topology info gathering
|
|
etc.
|
|
|
|
As a preparation for storing the downstream topology information at
|
|
intel_connector and accessig SRM revocated ID list from intel_connector,
|
|
we are passing the intel_connector reference to hdcp authentication.
|
|
|
|
Change-Id: I2cb3608ed1d3b408e3531fe15687a01f78d716b0
|
|
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
|
|
Signed-off-by: Romli, Khairul Anuar <khairul.anuar.romli@intel.com>
|
|
---
|
|
drivers/gpu/drm/i915/intel_hdcp.c | 143 ++++++++++++------------------
|
|
1 file changed, 57 insertions(+), 86 deletions(-)
|
|
|
|
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
|
|
index 7f87667753b3..a03a745544e2 100644
|
|
--- a/drivers/gpu/drm/i915/intel_hdcp.c
|
|
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
|
|
@@ -179,16 +179,60 @@ bool intel_hdcp_is_ksv_valid(u8 *ksv)
|
|
return true;
|
|
}
|
|
|
|
+struct intel_digital_port *conn_to_dig_port(struct intel_connector *connector)
|
|
+{
|
|
+ return enc_to_dig_port(&intel_attached_encoder(&connector->base)->base);
|
|
+}
|
|
+
|
|
+/* Implements Part 2 of the HDCP authorization procedure */
|
|
static
|
|
-int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port,
|
|
- const struct intel_hdcp_shim *shim,
|
|
- u8 *ksv_fifo, u8 num_downstream, u8 *bstatus)
|
|
+int intel_hdcp_auth_downstream(struct intel_connector *connector)
|
|
{
|
|
- struct drm_i915_private *dev_priv;
|
|
+ struct intel_digital_port *intel_dig_port =
|
|
+ conn_to_dig_port(connector);
|
|
+ const struct intel_hdcp_shim *shim = connector->hdcp_shim;
|
|
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
|
|
u32 vprime, sha_text, sha_leftovers, rep_ctl;
|
|
+ u8 bstatus[2], num_downstream, *ksv_fifo;
|
|
int ret, i, j, sha_idx;
|
|
|
|
- dev_priv = intel_dig_port->base.base.dev->dev_private;
|
|
+ if(intel_dig_port == NULL)
|
|
+ return EINVAL;
|
|
+
|
|
+ ret = intel_hdcp_poll_ksv_fifo(intel_dig_port, shim);
|
|
+ if (ret) {
|
|
+ DRM_ERROR("KSV list failed to become ready (%d)\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ret = shim->read_bstatus(intel_dig_port, bstatus);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ if (DRM_HDCP_MAX_DEVICE_EXCEEDED(bstatus[0]) ||
|
|
+ DRM_HDCP_MAX_CASCADE_EXCEEDED(bstatus[1])) {
|
|
+ DRM_ERROR("Max Topology Limit Exceeded\n");
|
|
+ return -EPERM;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * When repeater reports 0 device count, HDCP1.4 spec allows disabling
|
|
+ * the HDCP encryption. That implies that repeater can't have its own
|
|
+ * display. As there is no consumption of encrypted content in the
|
|
+ * repeater with 0 downstream devices, we are failing the
|
|
+ * authentication.
|
|
+ */
|
|
+ num_downstream = DRM_HDCP_NUM_DOWNSTREAM(bstatus[0]);
|
|
+ if (num_downstream == 0)
|
|
+ return -EINVAL;
|
|
+
|
|
+ ksv_fifo = kzalloc(num_downstream * DRM_HDCP_KSV_LEN, GFP_KERNEL);
|
|
+ if (!ksv_fifo)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ ret = shim->read_ksv_fifo(intel_dig_port, num_downstream, ksv_fifo);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
/* Process V' values from the receiver */
|
|
for (i = 0; i < DRM_HDCP_V_PRIME_NUM_PARTS; i++) {
|
|
@@ -394,79 +438,12 @@ int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port,
|
|
return 0;
|
|
}
|
|
|
|
-/* Implements Part 2 of the HDCP authorization procedure */
|
|
-static
|
|
-int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
|
|
- const struct intel_hdcp_shim *shim)
|
|
-{
|
|
- u8 bstatus[2], num_downstream, *ksv_fifo;
|
|
- int ret, i, tries = 3;
|
|
-
|
|
- ret = intel_hdcp_poll_ksv_fifo(intel_dig_port, shim);
|
|
- if (ret) {
|
|
- DRM_ERROR("KSV list failed to become ready (%d)\n", ret);
|
|
- return ret;
|
|
- }
|
|
-
|
|
- ret = shim->read_bstatus(intel_dig_port, bstatus);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
- if (DRM_HDCP_MAX_DEVICE_EXCEEDED(bstatus[0]) ||
|
|
- DRM_HDCP_MAX_CASCADE_EXCEEDED(bstatus[1])) {
|
|
- DRM_ERROR("Max Topology Limit Exceeded\n");
|
|
- return -EPERM;
|
|
- }
|
|
-
|
|
- /*
|
|
- * When repeater reports 0 device count, HDCP1.4 spec allows disabling
|
|
- * the HDCP encryption. That implies that repeater can't have its own
|
|
- * display. As there is no consumption of encrypted content in the
|
|
- * repeater with 0 downstream devices, we are failing the
|
|
- * authentication.
|
|
- */
|
|
- num_downstream = DRM_HDCP_NUM_DOWNSTREAM(bstatus[0]);
|
|
- if (num_downstream == 0)
|
|
- return -EINVAL;
|
|
-
|
|
- ksv_fifo = kcalloc(DRM_HDCP_KSV_LEN, num_downstream, GFP_KERNEL);
|
|
- if (!ksv_fifo)
|
|
- return -ENOMEM;
|
|
-
|
|
- ret = shim->read_ksv_fifo(intel_dig_port, num_downstream, ksv_fifo);
|
|
- if (ret)
|
|
- goto err;
|
|
-
|
|
- /*
|
|
- * When V prime mismatches, DP Spec mandates re-read of
|
|
- * V prime atleast twice.
|
|
- */
|
|
- for (i = 0; i < tries; i++) {
|
|
- ret = intel_hdcp_validate_v_prime(intel_dig_port, shim,
|
|
- ksv_fifo, num_downstream,
|
|
- bstatus);
|
|
- if (!ret)
|
|
- break;
|
|
- }
|
|
-
|
|
- if (i == tries) {
|
|
- DRM_ERROR("V Prime validation failed.(%d)\n", ret);
|
|
- goto err;
|
|
- }
|
|
-
|
|
- DRM_DEBUG_KMS("HDCP is enabled (%d downstream devices)\n",
|
|
- num_downstream);
|
|
- ret = 0;
|
|
-err:
|
|
- kfree(ksv_fifo);
|
|
- return ret;
|
|
-}
|
|
-
|
|
/* Implements Part 1 of the HDCP authorization procedure */
|
|
-static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
|
|
- const struct intel_hdcp_shim *shim)
|
|
+static int intel_hdcp_auth(struct intel_connector *connector)
|
|
{
|
|
- struct drm_i915_private *dev_priv;
|
|
+ struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
|
|
+ const struct intel_hdcp_shim *shim = connector->hdcp_shim;
|
|
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
|
|
enum port port;
|
|
unsigned long r0_prime_gen_start;
|
|
int ret, i, tries = 2;
|
|
@@ -484,7 +461,8 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
|
|
} ri;
|
|
bool repeater_present, hdcp_capable;
|
|
|
|
- dev_priv = intel_dig_port->base.base.dev->dev_private;
|
|
+ if(intel_dig_port == NULL)
|
|
+ return EINVAL;
|
|
|
|
port = intel_dig_port->base.port;
|
|
|
|
@@ -612,18 +590,12 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
|
|
*/
|
|
|
|
if (repeater_present)
|
|
- return intel_hdcp_auth_downstream(intel_dig_port, shim);
|
|
+ return intel_hdcp_auth_downstream(connector);
|
|
|
|
DRM_DEBUG_KMS("HDCP is enabled (no repeater present)\n");
|
|
return 0;
|
|
}
|
|
|
|
-static
|
|
-struct intel_digital_port *conn_to_dig_port(struct intel_connector *connector)
|
|
-{
|
|
- return enc_to_dig_port(&intel_attached_encoder(&connector->base)->base);
|
|
-}
|
|
-
|
|
static int _intel_hdcp_disable(struct intel_connector *connector)
|
|
{
|
|
struct drm_i915_private *dev_priv = connector->base.dev->dev_private;
|
|
@@ -677,8 +649,7 @@ 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),
|
|
- connector->hdcp_shim);
|
|
+ ret = intel_hdcp_auth(connector);
|
|
if (!ret) {
|
|
connector->hdcp_value =
|
|
DRM_MODE_CONTENT_PROTECTION_ENABLED;
|
|
--
|
|
2.19.2
|
|
|