Commit 1f088221 authored by Sean Paul's avatar Sean Paul Committed by Ramalingam C

drm/i915: Fix sha_text population code

This patch fixes a few bugs:

1- We weren't taking into account sha_leftovers when adding multiple
   ksvs to sha_text. As such, we were or'ing the end of ksv[j - 1] with
   the beginning of ksv[j]

2- In the sha_leftovers == 2 and sha_leftovers == 3 case, bstatus was
   being placed on the wrong half of sha_text, overlapping the leftover
   ksv value

3- In the sha_leftovers == 2 case, we need to manually terminate the
   byte stream with 0x80 since the hardware doesn't have enough room to
   add it after writing M0

The upside is that all of the HDCP supported HDMI repeaters I could
find on Amazon just strip HDCP anyways, so it turns out to be _really_
hard to hit any of these cases without an MST hub, which is not (yet)
supported. Oh, and the sha_leftovers == 1 case works perfectly!

Fixes: ee5e5e7a ("drm/i915: Add HDCP framework + base implementation")
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Ramalingam C <ramalingam.c@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Sean Paul <seanpaul@chromium.org>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v4.17+
Reviewed-by: default avatarRamalingam C <ramalingam.c@intel.com>
Signed-off-by: default avatarSean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-2-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-2-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-2-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-2-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-2-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-2-sean@poorly.run #v6
Link: https://patchwork.freedesktop.org/patch/msgid/20200623155907.22961-2-sean@poorly.run #v7

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-Rebased on intel_de_write changes
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-None
Changes in v8:
-None
Signed-off-by: default avatarRamalingam C <ramalingam.c@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200818153910.27894-2-sean@poorly.run
parent d452bd09
...@@ -327,8 +327,10 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, ...@@ -327,8 +327,10 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
/* Fill up the empty slots in sha_text and write it out */ /* Fill up the empty slots in sha_text and write it out */
sha_empty = sizeof(sha_text) - sha_leftovers; sha_empty = sizeof(sha_text) - sha_leftovers;
for (j = 0; j < sha_empty; j++) for (j = 0; j < sha_empty; j++) {
sha_text |= ksv[j] << ((sizeof(sha_text) - j - 1) * 8); u8 off = ((sizeof(sha_text) - j - 1 - sha_leftovers) * 8);
sha_text |= ksv[j] << off;
}
ret = intel_write_sha_text(dev_priv, sha_text); ret = intel_write_sha_text(dev_priv, sha_text);
if (ret < 0) if (ret < 0)
...@@ -426,7 +428,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, ...@@ -426,7 +428,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
/* Write 32 bits of text */ /* Write 32 bits of text */
intel_de_write(dev_priv, HDCP_REP_CTL, intel_de_write(dev_priv, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_32); rep_ctl | HDCP_SHA1_TEXT_32);
sha_text |= bstatus[0] << 24 | bstatus[1] << 16; sha_text |= bstatus[0] << 8 | bstatus[1];
ret = intel_write_sha_text(dev_priv, sha_text); ret = intel_write_sha_text(dev_priv, sha_text);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -441,17 +443,29 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, ...@@ -441,17 +443,29 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
return ret; return ret;
sha_idx += sizeof(sha_text); sha_idx += sizeof(sha_text);
} }
/*
* Terminate the SHA-1 stream by hand. For the other leftover
* cases this is appended by the hardware.
*/
intel_de_write(dev_priv, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_32);
sha_text = DRM_HDCP_SHA1_TERMINATOR << 24;
ret = intel_write_sha_text(dev_priv, sha_text);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
} else if (sha_leftovers == 3) { } else if (sha_leftovers == 3) {
/* Write 32 bits of text */ /* Write 32 bits of text (filled from LSB) */
intel_de_write(dev_priv, HDCP_REP_CTL, intel_de_write(dev_priv, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_32); rep_ctl | HDCP_SHA1_TEXT_32);
sha_text |= bstatus[0] << 24; sha_text |= bstatus[0];
ret = intel_write_sha_text(dev_priv, sha_text); ret = intel_write_sha_text(dev_priv, sha_text);
if (ret < 0) if (ret < 0)
return ret; return ret;
sha_idx += sizeof(sha_text); sha_idx += sizeof(sha_text);
/* Write 8 bits of text, 24 bits of M0 */ /* Write 8 bits of text (filled from LSB), 24 bits of M0 */
intel_de_write(dev_priv, HDCP_REP_CTL, intel_de_write(dev_priv, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_8); rep_ctl | HDCP_SHA1_TEXT_8);
ret = intel_write_sha_text(dev_priv, bstatus[1]); ret = intel_write_sha_text(dev_priv, bstatus[1]);
......
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
/* Slave address for the HDCP registers in the receiver */ /* Slave address for the HDCP registers in the receiver */
#define DRM_HDCP_DDC_ADDR 0x3A #define DRM_HDCP_DDC_ADDR 0x3A
/* Value to use at the end of the SHA-1 bytestream used for repeaters */
#define DRM_HDCP_SHA1_TERMINATOR 0x80
/* HDCP register offsets for HDMI/DVI devices */ /* HDCP register offsets for HDMI/DVI devices */
#define DRM_HDCP_DDC_BKSV 0x00 #define DRM_HDCP_DDC_BKSV 0x00
#define DRM_HDCP_DDC_RI_PRIME 0x08 #define DRM_HDCP_DDC_RI_PRIME 0x08
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment