Message ID | 20200429195502.39919-2-sean@poorly.run (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/i915: Add support for HDCP 1.4 over MST connectors | expand |
Hi [This is an automated email] This commit has been processed because it contains a "Fixes:" tag fixing commit: ee5e5e7a5e0f ("drm/i915: Add HDCP framework + base implementation"). The bot has tested the following trees: v5.6.7, v5.4.35, v4.19.118. v5.6.7: Failed to apply! Possible dependencies: 65833c463886 ("drm/i915/hdcp: conversion to struct drm_device based logging macros.") 667944ad77f1 ("drm/i915/hdcp: use intel_de_*() functions for register access") v5.4.35: Failed to apply! Possible dependencies: 65833c463886 ("drm/i915/hdcp: conversion to struct drm_device based logging macros.") 667944ad77f1 ("drm/i915/hdcp: use intel_de_*() functions for register access") 692059318c0f ("drm/i915/hdcp: Enable HDCP 1.4 and 2.2 on Gen12+") v4.19.118: Failed to apply! Possible dependencies: 04707f971636 ("drm/i915: Initialize HDCP2.2") 09d56393c1d8 ("drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking") 2f80d7bd8d93 ("drm/i915: drop all drmP.h includes") 33b7f3ee6e00 ("drm/i915: Add CRTC output format YCBCR 4:2:0") 340a44bef234 ("drm/i915/icl: program MG_DP_MODE") 342ac601df64 ("drm/i915: hdcp_check_link only on CP_IRQ") 47658556da85 ("drm/i915/dp: Do not grab crtc modeset lock in intel_dp_detect()") 667944ad77f1 ("drm/i915/hdcp: use intel_de_*() functions for register access") 668b6c176c33 ("drm/i915: Add YCBCR 4:2:0/4:4:4 support for LSPCON") 7b610f1fbed2 ("drm/i915/dp: Add DSC params and DSC config to intel_crtc_state") 9055aac76589 ("drm/i915: MEI interface implementation") 9844bc87cb7a ("drm/i915/dp: Fix duplication of DEVICE_SERVICE_IRQ handling") bdc93fe0eb82 ("drm/i915/debugfs: hdcp capability of a sink") cbfa8ac835cb ("drm/i915/dp: Kill intel_dp->detect_done flag") d3dacc70797b ("drm/i915: wrapping all hdcp var into intel_hdcp") d5acd97f5571 ("drm/i915/dp: Use a local variable for intel_encoder *") d78aa650670d ("drm: Add drm/drm_util.h header file") de25eb7f3075 ("drm/i915: introduce dp_to_i915() helper") f106d1005ac7 ("drm/i915: Pullout the bksv read and validation") NOTE: The patch will not be queued to stable trees until it is upstream. How should we proceed with this patch?
On 2020-04-29 at 15:54:47 -0400, Sean Paul wrote: > From: Sean Paul <seanpaul@chromium.org> > > 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: ee5e5e7a5e0f (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: Ramalingam C <ramalingam.c@intel.com> Just reconfirming my R-b here. Reviewed-by: Ramalingam C <ramalingam.c@intel.com> > Signed-off-by: Sean 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 > > 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 > --- > drivers/gpu/drm/i915/display/intel_hdcp.c | 26 +++++++++++++++++------ > include/drm/drm_hdcp.h | 3 +++ > 2 files changed, 23 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c > index 2cbc4619b4ce..525658fd201f 100644 > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c > @@ -336,8 +336,10 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, > > /* Fill up the empty slots in sha_text and write it out */ > sha_empty = sizeof(sha_text) - sha_leftovers; > - for (j = 0; j < sha_empty; j++) > - sha_text |= ksv[j] << ((sizeof(sha_text) - j - 1) * 8); > + for (j = 0; j < sha_empty; j++) { > + u8 off = ((sizeof(sha_text) - j - 1 - sha_leftovers) * 8); > + sha_text |= ksv[j] << off; > + } > > ret = intel_write_sha_text(dev_priv, sha_text); > if (ret < 0) > @@ -435,7 +437,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, > /* Write 32 bits of text */ > intel_de_write(dev_priv, HDCP_REP_CTL, > 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); > if (ret < 0) > return ret; > @@ -450,17 +452,29 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, > return ret; > 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) { > - /* Write 32 bits of text */ > + /* Write 32 bits of text (filled from LSB) */ > intel_de_write(dev_priv, HDCP_REP_CTL, > rep_ctl | HDCP_SHA1_TEXT_32); > - sha_text |= bstatus[0] << 24; > + sha_text |= bstatus[0]; > ret = intel_write_sha_text(dev_priv, sha_text); > if (ret < 0) > return ret; > 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, > rep_ctl | HDCP_SHA1_TEXT_8); > ret = intel_write_sha_text(dev_priv, bstatus[1]); > diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h > index c6bab4986a65..fe58dbb46962 100644 > --- a/include/drm/drm_hdcp.h > +++ b/include/drm/drm_hdcp.h > @@ -29,6 +29,9 @@ > /* Slave address for the HDCP registers in the receiver */ > #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 */ > #define DRM_HDCP_DDC_BKSV 0x00 > #define DRM_HDCP_DDC_RI_PRIME 0x08 > -- > Sean Paul, Software Engineer, Google / Chromium OS >
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 2cbc4619b4ce..525658fd201f 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -336,8 +336,10 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, /* Fill up the empty slots in sha_text and write it out */ sha_empty = sizeof(sha_text) - sha_leftovers; - for (j = 0; j < sha_empty; j++) - sha_text |= ksv[j] << ((sizeof(sha_text) - j - 1) * 8); + for (j = 0; j < sha_empty; j++) { + u8 off = ((sizeof(sha_text) - j - 1 - sha_leftovers) * 8); + sha_text |= ksv[j] << off; + } ret = intel_write_sha_text(dev_priv, sha_text); if (ret < 0) @@ -435,7 +437,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, /* Write 32 bits of text */ intel_de_write(dev_priv, HDCP_REP_CTL, 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); if (ret < 0) return ret; @@ -450,17 +452,29 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector, return ret; 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) { - /* Write 32 bits of text */ + /* Write 32 bits of text (filled from LSB) */ intel_de_write(dev_priv, HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32); - sha_text |= bstatus[0] << 24; + sha_text |= bstatus[0]; ret = intel_write_sha_text(dev_priv, sha_text); if (ret < 0) return ret; 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, rep_ctl | HDCP_SHA1_TEXT_8); ret = intel_write_sha_text(dev_priv, bstatus[1]); diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h index c6bab4986a65..fe58dbb46962 100644 --- a/include/drm/drm_hdcp.h +++ b/include/drm/drm_hdcp.h @@ -29,6 +29,9 @@ /* Slave address for the HDCP registers in the receiver */ #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 */ #define DRM_HDCP_DDC_BKSV 0x00 #define DRM_HDCP_DDC_RI_PRIME 0x08