All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 00/17] drm/i915: Add support for HDCP 1.4 over MST
@ 2020-06-23 15:58 ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

No functional changes, this set has the following changes since v6:
- rebased on drm-tip
- split "drm/i915: Clean up intel_hdcp_disable" out of "drm/i915: Don't
  fully disable HDCP on a port if multiple pipes are using it"
- remove hdcp2 dpmst stubs

Regarding "level of testing" questions, I've tested with multiple MST
hubs and displays. I don't have any compliance gear so all of this is
desk tested and works for me.

Sean

Sean Paul (17):
  drm/i915: Fix sha_text population code
  drm/i915: Clear the repeater bit on HDCP disable
  drm/i915: WARN if HDCP signalling is enabled upon disable
  drm/i915: Intercept Aksv writes in the aux hooks
  drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP
    signalling
  drm/i915: Factor out hdcp->value assignments
  drm/i915: Protect workers against disappearing connectors
  drm/i915: Clean up intel_hdcp_disable
  drm/i915: Don't fully disable HDCP on a port if multiple pipes are
    using it
  drm/i915: Support DP MST in enc_to_dig_port() function
  drm/i915: Use ddi_update_pipe in intel_dp_mst
  drm/i915: Factor out HDCP shim functions from dp for use by dp_mst
  drm/i915: Plumb port through hdcp init
  drm/i915: Add connector to hdcp_shim->check_link()
  drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband
    message
  drm/i915: Print HDCP version info for all connectors
  drm/i915: Add HDCP 1.4 support for MST connectors

 drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++
 drivers/gpu/drm/i915/Makefile                 |   1 +
 drivers/gpu/drm/i915/display/intel_ddi.c      |  29 +-
 drivers/gpu/drm/i915/display/intel_ddi.h      |   2 +
 .../drm/i915/display/intel_display_debugfs.c  |  21 +-
 .../drm/i915/display/intel_display_types.h    |  30 +-
 drivers/gpu/drm/i915/display/intel_dp.c       | 646 +---------------
 drivers/gpu/drm/i915/display/intel_dp.h       |   9 +
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  | 702 ++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  19 +
 drivers/gpu/drm/i915/display/intel_hdcp.c     | 218 ++++--
 drivers/gpu/drm/i915/display/intel_hdcp.h     |   2 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c     |  25 +-
 .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +
 include/drm/drm_dp_helper.h                   |   3 +
 include/drm/drm_dp_mst_helper.h               |  44 ++
 include/drm/drm_hdcp.h                        |   3 +
 17 files changed, 1191 insertions(+), 722 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/intel_dp_hdcp.c

-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 00/17] drm/i915: Add support for HDCP 1.4 over MST
@ 2020-06-23 15:58 ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

No functional changes, this set has the following changes since v6:
- rebased on drm-tip
- split "drm/i915: Clean up intel_hdcp_disable" out of "drm/i915: Don't
  fully disable HDCP on a port if multiple pipes are using it"
- remove hdcp2 dpmst stubs

Regarding "level of testing" questions, I've tested with multiple MST
hubs and displays. I don't have any compliance gear so all of this is
desk tested and works for me.

Sean

Sean Paul (17):
  drm/i915: Fix sha_text population code
  drm/i915: Clear the repeater bit on HDCP disable
  drm/i915: WARN if HDCP signalling is enabled upon disable
  drm/i915: Intercept Aksv writes in the aux hooks
  drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP
    signalling
  drm/i915: Factor out hdcp->value assignments
  drm/i915: Protect workers against disappearing connectors
  drm/i915: Clean up intel_hdcp_disable
  drm/i915: Don't fully disable HDCP on a port if multiple pipes are
    using it
  drm/i915: Support DP MST in enc_to_dig_port() function
  drm/i915: Use ddi_update_pipe in intel_dp_mst
  drm/i915: Factor out HDCP shim functions from dp for use by dp_mst
  drm/i915: Plumb port through hdcp init
  drm/i915: Add connector to hdcp_shim->check_link()
  drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband
    message
  drm/i915: Print HDCP version info for all connectors
  drm/i915: Add HDCP 1.4 support for MST connectors

 drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++
 drivers/gpu/drm/i915/Makefile                 |   1 +
 drivers/gpu/drm/i915/display/intel_ddi.c      |  29 +-
 drivers/gpu/drm/i915/display/intel_ddi.h      |   2 +
 .../drm/i915/display/intel_display_debugfs.c  |  21 +-
 .../drm/i915/display/intel_display_types.h    |  30 +-
 drivers/gpu/drm/i915/display/intel_dp.c       | 646 +---------------
 drivers/gpu/drm/i915/display/intel_dp.h       |   9 +
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  | 702 ++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  19 +
 drivers/gpu/drm/i915/display/intel_hdcp.c     | 218 ++++--
 drivers/gpu/drm/i915/display/intel_hdcp.h     |   2 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c     |  25 +-
 .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +
 include/drm/drm_dp_helper.h                   |   3 +
 include/drm/drm_dp_mst_helper.h               |  44 ++
 include/drm/drm_hdcp.h                        |   3 +
 17 files changed, 1191 insertions(+), 722 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/intel_dp_hdcp.c

-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v7 01/17] drm/i915: Fix sha_text population code
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
  (?)
@ 2020-06-23 15:58   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx
  Cc: juston.li, ramalingam.c, ville.syrjala, jani.nikula,
	joonas.lahtinen, rodrigo.vivi, daniel.vetter, Sean Paul,
	Chris Wilson, stable

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>
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
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-2-sean@poorly.run #v6

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
---
 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 815b054bb167..f26fee3b4624 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


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 01/17] drm/i915: Fix sha_text population code
@ 2020-06-23 15:58   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx
  Cc: Chris Wilson, daniel.vetter, Sean Paul, juston.li, rodrigo.vivi, stable

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>
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
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-2-sean@poorly.run #v6

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
---
 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 815b054bb167..f26fee3b4624 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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 01/17] drm/i915: Fix sha_text population code
@ 2020-06-23 15:58   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: Chris Wilson, daniel.vetter, Sean Paul, stable

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>
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
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-2-sean@poorly.run #v6

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
---
 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 815b054bb167..f26fee3b4624 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 02/17] drm/i915: Clear the repeater bit on HDCP disable
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
  (?)
@ 2020-06-23 15:58   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx
  Cc: juston.li, ramalingam.c, ville.syrjala, jani.nikula,
	joonas.lahtinen, rodrigo.vivi, daniel.vetter, Sean Paul,
	Chris Wilson, stable

From: Sean Paul <seanpaul@chromium.org>

On HDCP disable, clear the repeater bit. This ensures if we connect a
non-repeater sink after a repeater, the bit is in the state we expect.

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>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-3-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-3-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-3-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-3-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-3-sean@poorly.run #v6

Changes in v2:
-Added to the set
Changes in v3:
-None
  I had previously agreed that clearing the rep_ctl bits on enable would
  also be a good idea. However when I committed that idea to code, it
  didn't look right. So let's rely on enables and disables being paired
  and everything outside of that will be considered a bug
Changes in v4:
-s/I915_(READ|WRITE)/intel_de_(read|write)/
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index f26fee3b4624..9f530b2f3606 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -795,6 +795,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	enum port port = intel_dig_port->base.port;
 	enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
+	u32 repeater_ctl;
 	int ret;
 
 	drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP is being disabled...\n",
@@ -810,6 +811,11 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 		return -ETIMEDOUT;
 	}
 
+	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
+						   port);
+	intel_de_write(dev_priv, HDCP_REP_CTL,
+		       intel_de_read(dev_priv, HDCP_REP_CTL) & ~repeater_ctl);
+
 	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
 	if (ret) {
 		drm_err(&dev_priv->drm, "Failed to disable HDCP signalling\n");
-- 
Sean Paul, Software Engineer, Google / Chromium OS


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 02/17] drm/i915: Clear the repeater bit on HDCP disable
@ 2020-06-23 15:58   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx
  Cc: Chris Wilson, daniel.vetter, Sean Paul, juston.li, rodrigo.vivi, stable

From: Sean Paul <seanpaul@chromium.org>

On HDCP disable, clear the repeater bit. This ensures if we connect a
non-repeater sink after a repeater, the bit is in the state we expect.

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>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-3-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-3-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-3-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-3-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-3-sean@poorly.run #v6

Changes in v2:
-Added to the set
Changes in v3:
-None
  I had previously agreed that clearing the rep_ctl bits on enable would
  also be a good idea. However when I committed that idea to code, it
  didn't look right. So let's rely on enables and disables being paired
  and everything outside of that will be considered a bug
Changes in v4:
-s/I915_(READ|WRITE)/intel_de_(read|write)/
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index f26fee3b4624..9f530b2f3606 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -795,6 +795,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	enum port port = intel_dig_port->base.port;
 	enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
+	u32 repeater_ctl;
 	int ret;
 
 	drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP is being disabled...\n",
@@ -810,6 +811,11 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 		return -ETIMEDOUT;
 	}
 
+	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
+						   port);
+	intel_de_write(dev_priv, HDCP_REP_CTL,
+		       intel_de_read(dev_priv, HDCP_REP_CTL) & ~repeater_ctl);
+
 	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
 	if (ret) {
 		drm_err(&dev_priv->drm, "Failed to disable HDCP signalling\n");
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 02/17] drm/i915: Clear the repeater bit on HDCP disable
@ 2020-06-23 15:58   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: Chris Wilson, daniel.vetter, Sean Paul, stable

From: Sean Paul <seanpaul@chromium.org>

On HDCP disable, clear the repeater bit. This ensures if we connect a
non-repeater sink after a repeater, the bit is in the state we expect.

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>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-3-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-3-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-3-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-3-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-3-sean@poorly.run #v6

Changes in v2:
-Added to the set
Changes in v3:
-None
  I had previously agreed that clearing the rep_ctl bits on enable would
  also be a good idea. However when I committed that idea to code, it
  didn't look right. So let's rely on enables and disables being paired
  and everything outside of that will be considered a bug
Changes in v4:
-s/I915_(READ|WRITE)/intel_de_(read|write)/
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index f26fee3b4624..9f530b2f3606 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -795,6 +795,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	enum port port = intel_dig_port->base.port;
 	enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
+	u32 repeater_ctl;
 	int ret;
 
 	drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP is being disabled...\n",
@@ -810,6 +811,11 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 		return -ETIMEDOUT;
 	}
 
+	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
+						   port);
+	intel_de_write(dev_priv, HDCP_REP_CTL,
+		       intel_de_read(dev_priv, HDCP_REP_CTL) & ~repeater_ctl);
+
 	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
 	if (ret) {
 		drm_err(&dev_priv->drm, "Failed to disable HDCP signalling\n");
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 03/17] drm/i915: WARN if HDCP signalling is enabled upon disable
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:58   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

HDCP signalling should not be left on, WARN if it is

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-4-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-4-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-4-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-4-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-4-sean@poorly.run #v6

Changes in v2:
-Added to the set in lieu of just clearing the bit
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-Change WARN_ON to drm_WARN_ON
Changes in v6:
-None
Changes in v7:
-Rebased, variable name changed from 'ctl' to 'val'
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 73d6cc29291a..8a03c58cbd31 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1708,6 +1708,8 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
 
 	ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
 
+	drm_WARN_ON(crtc->base.dev, ctl & TRANS_DDI_HDCP_SIGNALLING);
+
 	ctl &= ~TRANS_DDI_FUNC_ENABLE;
 
 	if (IS_GEN_RANGE(dev_priv, 8, 10))
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 03/17] drm/i915: WARN if HDCP signalling is enabled upon disable
@ 2020-06-23 15:58   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

HDCP signalling should not be left on, WARN if it is

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-4-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-4-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-4-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-4-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-4-sean@poorly.run #v6

Changes in v2:
-Added to the set in lieu of just clearing the bit
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-Change WARN_ON to drm_WARN_ON
Changes in v6:
-None
Changes in v7:
-Rebased, variable name changed from 'ctl' to 'val'
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 73d6cc29291a..8a03c58cbd31 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1708,6 +1708,8 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
 
 	ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
 
+	drm_WARN_ON(crtc->base.dev, ctl & TRANS_DDI_HDCP_SIGNALLING);
+
 	ctl &= ~TRANS_DDI_FUNC_ENABLE;
 
 	if (IS_GEN_RANGE(dev_priv, 8, 10))
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 04/17] drm/i915: Intercept Aksv writes in the aux hooks
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:58   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

Instead of hand rolling the transfer ourselves in the hdcp hook, inspect
aux messages and add the aksv flag in the aux transfer hook.

IIRC, this was the original implementation and folks wanted this hack to
be isolated to the hdcp code, which makes sense.

However in testing an LG monitor on my desk, I noticed it was passing
back a DEFER reply. This wasn't handled in our hand-rolled code and HDCP
auth was failing as a result. Instead of copy/pasting all of the retry
logic and delays from drm dp helpers, let's just use the helpers and hide
the aksv select as best as we can.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
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-3-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-5-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-5-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-5-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-5-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-5-sean@poorly.run #v6

Changes in v2:
-Remove 'generate' in intel_dp_aux_generate_xfer_flags, make arg const (Ville)
-Bundle Aksv if statement together (Ville)
-Rename 'txbuf' to 'aksv' (Ville)
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_dp.c | 63 ++++++++++++-------------
 1 file changed, 29 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 3df5d901dd9d..b30846e9e634 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1563,6 +1563,20 @@ intel_dp_aux_header(u8 txbuf[HEADER_SIZE],
 	txbuf[3] = msg->size - 1;
 }
 
+static u32 intel_dp_aux_xfer_flags(const struct drm_dp_aux_msg *msg)
+{
+	/*
+	 * If we're trying to send the HDCP Aksv, we need to set a the Aksv
+	 * select bit to inform the hardware to send the Aksv after our header
+	 * since we can't access that data from software.
+	 */
+	if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_WRITE &&
+	    msg->address == DP_AUX_HDCP_AKSV)
+		return DP_AUX_CH_CTL_AUX_AKSV_SELECT;
+
+	return 0;
+}
+
 static ssize_t
 intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 {
@@ -1570,6 +1584,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 txbuf[20], rxbuf[20];
 	size_t txsize, rxsize;
+	u32 flags = intel_dp_aux_xfer_flags(msg);
 	int ret;
 
 	intel_dp_aux_header(txbuf, msg);
@@ -1590,7 +1605,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			memcpy(txbuf + HEADER_SIZE, msg->buffer, msg->size);
 
 		ret = intel_dp_aux_xfer(intel_dp, txbuf, txsize,
-					rxbuf, rxsize, 0);
+					rxbuf, rxsize, flags);
 		if (ret > 0) {
 			msg->reply = rxbuf[0] >> 4;
 
@@ -1613,7 +1628,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			return -E2BIG;
 
 		ret = intel_dp_aux_xfer(intel_dp, txbuf, txsize,
-					rxbuf, rxsize, 0);
+					rxbuf, rxsize, flags);
 		if (ret > 0) {
 			msg->reply = rxbuf[0] >> 4;
 			/*
@@ -6398,17 +6413,9 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 				u8 *an)
 {
 	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(&intel_dig_port->base.base));
-	static const struct drm_dp_aux_msg msg = {
-		.request = DP_AUX_NATIVE_WRITE,
-		.address = DP_AUX_HDCP_AKSV,
-		.size = DRM_HDCP_KSV_LEN,
-	};
-	u8 txbuf[HEADER_SIZE + DRM_HDCP_KSV_LEN] = {}, rxbuf[2], reply = 0;
+	u8 aksv[DRM_HDCP_KSV_LEN] = {};
 	ssize_t dpcd_ret;
-	int ret;
 
-	/* Output An first, that's easy */
 	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN,
 				     an, DRM_HDCP_AN_LEN);
 	if (dpcd_ret != DRM_HDCP_AN_LEN) {
@@ -6419,31 +6426,19 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 	}
 
 	/*
-	 * Since Aksv is Oh-So-Secret, we can't access it in software. So in
-	 * order to get it on the wire, we need to create the AUX header as if
-	 * we were writing the data, and then tickle the hardware to output the
-	 * data once the header is sent out.
+	 * Since Aksv is Oh-So-Secret, we can't access it in software. So we
+	 * send an empty buffer of the correct length through the DP helpers. On
+	 * the other side, in the transfer hook, we'll generate a flag based on
+	 * the destination address which will tickle the hardware to output the
+	 * Aksv on our behalf after the header is sent.
 	 */
-	intel_dp_aux_header(txbuf, &msg);
-
-	ret = intel_dp_aux_xfer(intel_dp, txbuf, HEADER_SIZE + msg.size,
-				rxbuf, sizeof(rxbuf),
-				DP_AUX_CH_CTL_AUX_AKSV_SELECT);
-	if (ret < 0) {
-		drm_dbg_kms(&i915->drm,
-			    "Write Aksv over DP/AUX failed (%d)\n", ret);
-		return ret;
-	} else if (ret == 0) {
-		drm_dbg_kms(&i915->drm, "Aksv write over DP/AUX was empty\n");
-		return -EIO;
-	}
-
-	reply = (rxbuf[0] >> 4) & DP_AUX_NATIVE_REPLY_MASK;
-	if (reply != DP_AUX_NATIVE_REPLY_ACK) {
+	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AKSV,
+				     aksv, DRM_HDCP_KSV_LEN);
+	if (dpcd_ret != DRM_HDCP_KSV_LEN) {
 		drm_dbg_kms(&i915->drm,
-			    "Aksv write: no DP_AUX_NATIVE_REPLY_ACK %x\n",
-			    reply);
-		return -EIO;
+			    "Failed to write Aksv over DP/AUX (%zd)\n",
+			    dpcd_ret);
+		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
 	}
 	return 0;
 }
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 04/17] drm/i915: Intercept Aksv writes in the aux hooks
@ 2020-06-23 15:58   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

Instead of hand rolling the transfer ourselves in the hdcp hook, inspect
aux messages and add the aksv flag in the aux transfer hook.

IIRC, this was the original implementation and folks wanted this hack to
be isolated to the hdcp code, which makes sense.

However in testing an LG monitor on my desk, I noticed it was passing
back a DEFER reply. This wasn't handled in our hand-rolled code and HDCP
auth was failing as a result. Instead of copy/pasting all of the retry
logic and delays from drm dp helpers, let's just use the helpers and hide
the aksv select as best as we can.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
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-3-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-5-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-5-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-5-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-5-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-5-sean@poorly.run #v6

Changes in v2:
-Remove 'generate' in intel_dp_aux_generate_xfer_flags, make arg const (Ville)
-Bundle Aksv if statement together (Ville)
-Rename 'txbuf' to 'aksv' (Ville)
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_dp.c | 63 ++++++++++++-------------
 1 file changed, 29 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 3df5d901dd9d..b30846e9e634 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1563,6 +1563,20 @@ intel_dp_aux_header(u8 txbuf[HEADER_SIZE],
 	txbuf[3] = msg->size - 1;
 }
 
+static u32 intel_dp_aux_xfer_flags(const struct drm_dp_aux_msg *msg)
+{
+	/*
+	 * If we're trying to send the HDCP Aksv, we need to set a the Aksv
+	 * select bit to inform the hardware to send the Aksv after our header
+	 * since we can't access that data from software.
+	 */
+	if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_WRITE &&
+	    msg->address == DP_AUX_HDCP_AKSV)
+		return DP_AUX_CH_CTL_AUX_AKSV_SELECT;
+
+	return 0;
+}
+
 static ssize_t
 intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 {
@@ -1570,6 +1584,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 txbuf[20], rxbuf[20];
 	size_t txsize, rxsize;
+	u32 flags = intel_dp_aux_xfer_flags(msg);
 	int ret;
 
 	intel_dp_aux_header(txbuf, msg);
@@ -1590,7 +1605,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			memcpy(txbuf + HEADER_SIZE, msg->buffer, msg->size);
 
 		ret = intel_dp_aux_xfer(intel_dp, txbuf, txsize,
-					rxbuf, rxsize, 0);
+					rxbuf, rxsize, flags);
 		if (ret > 0) {
 			msg->reply = rxbuf[0] >> 4;
 
@@ -1613,7 +1628,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
 			return -E2BIG;
 
 		ret = intel_dp_aux_xfer(intel_dp, txbuf, txsize,
-					rxbuf, rxsize, 0);
+					rxbuf, rxsize, flags);
 		if (ret > 0) {
 			msg->reply = rxbuf[0] >> 4;
 			/*
@@ -6398,17 +6413,9 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 				u8 *an)
 {
 	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(&intel_dig_port->base.base));
-	static const struct drm_dp_aux_msg msg = {
-		.request = DP_AUX_NATIVE_WRITE,
-		.address = DP_AUX_HDCP_AKSV,
-		.size = DRM_HDCP_KSV_LEN,
-	};
-	u8 txbuf[HEADER_SIZE + DRM_HDCP_KSV_LEN] = {}, rxbuf[2], reply = 0;
+	u8 aksv[DRM_HDCP_KSV_LEN] = {};
 	ssize_t dpcd_ret;
-	int ret;
 
-	/* Output An first, that's easy */
 	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN,
 				     an, DRM_HDCP_AN_LEN);
 	if (dpcd_ret != DRM_HDCP_AN_LEN) {
@@ -6419,31 +6426,19 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 	}
 
 	/*
-	 * Since Aksv is Oh-So-Secret, we can't access it in software. So in
-	 * order to get it on the wire, we need to create the AUX header as if
-	 * we were writing the data, and then tickle the hardware to output the
-	 * data once the header is sent out.
+	 * Since Aksv is Oh-So-Secret, we can't access it in software. So we
+	 * send an empty buffer of the correct length through the DP helpers. On
+	 * the other side, in the transfer hook, we'll generate a flag based on
+	 * the destination address which will tickle the hardware to output the
+	 * Aksv on our behalf after the header is sent.
 	 */
-	intel_dp_aux_header(txbuf, &msg);
-
-	ret = intel_dp_aux_xfer(intel_dp, txbuf, HEADER_SIZE + msg.size,
-				rxbuf, sizeof(rxbuf),
-				DP_AUX_CH_CTL_AUX_AKSV_SELECT);
-	if (ret < 0) {
-		drm_dbg_kms(&i915->drm,
-			    "Write Aksv over DP/AUX failed (%d)\n", ret);
-		return ret;
-	} else if (ret == 0) {
-		drm_dbg_kms(&i915->drm, "Aksv write over DP/AUX was empty\n");
-		return -EIO;
-	}
-
-	reply = (rxbuf[0] >> 4) & DP_AUX_NATIVE_REPLY_MASK;
-	if (reply != DP_AUX_NATIVE_REPLY_ACK) {
+	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AKSV,
+				     aksv, DRM_HDCP_KSV_LEN);
+	if (dpcd_ret != DRM_HDCP_KSV_LEN) {
 		drm_dbg_kms(&i915->drm,
-			    "Aksv write: no DP_AUX_NATIVE_REPLY_ACK %x\n",
-			    reply);
-		return -EIO;
+			    "Failed to write Aksv over DP/AUX (%zd)\n",
+			    dpcd_ret);
+		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
 	}
 	return 0;
 }
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 05/17] drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:58   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

Instead of using intel_dig_port's encoder pipe to determine which
transcoder to toggle signalling on, use the cpu_transcoder field already
stored in intel_hdmi.

This is particularly important for MST.

Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-6-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-6-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-6-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-6-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-6-sean@poorly.run #v6

Changes in v2:
-Added to the set
Changes in v3:
-s/hdcp/hdmi/ in commit msg (Ram)
Changes in v4:
-Rebased on intel_de_(read|write) change
Changes in v5:
-Update hdcp->cpu_transcoder in intel_hdcp_enable so it works with pipe != 0
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_ddi.c         | 13 +++----------
 drivers/gpu/drm/i915/display/intel_ddi.h         |  2 ++
 .../gpu/drm/i915/display/intel_display_types.h   |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c          |  1 +
 drivers/gpu/drm/i915/display/intel_hdcp.c        | 16 +++++++++-------
 drivers/gpu/drm/i915/display/intel_hdmi.c        | 16 +++++++++++-----
 6 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 8a03c58cbd31..4153a0d1e07d 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1737,12 +1737,12 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
 }
 
 int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
+				     enum transcoder cpu_transcoder,
 				     bool enable)
 {
 	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	intel_wakeref_t wakeref;
-	enum pipe pipe = 0;
 	int ret = 0;
 	u32 tmp;
 
@@ -1751,19 +1751,12 @@ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
 	if (drm_WARN_ON(dev, !wakeref))
 		return -ENXIO;
 
-	if (drm_WARN_ON(dev,
-			!intel_encoder->get_hw_state(intel_encoder, &pipe))) {
-		ret = -EIO;
-		goto out;
-	}
-
-	tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(pipe));
+	tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (enable)
 		tmp |= TRANS_DDI_HDCP_SIGNALLING;
 	else
 		tmp &= ~TRANS_DDI_HDCP_SIGNALLING;
-	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(pipe), tmp);
-out:
+	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), tmp);
 	intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
index 077e9dbbe367..f5fb62fc9400 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -16,6 +16,7 @@ struct intel_crtc_state;
 struct intel_dp;
 struct intel_dpll_hw_state;
 struct intel_encoder;
+enum transcoder;
 
 void intel_ddi_fdi_post_disable(struct intel_atomic_state *state,
 				struct intel_encoder *intel_encoder,
@@ -43,6 +44,7 @@ void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
 u32 bxt_signal_levels(struct intel_dp *intel_dp);
 u32 ddi_signal_levels(struct intel_dp *intel_dp);
 int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
+				     enum transcoder cpu_transcoder,
 				     bool enable);
 void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 4b0aaa3081c9..fc0befd55420 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -314,6 +314,7 @@ struct intel_hdcp_shim {
 
 	/* Enables HDCP signalling on the port */
 	int (*toggle_signalling)(struct intel_digital_port *intel_dig_port,
+				 enum transcoder cpu_transcoder,
 				 bool enable);
 
 	/* Ensures the link is still protected */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index b30846e9e634..d0fea51f5dec 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6597,6 +6597,7 @@ int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
 
 static
 int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
+				    enum transcoder cpu_transcoder,
 				    bool enable)
 {
 	/* Not used for single stream DisplayPort setups */
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 9f530b2f3606..39715abf2ce4 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -713,7 +713,7 @@ static int intel_hdcp_auth(struct intel_connector *connector)
 		intel_de_write(dev_priv, HDCP_REP_CTL,
 			       intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder, port));
 
-	ret = shim->toggle_signalling(intel_dig_port, true);
+	ret = shim->toggle_signalling(intel_dig_port, cpu_transcoder, true);
 	if (ret)
 		return ret;
 
@@ -816,7 +816,8 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 	intel_de_write(dev_priv, HDCP_REP_CTL,
 		       intel_de_read(dev_priv, HDCP_REP_CTL) & ~repeater_ctl);
 
-	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
+	ret = hdcp->shim->toggle_signalling(intel_dig_port, cpu_transcoder,
+					    false);
 	if (ret) {
 		drm_err(&dev_priv->drm, "Failed to disable HDCP signalling\n");
 		return ret;
@@ -1600,7 +1601,8 @@ static int hdcp2_enable_encryption(struct intel_connector *connector)
 		    intel_de_read(dev_priv, HDCP2_STATUS(dev_priv, cpu_transcoder, port)) &
 		    LINK_ENCRYPTION_STATUS);
 	if (hdcp->shim->toggle_signalling) {
-		ret = hdcp->shim->toggle_signalling(intel_dig_port, true);
+		ret = hdcp->shim->toggle_signalling(intel_dig_port,
+						    cpu_transcoder, true);
 		if (ret) {
 			drm_err(&dev_priv->drm,
 				"Failed to enable HDCP signalling. %d\n",
@@ -1650,7 +1652,8 @@ static int hdcp2_disable_encryption(struct intel_connector *connector)
 		drm_dbg_kms(&dev_priv->drm, "Disable Encryption Timedout");
 
 	if (hdcp->shim->toggle_signalling) {
-		ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
+		ret = hdcp->shim->toggle_signalling(intel_dig_port,
+						    cpu_transcoder, false);
 		if (ret) {
 			drm_err(&dev_priv->drm,
 				"Failed to disable HDCP signalling. %d\n",
@@ -2036,11 +2039,10 @@ int intel_hdcp_enable(struct intel_connector *connector,
 	drm_WARN_ON(&dev_priv->drm,
 		    hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
 	hdcp->content_type = content_type;
+	hdcp->cpu_transcoder = cpu_transcoder;
 
-	if (INTEL_GEN(dev_priv) >= 12) {
-		hdcp->cpu_transcoder = cpu_transcoder;
+	if (INTEL_GEN(dev_priv) >= 12)
 		hdcp->port_data.fw_tc = intel_get_mei_fw_tc(cpu_transcoder);
-	}
 
 	/*
 	 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index a31a98d26882..ab7bddf0dfdc 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -1477,7 +1477,8 @@ int intel_hdmi_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
 	return ret;
 }
 
-static int kbl_repositioning_enc_en_signal(struct intel_connector *connector)
+static int kbl_repositioning_enc_en_signal(struct intel_connector *connector,
+					   enum transcoder cpu_transcoder)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
@@ -1494,13 +1495,15 @@ static int kbl_repositioning_enc_en_signal(struct intel_connector *connector)
 		usleep_range(25, 50);
 	}
 
-	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, false);
+	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
+					       cpu_transcoder, false);
 	if (ret) {
 		drm_err(&dev_priv->drm,
 			"Disable HDCP signalling failed (%d)\n", ret);
 		return ret;
 	}
-	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, true);
+	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
+					       cpu_transcoder, true);
 	if (ret) {
 		drm_err(&dev_priv->drm,
 			"Enable HDCP signalling failed (%d)\n", ret);
@@ -1512,6 +1515,7 @@ static int kbl_repositioning_enc_en_signal(struct intel_connector *connector)
 
 static
 int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
+				      enum transcoder cpu_transcoder,
 				      bool enable)
 {
 	struct intel_hdmi *hdmi = &intel_dig_port->hdmi;
@@ -1522,7 +1526,8 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
 	if (!enable)
 		usleep_range(6, 60); /* Bspec says >= 6us */
 
-	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, enable);
+	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
+					       cpu_transcoder, enable);
 	if (ret) {
 		drm_err(&dev_priv->drm, "%s HDCP signalling failed (%d)\n",
 			enable ? "Enable" : "Disable", ret);
@@ -1534,7 +1539,8 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
 	 * opportunity and enc_en signalling in KABYLAKE.
 	 */
 	if (IS_KABYLAKE(dev_priv) && enable)
-		return kbl_repositioning_enc_en_signal(connector);
+		return kbl_repositioning_enc_en_signal(connector,
+						       cpu_transcoder);
 
 	return 0;
 }
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 05/17] drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling
@ 2020-06-23 15:58   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

Instead of using intel_dig_port's encoder pipe to determine which
transcoder to toggle signalling on, use the cpu_transcoder field already
stored in intel_hdmi.

This is particularly important for MST.

Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-6-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-6-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-6-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-6-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-6-sean@poorly.run #v6

Changes in v2:
-Added to the set
Changes in v3:
-s/hdcp/hdmi/ in commit msg (Ram)
Changes in v4:
-Rebased on intel_de_(read|write) change
Changes in v5:
-Update hdcp->cpu_transcoder in intel_hdcp_enable so it works with pipe != 0
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_ddi.c         | 13 +++----------
 drivers/gpu/drm/i915/display/intel_ddi.h         |  2 ++
 .../gpu/drm/i915/display/intel_display_types.h   |  1 +
 drivers/gpu/drm/i915/display/intel_dp.c          |  1 +
 drivers/gpu/drm/i915/display/intel_hdcp.c        | 16 +++++++++-------
 drivers/gpu/drm/i915/display/intel_hdmi.c        | 16 +++++++++++-----
 6 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 8a03c58cbd31..4153a0d1e07d 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1737,12 +1737,12 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
 }
 
 int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
+				     enum transcoder cpu_transcoder,
 				     bool enable)
 {
 	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	intel_wakeref_t wakeref;
-	enum pipe pipe = 0;
 	int ret = 0;
 	u32 tmp;
 
@@ -1751,19 +1751,12 @@ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
 	if (drm_WARN_ON(dev, !wakeref))
 		return -ENXIO;
 
-	if (drm_WARN_ON(dev,
-			!intel_encoder->get_hw_state(intel_encoder, &pipe))) {
-		ret = -EIO;
-		goto out;
-	}
-
-	tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(pipe));
+	tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (enable)
 		tmp |= TRANS_DDI_HDCP_SIGNALLING;
 	else
 		tmp &= ~TRANS_DDI_HDCP_SIGNALLING;
-	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(pipe), tmp);
-out:
+	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), tmp);
 	intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
index 077e9dbbe367..f5fb62fc9400 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -16,6 +16,7 @@ struct intel_crtc_state;
 struct intel_dp;
 struct intel_dpll_hw_state;
 struct intel_encoder;
+enum transcoder;
 
 void intel_ddi_fdi_post_disable(struct intel_atomic_state *state,
 				struct intel_encoder *intel_encoder,
@@ -43,6 +44,7 @@ void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
 u32 bxt_signal_levels(struct intel_dp *intel_dp);
 u32 ddi_signal_levels(struct intel_dp *intel_dp);
 int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
+				     enum transcoder cpu_transcoder,
 				     bool enable);
 void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 4b0aaa3081c9..fc0befd55420 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -314,6 +314,7 @@ struct intel_hdcp_shim {
 
 	/* Enables HDCP signalling on the port */
 	int (*toggle_signalling)(struct intel_digital_port *intel_dig_port,
+				 enum transcoder cpu_transcoder,
 				 bool enable);
 
 	/* Ensures the link is still protected */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index b30846e9e634..d0fea51f5dec 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6597,6 +6597,7 @@ int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
 
 static
 int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
+				    enum transcoder cpu_transcoder,
 				    bool enable)
 {
 	/* Not used for single stream DisplayPort setups */
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 9f530b2f3606..39715abf2ce4 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -713,7 +713,7 @@ static int intel_hdcp_auth(struct intel_connector *connector)
 		intel_de_write(dev_priv, HDCP_REP_CTL,
 			       intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder, port));
 
-	ret = shim->toggle_signalling(intel_dig_port, true);
+	ret = shim->toggle_signalling(intel_dig_port, cpu_transcoder, true);
 	if (ret)
 		return ret;
 
@@ -816,7 +816,8 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 	intel_de_write(dev_priv, HDCP_REP_CTL,
 		       intel_de_read(dev_priv, HDCP_REP_CTL) & ~repeater_ctl);
 
-	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
+	ret = hdcp->shim->toggle_signalling(intel_dig_port, cpu_transcoder,
+					    false);
 	if (ret) {
 		drm_err(&dev_priv->drm, "Failed to disable HDCP signalling\n");
 		return ret;
@@ -1600,7 +1601,8 @@ static int hdcp2_enable_encryption(struct intel_connector *connector)
 		    intel_de_read(dev_priv, HDCP2_STATUS(dev_priv, cpu_transcoder, port)) &
 		    LINK_ENCRYPTION_STATUS);
 	if (hdcp->shim->toggle_signalling) {
-		ret = hdcp->shim->toggle_signalling(intel_dig_port, true);
+		ret = hdcp->shim->toggle_signalling(intel_dig_port,
+						    cpu_transcoder, true);
 		if (ret) {
 			drm_err(&dev_priv->drm,
 				"Failed to enable HDCP signalling. %d\n",
@@ -1650,7 +1652,8 @@ static int hdcp2_disable_encryption(struct intel_connector *connector)
 		drm_dbg_kms(&dev_priv->drm, "Disable Encryption Timedout");
 
 	if (hdcp->shim->toggle_signalling) {
-		ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
+		ret = hdcp->shim->toggle_signalling(intel_dig_port,
+						    cpu_transcoder, false);
 		if (ret) {
 			drm_err(&dev_priv->drm,
 				"Failed to disable HDCP signalling. %d\n",
@@ -2036,11 +2039,10 @@ int intel_hdcp_enable(struct intel_connector *connector,
 	drm_WARN_ON(&dev_priv->drm,
 		    hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
 	hdcp->content_type = content_type;
+	hdcp->cpu_transcoder = cpu_transcoder;
 
-	if (INTEL_GEN(dev_priv) >= 12) {
-		hdcp->cpu_transcoder = cpu_transcoder;
+	if (INTEL_GEN(dev_priv) >= 12)
 		hdcp->port_data.fw_tc = intel_get_mei_fw_tc(cpu_transcoder);
-	}
 
 	/*
 	 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index a31a98d26882..ab7bddf0dfdc 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -1477,7 +1477,8 @@ int intel_hdmi_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
 	return ret;
 }
 
-static int kbl_repositioning_enc_en_signal(struct intel_connector *connector)
+static int kbl_repositioning_enc_en_signal(struct intel_connector *connector,
+					   enum transcoder cpu_transcoder)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
@@ -1494,13 +1495,15 @@ static int kbl_repositioning_enc_en_signal(struct intel_connector *connector)
 		usleep_range(25, 50);
 	}
 
-	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, false);
+	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
+					       cpu_transcoder, false);
 	if (ret) {
 		drm_err(&dev_priv->drm,
 			"Disable HDCP signalling failed (%d)\n", ret);
 		return ret;
 	}
-	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, true);
+	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
+					       cpu_transcoder, true);
 	if (ret) {
 		drm_err(&dev_priv->drm,
 			"Enable HDCP signalling failed (%d)\n", ret);
@@ -1512,6 +1515,7 @@ static int kbl_repositioning_enc_en_signal(struct intel_connector *connector)
 
 static
 int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
+				      enum transcoder cpu_transcoder,
 				      bool enable)
 {
 	struct intel_hdmi *hdmi = &intel_dig_port->hdmi;
@@ -1522,7 +1526,8 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
 	if (!enable)
 		usleep_range(6, 60); /* Bspec says >= 6us */
 
-	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base, enable);
+	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
+					       cpu_transcoder, enable);
 	if (ret) {
 		drm_err(&dev_priv->drm, "%s HDCP signalling failed (%d)\n",
 			enable ? "Enable" : "Disable", ret);
@@ -1534,7 +1539,8 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
 	 * opportunity and enc_en signalling in KABYLAKE.
 	 */
 	if (IS_KABYLAKE(dev_priv) && enable)
-		return kbl_repositioning_enc_en_signal(connector);
+		return kbl_repositioning_enc_en_signal(connector,
+						       cpu_transcoder);
 
 	return 0;
 }
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 06/17] drm/i915: Factor out hdcp->value assignments
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:58   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

This is a bit of housecleaning for a future patch. Instead of sprinkling
hdcp->value assignments and prop_work scheduling everywhere, introduce a
function to do it for us.

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-7-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-7-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-7-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-7-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-7-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-7-sean@poorly.run #v6

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-Rebased on top of drm_* logging changes
Changes in v5:
-Change WARN_ON to drm_WARN_ON
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 67 ++++++++++++++++-------
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 39715abf2ce4..88500a0bd77e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -877,6 +877,21 @@ static struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
 	return container_of(hdcp, struct intel_connector, hdcp);
 }
 
+static void intel_hdcp_update_value(struct intel_connector *connector,
+				    u64 value, bool update_property)
+{
+	struct intel_hdcp *hdcp = &connector->hdcp;
+
+	drm_WARN_ON(connector->base.dev, !mutex_is_locked(&hdcp->mutex));
+
+	if (hdcp->value == value)
+		return;
+
+	hdcp->value = value;
+	if (update_property)
+		schedule_work(&hdcp->prop_work);
+}
+
 /* Implements Part 3 of the HDCP authorization procedure */
 static int intel_hdcp_check_link(struct intel_connector *connector)
 {
@@ -904,15 +919,16 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 			connector->base.name, connector->base.base.id,
 			intel_de_read(dev_priv, HDCP_STATUS(dev_priv, cpu_transcoder, port)));
 		ret = -ENXIO;
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_DESIRED,
+					true);
 		goto out;
 	}
 
 	if (hdcp->shim->check_link(intel_dig_port)) {
 		if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
-			hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
-			schedule_work(&hdcp->prop_work);
+			intel_hdcp_update_value(connector,
+				DRM_MODE_CONTENT_PROTECTION_ENABLED, true);
 		}
 		goto out;
 	}
@@ -924,16 +940,18 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 	ret = _intel_hdcp_disable(connector);
 	if (ret) {
 		drm_err(&dev_priv->drm, "Failed to disable hdcp (%d)\n", ret);
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_DESIRED,
+					true);
 		goto out;
 	}
 
 	ret = _intel_hdcp_enable(connector);
 	if (ret) {
 		drm_err(&dev_priv->drm, "Failed to enable hdcp (%d)\n", ret);
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_DESIRED,
+					true);
 		goto out;
 	}
 
@@ -1769,16 +1787,18 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 			"HDCP2.2 link stopped the encryption, %x\n",
 			intel_de_read(dev_priv, HDCP2_STATUS(dev_priv, cpu_transcoder, port)));
 		ret = -ENXIO;
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_DESIRED,
+					true);
 		goto out;
 	}
 
 	ret = hdcp->shim->check_2_2_link(intel_dig_port);
 	if (ret == HDCP_LINK_PROTECTED) {
 		if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
-			hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
-			schedule_work(&hdcp->prop_work);
+			intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_ENABLED,
+					true);
 		}
 		goto out;
 	}
@@ -1791,8 +1811,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 			    "HDCP2.2 Downstream topology change\n");
 		ret = hdcp2_authenticate_repeater_topology(connector);
 		if (!ret) {
-			hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
-			schedule_work(&hdcp->prop_work);
+			intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_ENABLED,
+					true);
 			goto out;
 		}
 		drm_dbg_kms(&dev_priv->drm,
@@ -1810,8 +1831,8 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 		drm_err(&dev_priv->drm,
 			"[%s:%d] Failed to disable hdcp2.2 (%d)\n",
 			connector->base.name, connector->base.base.id, ret);
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+				DRM_MODE_CONTENT_PROTECTION_DESIRED, true);
 		goto out;
 	}
 
@@ -1821,8 +1842,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 			    "[%s:%d] Failed to enable hdcp2.2 (%d)\n",
 			    connector->base.name, connector->base.base.id,
 			    ret);
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_DESIRED,
+					true);
 		goto out;
 	}
 
@@ -2065,8 +2087,9 @@ int intel_hdcp_enable(struct intel_connector *connector,
 
 	if (!ret) {
 		schedule_delayed_work(&hdcp->check_work, check_link_interval);
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_ENABLED,
+					true);
 	}
 
 	mutex_unlock(&hdcp->mutex);
@@ -2084,7 +2107,9 @@ int intel_hdcp_disable(struct intel_connector *connector)
 	mutex_lock(&hdcp->mutex);
 
 	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_UNDESIRED,
+					false);
 		if (hdcp->hdcp2_encrypted)
 			ret = _intel_hdcp2_disable(connector);
 		else if (hdcp->hdcp_encrypted)
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 06/17] drm/i915: Factor out hdcp->value assignments
@ 2020-06-23 15:58   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

This is a bit of housecleaning for a future patch. Instead of sprinkling
hdcp->value assignments and prop_work scheduling everywhere, introduce a
function to do it for us.

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-7-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-7-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-7-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-7-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-7-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-7-sean@poorly.run #v6

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-Rebased on top of drm_* logging changes
Changes in v5:
-Change WARN_ON to drm_WARN_ON
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 67 ++++++++++++++++-------
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 39715abf2ce4..88500a0bd77e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -877,6 +877,21 @@ static struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
 	return container_of(hdcp, struct intel_connector, hdcp);
 }
 
+static void intel_hdcp_update_value(struct intel_connector *connector,
+				    u64 value, bool update_property)
+{
+	struct intel_hdcp *hdcp = &connector->hdcp;
+
+	drm_WARN_ON(connector->base.dev, !mutex_is_locked(&hdcp->mutex));
+
+	if (hdcp->value == value)
+		return;
+
+	hdcp->value = value;
+	if (update_property)
+		schedule_work(&hdcp->prop_work);
+}
+
 /* Implements Part 3 of the HDCP authorization procedure */
 static int intel_hdcp_check_link(struct intel_connector *connector)
 {
@@ -904,15 +919,16 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 			connector->base.name, connector->base.base.id,
 			intel_de_read(dev_priv, HDCP_STATUS(dev_priv, cpu_transcoder, port)));
 		ret = -ENXIO;
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_DESIRED,
+					true);
 		goto out;
 	}
 
 	if (hdcp->shim->check_link(intel_dig_port)) {
 		if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
-			hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
-			schedule_work(&hdcp->prop_work);
+			intel_hdcp_update_value(connector,
+				DRM_MODE_CONTENT_PROTECTION_ENABLED, true);
 		}
 		goto out;
 	}
@@ -924,16 +940,18 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 	ret = _intel_hdcp_disable(connector);
 	if (ret) {
 		drm_err(&dev_priv->drm, "Failed to disable hdcp (%d)\n", ret);
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_DESIRED,
+					true);
 		goto out;
 	}
 
 	ret = _intel_hdcp_enable(connector);
 	if (ret) {
 		drm_err(&dev_priv->drm, "Failed to enable hdcp (%d)\n", ret);
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_DESIRED,
+					true);
 		goto out;
 	}
 
@@ -1769,16 +1787,18 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 			"HDCP2.2 link stopped the encryption, %x\n",
 			intel_de_read(dev_priv, HDCP2_STATUS(dev_priv, cpu_transcoder, port)));
 		ret = -ENXIO;
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_DESIRED,
+					true);
 		goto out;
 	}
 
 	ret = hdcp->shim->check_2_2_link(intel_dig_port);
 	if (ret == HDCP_LINK_PROTECTED) {
 		if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
-			hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
-			schedule_work(&hdcp->prop_work);
+			intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_ENABLED,
+					true);
 		}
 		goto out;
 	}
@@ -1791,8 +1811,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 			    "HDCP2.2 Downstream topology change\n");
 		ret = hdcp2_authenticate_repeater_topology(connector);
 		if (!ret) {
-			hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
-			schedule_work(&hdcp->prop_work);
+			intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_ENABLED,
+					true);
 			goto out;
 		}
 		drm_dbg_kms(&dev_priv->drm,
@@ -1810,8 +1831,8 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 		drm_err(&dev_priv->drm,
 			"[%s:%d] Failed to disable hdcp2.2 (%d)\n",
 			connector->base.name, connector->base.base.id, ret);
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+				DRM_MODE_CONTENT_PROTECTION_DESIRED, true);
 		goto out;
 	}
 
@@ -1821,8 +1842,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 			    "[%s:%d] Failed to enable hdcp2.2 (%d)\n",
 			    connector->base.name, connector->base.base.id,
 			    ret);
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_DESIRED,
+					true);
 		goto out;
 	}
 
@@ -2065,8 +2087,9 @@ int intel_hdcp_enable(struct intel_connector *connector,
 
 	if (!ret) {
 		schedule_delayed_work(&hdcp->check_work, check_link_interval);
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_ENABLED;
-		schedule_work(&hdcp->prop_work);
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_ENABLED,
+					true);
 	}
 
 	mutex_unlock(&hdcp->mutex);
@@ -2084,7 +2107,9 @@ int intel_hdcp_disable(struct intel_connector *connector)
 	mutex_lock(&hdcp->mutex);
 
 	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
-		hdcp->value = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
+		intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_UNDESIRED,
+					false);
 		if (hdcp->hdcp2_encrypted)
 			ret = _intel_hdcp2_disable(connector);
 		else if (hdcp->hdcp_encrypted)
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 07/17] drm/i915: Protect workers against disappearing connectors
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:58   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

This patch adds some protection against connectors being destroyed
before the HDCP workers are finished.

For check_work, we do a synchronous cancel after the connector is
unregistered which will ensure that it is finished before destruction.

In the case of prop_work, we can't do a synchronous wait since it needs
to take connection_mutex which could cause deadlock. Instead, we'll take
a reference on the connector when scheduling prop_work and give it up
once we're done.

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-8-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-8-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-8-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-8-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-8-sean@poorly.run #v6

Changes in v2:
-Added to the set
Changes in v3:
-Change the WARN_ON condition in intel_hdcp_cleanup to allow for
 initializing connectors as well
Changes in v4:
-None
Changes in v5:
-Change WARN_ON to drm_WARN_ON
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 44 ++++++++++++++++++++---
 1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 88500a0bd77e..62cab3aea745 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -888,8 +888,10 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
 		return;
 
 	hdcp->value = value;
-	if (update_property)
+	if (update_property) {
+		drm_connector_get(&connector->base);
 		schedule_work(&hdcp->prop_work);
+	}
 }
 
 /* Implements Part 3 of the HDCP authorization procedure */
@@ -981,6 +983,8 @@ static void intel_hdcp_prop_work(struct work_struct *work)
 
 	mutex_unlock(&hdcp->mutex);
 	drm_modeset_unlock(&dev_priv->drm.mode_config.connection_mutex);
+
+	drm_connector_put(&connector->base);
 }
 
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
@@ -1860,6 +1864,9 @@ static void intel_hdcp_check_work(struct work_struct *work)
 					       check_work);
 	struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
 
+	if (drm_connector_is_unregistered(&connector->base))
+		return;
+
 	if (!intel_hdcp2_check_link(connector))
 		schedule_delayed_work(&hdcp->check_work,
 				      DRM_HDCP2_CHECK_PERIOD_MS);
@@ -2178,12 +2185,39 @@ void intel_hdcp_component_fini(struct drm_i915_private *dev_priv)
 
 void intel_hdcp_cleanup(struct intel_connector *connector)
 {
-	if (!connector->hdcp.shim)
+	struct intel_hdcp *hdcp = &connector->hdcp;
+
+	if (!hdcp->shim)
 		return;
 
-	mutex_lock(&connector->hdcp.mutex);
-	kfree(connector->hdcp.port_data.streams);
-	mutex_unlock(&connector->hdcp.mutex);
+	/*
+	 * If the connector is registered, it's possible userspace could kick
+	 * off another HDCP enable, which would re-spawn the workers.
+	 */
+	drm_WARN_ON(connector->base.dev,
+		connector->base.registration_state == DRM_CONNECTOR_REGISTERED);
+
+	/*
+	 * Now that the connector is not registered, check_work won't be run,
+	 * but cancel any outstanding instances of it
+	 */
+	cancel_delayed_work_sync(&hdcp->check_work);
+
+	/*
+	 * We don't cancel prop_work in the same way as check_work since it
+	 * requires connection_mutex which could be held while calling this
+	 * function. Instead, we rely on the connector references grabbed before
+	 * scheduling prop_work to ensure the connector is alive when prop_work
+	 * is run. So if we're in the destroy path (which is where this
+	 * function should be called), we're "guaranteed" that prop_work is not
+	 * active (tl;dr This Should Never Happen).
+	 */
+	drm_WARN_ON(connector->base.dev, work_pending(&hdcp->prop_work));
+
+	mutex_lock(&hdcp->mutex);
+	kfree(hdcp->port_data.streams);
+	hdcp->shim = NULL;
+	mutex_unlock(&hdcp->mutex);
 }
 
 void intel_hdcp_atomic_check(struct drm_connector *connector,
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 07/17] drm/i915: Protect workers against disappearing connectors
@ 2020-06-23 15:58   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

This patch adds some protection against connectors being destroyed
before the HDCP workers are finished.

For check_work, we do a synchronous cancel after the connector is
unregistered which will ensure that it is finished before destruction.

In the case of prop_work, we can't do a synchronous wait since it needs
to take connection_mutex which could cause deadlock. Instead, we'll take
a reference on the connector when scheduling prop_work and give it up
once we're done.

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-8-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-8-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-8-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-8-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-8-sean@poorly.run #v6

Changes in v2:
-Added to the set
Changes in v3:
-Change the WARN_ON condition in intel_hdcp_cleanup to allow for
 initializing connectors as well
Changes in v4:
-None
Changes in v5:
-Change WARN_ON to drm_WARN_ON
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 44 ++++++++++++++++++++---
 1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 88500a0bd77e..62cab3aea745 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -888,8 +888,10 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
 		return;
 
 	hdcp->value = value;
-	if (update_property)
+	if (update_property) {
+		drm_connector_get(&connector->base);
 		schedule_work(&hdcp->prop_work);
+	}
 }
 
 /* Implements Part 3 of the HDCP authorization procedure */
@@ -981,6 +983,8 @@ static void intel_hdcp_prop_work(struct work_struct *work)
 
 	mutex_unlock(&hdcp->mutex);
 	drm_modeset_unlock(&dev_priv->drm.mode_config.connection_mutex);
+
+	drm_connector_put(&connector->base);
 }
 
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
@@ -1860,6 +1864,9 @@ static void intel_hdcp_check_work(struct work_struct *work)
 					       check_work);
 	struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
 
+	if (drm_connector_is_unregistered(&connector->base))
+		return;
+
 	if (!intel_hdcp2_check_link(connector))
 		schedule_delayed_work(&hdcp->check_work,
 				      DRM_HDCP2_CHECK_PERIOD_MS);
@@ -2178,12 +2185,39 @@ void intel_hdcp_component_fini(struct drm_i915_private *dev_priv)
 
 void intel_hdcp_cleanup(struct intel_connector *connector)
 {
-	if (!connector->hdcp.shim)
+	struct intel_hdcp *hdcp = &connector->hdcp;
+
+	if (!hdcp->shim)
 		return;
 
-	mutex_lock(&connector->hdcp.mutex);
-	kfree(connector->hdcp.port_data.streams);
-	mutex_unlock(&connector->hdcp.mutex);
+	/*
+	 * If the connector is registered, it's possible userspace could kick
+	 * off another HDCP enable, which would re-spawn the workers.
+	 */
+	drm_WARN_ON(connector->base.dev,
+		connector->base.registration_state == DRM_CONNECTOR_REGISTERED);
+
+	/*
+	 * Now that the connector is not registered, check_work won't be run,
+	 * but cancel any outstanding instances of it
+	 */
+	cancel_delayed_work_sync(&hdcp->check_work);
+
+	/*
+	 * We don't cancel prop_work in the same way as check_work since it
+	 * requires connection_mutex which could be held while calling this
+	 * function. Instead, we rely on the connector references grabbed before
+	 * scheduling prop_work to ensure the connector is alive when prop_work
+	 * is run. So if we're in the destroy path (which is where this
+	 * function should be called), we're "guaranteed" that prop_work is not
+	 * active (tl;dr This Should Never Happen).
+	 */
+	drm_WARN_ON(connector->base.dev, work_pending(&hdcp->prop_work));
+
+	mutex_lock(&hdcp->mutex);
+	kfree(hdcp->port_data.streams);
+	hdcp->shim = NULL;
+	mutex_unlock(&hdcp->mutex);
 }
 
 void intel_hdcp_atomic_check(struct drm_connector *connector,
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 08/17] drm/i915: Clean up intel_hdcp_disable
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:58   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

Add an out label and un-indent hdcp disable in preparation for
hdcp_mutex. No functional changes

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-9-sean@poorly.run #v6

Changes in v7:
-Split into separate patch (Ramalingam)
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 62cab3aea745..16bf0fbe5f17 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -2113,16 +2113,17 @@ int intel_hdcp_disable(struct intel_connector *connector)
 
 	mutex_lock(&hdcp->mutex);
 
-	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
-		intel_hdcp_update_value(connector,
-					DRM_MODE_CONTENT_PROTECTION_UNDESIRED,
-					false);
-		if (hdcp->hdcp2_encrypted)
-			ret = _intel_hdcp2_disable(connector);
-		else if (hdcp->hdcp_encrypted)
-			ret = _intel_hdcp_disable(connector);
-	}
+	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+		goto out;
 
+	intel_hdcp_update_value(connector,
+				DRM_MODE_CONTENT_PROTECTION_UNDESIRED, false);
+	if (hdcp->hdcp2_encrypted)
+		ret = _intel_hdcp2_disable(connector);
+	else if (hdcp->hdcp_encrypted)
+		ret = _intel_hdcp_disable(connector);
+
+out:
 	mutex_unlock(&hdcp->mutex);
 	cancel_delayed_work_sync(&hdcp->check_work);
 	return ret;
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 08/17] drm/i915: Clean up intel_hdcp_disable
@ 2020-06-23 15:58   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

Add an out label and un-indent hdcp disable in preparation for
hdcp_mutex. No functional changes

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-9-sean@poorly.run #v6

Changes in v7:
-Split into separate patch (Ramalingam)
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 62cab3aea745..16bf0fbe5f17 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -2113,16 +2113,17 @@ int intel_hdcp_disable(struct intel_connector *connector)
 
 	mutex_lock(&hdcp->mutex);
 
-	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
-		intel_hdcp_update_value(connector,
-					DRM_MODE_CONTENT_PROTECTION_UNDESIRED,
-					false);
-		if (hdcp->hdcp2_encrypted)
-			ret = _intel_hdcp2_disable(connector);
-		else if (hdcp->hdcp_encrypted)
-			ret = _intel_hdcp_disable(connector);
-	}
+	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+		goto out;
 
+	intel_hdcp_update_value(connector,
+				DRM_MODE_CONTENT_PROTECTION_UNDESIRED, false);
+	if (hdcp->hdcp2_encrypted)
+		ret = _intel_hdcp2_disable(connector);
+	else if (hdcp->hdcp_encrypted)
+		ret = _intel_hdcp_disable(connector);
+
+out:
 	mutex_unlock(&hdcp->mutex);
 	cancel_delayed_work_sync(&hdcp->check_work);
 	return ret;
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 09/17] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:58   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

This patch is required for HDCP over MST. If a port is being used for
multiple HDCP streams, we don't want to fully disable HDCP on a port if
one of them is disabled. Instead, we just disable the HDCP signalling on
that particular pipe and exit early. The last pipe to disable HDCP will
also bring down HDCP on the port.

In order to achieve this, we need to keep a refcount in intel_digital_port
and protect it using a new hdcp_mutex.

Cc: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-8-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-9-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-9-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-9-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-9-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-9-sean@poorly.run #v6

Changes in v2:
-Move the toggle_signalling call into _intel_hdcp_disable so it's called from check_work
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-Change WARN_ON to drm_WARN_ON
Changes in v6:
-None
Changes in v7:
-Split minor intel_hdcp_disable refactor into separate patch (Ramalingam)
---
 drivers/gpu/drm/i915/display/intel_ddi.c      |  3 ++
 .../drm/i915/display/intel_display_types.h    |  5 +++
 drivers/gpu/drm/i915/display/intel_dp.c       |  2 ++
 drivers/gpu/drm/i915/display/intel_hdcp.c     | 33 +++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_hdmi.c     |  2 ++
 5 files changed, 45 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 4153a0d1e07d..536299f902b9 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4884,6 +4884,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
 	drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
 			 DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port));
 
+	mutex_init(&intel_dig_port->hdcp_mutex);
+	intel_dig_port->num_hdcp_streams = 0;
+
 	encoder->hotplug = intel_ddi_hotplug;
 	encoder->compute_output_type = intel_ddi_compute_output_type;
 	encoder->compute_config = intel_ddi_compute_config;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index fc0befd55420..1503403a808b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1410,6 +1410,11 @@ struct intel_digital_port {
 	enum phy_fia tc_phy_fia;
 	u8 tc_phy_fia_idx;
 
+	/* protects num_hdcp_streams reference count */
+	struct mutex hdcp_mutex;
+	/* the number of pipes using HDCP signalling out of this port */
+	unsigned int num_hdcp_streams;
+
 	void (*write_infoframe)(struct intel_encoder *encoder,
 				const struct intel_crtc_state *crtc_state,
 				unsigned int type,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index d0fea51f5dec..d98e45a09c28 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -8276,6 +8276,8 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
 	intel_encoder = &intel_dig_port->base;
 	encoder = &intel_encoder->base;
 
+	mutex_init(&intel_dig_port->hdcp_mutex);
+
 	if (drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
 			     &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS,
 			     "DP %c", port_name(port)))
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 16bf0fbe5f17..5679877c6b4c 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -801,6 +801,19 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 	drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP is being disabled...\n",
 		    connector->base.name, connector->base.base.id);
 
+	/*
+	 * If there are other connectors on this port using HDCP, don't disable
+	 * it. Instead, toggle the HDCP signalling off on that particular
+	 * connector/pipe and exit.
+	 */
+	if (intel_dig_port->num_hdcp_streams > 0) {
+		ret = hdcp->shim->toggle_signalling(intel_dig_port,
+						    cpu_transcoder, false);
+		if (ret)
+			DRM_ERROR("Failed to disable HDCP signalling\n");
+		return ret;
+	}
+
 	hdcp->hdcp_encrypted = false;
 	intel_de_write(dev_priv, HDCP_CONF(dev_priv, cpu_transcoder, port), 0);
 	if (intel_de_wait_for_clear(dev_priv,
@@ -880,6 +893,8 @@ static struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
 static void intel_hdcp_update_value(struct intel_connector *connector,
 				    u64 value, bool update_property)
 {
+	struct drm_device *dev = connector->base.dev;
+	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 
 	drm_WARN_ON(connector->base.dev, !mutex_is_locked(&hdcp->mutex));
@@ -887,6 +902,15 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
 	if (hdcp->value == value)
 		return;
 
+	drm_WARN_ON(dev, !mutex_is_locked(&intel_dig_port->hdcp_mutex));
+
+	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
+		if (!drm_WARN_ON(dev, intel_dig_port->num_hdcp_streams == 0))
+			intel_dig_port->num_hdcp_streams--;
+	} else if (value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
+		intel_dig_port->num_hdcp_streams++;
+	}
+
 	hdcp->value = value;
 	if (update_property) {
 		drm_connector_get(&connector->base);
@@ -905,6 +929,8 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 	int ret = 0;
 
 	mutex_lock(&hdcp->mutex);
+	mutex_lock(&intel_dig_port->hdcp_mutex);
+
 	cpu_transcoder = hdcp->cpu_transcoder;
 
 	/* Check_link valid only when HDCP1.4 is enabled */
@@ -958,6 +984,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 	}
 
 out:
+	mutex_unlock(&intel_dig_port->hdcp_mutex);
 	mutex_unlock(&hdcp->mutex);
 	return ret;
 }
@@ -2057,6 +2084,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
 		      enum transcoder cpu_transcoder, u8 content_type)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
 	int ret = -EINVAL;
@@ -2065,6 +2093,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
 		return -ENOENT;
 
 	mutex_lock(&hdcp->mutex);
+	mutex_lock(&intel_dig_port->hdcp_mutex);
 	drm_WARN_ON(&dev_priv->drm,
 		    hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
 	hdcp->content_type = content_type;
@@ -2099,12 +2128,14 @@ int intel_hdcp_enable(struct intel_connector *connector,
 					true);
 	}
 
+	mutex_unlock(&intel_dig_port->hdcp_mutex);
 	mutex_unlock(&hdcp->mutex);
 	return ret;
 }
 
 int intel_hdcp_disable(struct intel_connector *connector)
 {
+	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	int ret = 0;
 
@@ -2112,6 +2143,7 @@ int intel_hdcp_disable(struct intel_connector *connector)
 		return -ENOENT;
 
 	mutex_lock(&hdcp->mutex);
+	mutex_lock(&intel_dig_port->hdcp_mutex);
 
 	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
 		goto out;
@@ -2124,6 +2156,7 @@ int intel_hdcp_disable(struct intel_connector *connector)
 		ret = _intel_hdcp_disable(connector);
 
 out:
+	mutex_unlock(&intel_dig_port->hdcp_mutex);
 	mutex_unlock(&hdcp->mutex);
 	cancel_delayed_work_sync(&hdcp->check_work);
 	return ret;
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index ab7bddf0dfdc..a59acfff456e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -3331,6 +3331,8 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
 
 	intel_encoder = &intel_dig_port->base;
 
+	mutex_init(&intel_dig_port->hdcp_mutex);
+
 	drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
 			 &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,
 			 "HDMI %c", port_name(port));
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 09/17] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
@ 2020-06-23 15:58   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:58 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

This patch is required for HDCP over MST. If a port is being used for
multiple HDCP streams, we don't want to fully disable HDCP on a port if
one of them is disabled. Instead, we just disable the HDCP signalling on
that particular pipe and exit early. The last pipe to disable HDCP will
also bring down HDCP on the port.

In order to achieve this, we need to keep a refcount in intel_digital_port
and protect it using a new hdcp_mutex.

Cc: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-8-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-9-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-9-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-9-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-9-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-9-sean@poorly.run #v6

Changes in v2:
-Move the toggle_signalling call into _intel_hdcp_disable so it's called from check_work
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-Change WARN_ON to drm_WARN_ON
Changes in v6:
-None
Changes in v7:
-Split minor intel_hdcp_disable refactor into separate patch (Ramalingam)
---
 drivers/gpu/drm/i915/display/intel_ddi.c      |  3 ++
 .../drm/i915/display/intel_display_types.h    |  5 +++
 drivers/gpu/drm/i915/display/intel_dp.c       |  2 ++
 drivers/gpu/drm/i915/display/intel_hdcp.c     | 33 +++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_hdmi.c     |  2 ++
 5 files changed, 45 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 4153a0d1e07d..536299f902b9 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4884,6 +4884,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
 	drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
 			 DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port));
 
+	mutex_init(&intel_dig_port->hdcp_mutex);
+	intel_dig_port->num_hdcp_streams = 0;
+
 	encoder->hotplug = intel_ddi_hotplug;
 	encoder->compute_output_type = intel_ddi_compute_output_type;
 	encoder->compute_config = intel_ddi_compute_config;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index fc0befd55420..1503403a808b 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1410,6 +1410,11 @@ struct intel_digital_port {
 	enum phy_fia tc_phy_fia;
 	u8 tc_phy_fia_idx;
 
+	/* protects num_hdcp_streams reference count */
+	struct mutex hdcp_mutex;
+	/* the number of pipes using HDCP signalling out of this port */
+	unsigned int num_hdcp_streams;
+
 	void (*write_infoframe)(struct intel_encoder *encoder,
 				const struct intel_crtc_state *crtc_state,
 				unsigned int type,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index d0fea51f5dec..d98e45a09c28 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -8276,6 +8276,8 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
 	intel_encoder = &intel_dig_port->base;
 	encoder = &intel_encoder->base;
 
+	mutex_init(&intel_dig_port->hdcp_mutex);
+
 	if (drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
 			     &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS,
 			     "DP %c", port_name(port)))
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 16bf0fbe5f17..5679877c6b4c 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -801,6 +801,19 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 	drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP is being disabled...\n",
 		    connector->base.name, connector->base.base.id);
 
+	/*
+	 * If there are other connectors on this port using HDCP, don't disable
+	 * it. Instead, toggle the HDCP signalling off on that particular
+	 * connector/pipe and exit.
+	 */
+	if (intel_dig_port->num_hdcp_streams > 0) {
+		ret = hdcp->shim->toggle_signalling(intel_dig_port,
+						    cpu_transcoder, false);
+		if (ret)
+			DRM_ERROR("Failed to disable HDCP signalling\n");
+		return ret;
+	}
+
 	hdcp->hdcp_encrypted = false;
 	intel_de_write(dev_priv, HDCP_CONF(dev_priv, cpu_transcoder, port), 0);
 	if (intel_de_wait_for_clear(dev_priv,
@@ -880,6 +893,8 @@ static struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
 static void intel_hdcp_update_value(struct intel_connector *connector,
 				    u64 value, bool update_property)
 {
+	struct drm_device *dev = connector->base.dev;
+	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 
 	drm_WARN_ON(connector->base.dev, !mutex_is_locked(&hdcp->mutex));
@@ -887,6 +902,15 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
 	if (hdcp->value == value)
 		return;
 
+	drm_WARN_ON(dev, !mutex_is_locked(&intel_dig_port->hdcp_mutex));
+
+	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
+		if (!drm_WARN_ON(dev, intel_dig_port->num_hdcp_streams == 0))
+			intel_dig_port->num_hdcp_streams--;
+	} else if (value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
+		intel_dig_port->num_hdcp_streams++;
+	}
+
 	hdcp->value = value;
 	if (update_property) {
 		drm_connector_get(&connector->base);
@@ -905,6 +929,8 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 	int ret = 0;
 
 	mutex_lock(&hdcp->mutex);
+	mutex_lock(&intel_dig_port->hdcp_mutex);
+
 	cpu_transcoder = hdcp->cpu_transcoder;
 
 	/* Check_link valid only when HDCP1.4 is enabled */
@@ -958,6 +984,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 	}
 
 out:
+	mutex_unlock(&intel_dig_port->hdcp_mutex);
 	mutex_unlock(&hdcp->mutex);
 	return ret;
 }
@@ -2057,6 +2084,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
 		      enum transcoder cpu_transcoder, u8 content_type)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
 	int ret = -EINVAL;
@@ -2065,6 +2093,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
 		return -ENOENT;
 
 	mutex_lock(&hdcp->mutex);
+	mutex_lock(&intel_dig_port->hdcp_mutex);
 	drm_WARN_ON(&dev_priv->drm,
 		    hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
 	hdcp->content_type = content_type;
@@ -2099,12 +2128,14 @@ int intel_hdcp_enable(struct intel_connector *connector,
 					true);
 	}
 
+	mutex_unlock(&intel_dig_port->hdcp_mutex);
 	mutex_unlock(&hdcp->mutex);
 	return ret;
 }
 
 int intel_hdcp_disable(struct intel_connector *connector)
 {
+	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	int ret = 0;
 
@@ -2112,6 +2143,7 @@ int intel_hdcp_disable(struct intel_connector *connector)
 		return -ENOENT;
 
 	mutex_lock(&hdcp->mutex);
+	mutex_lock(&intel_dig_port->hdcp_mutex);
 
 	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
 		goto out;
@@ -2124,6 +2156,7 @@ int intel_hdcp_disable(struct intel_connector *connector)
 		ret = _intel_hdcp_disable(connector);
 
 out:
+	mutex_unlock(&intel_dig_port->hdcp_mutex);
 	mutex_unlock(&hdcp->mutex);
 	cancel_delayed_work_sync(&hdcp->check_work);
 	return ret;
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index ab7bddf0dfdc..a59acfff456e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -3331,6 +3331,8 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
 
 	intel_encoder = &intel_dig_port->base;
 
+	mutex_init(&intel_dig_port->hdcp_mutex);
+
 	drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
 			 &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,
 			 "HDMI %c", port_name(port));
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 10/17] drm/i915: Support DP MST in enc_to_dig_port() function
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:59   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

Although DP_MST fake encoders are not subclassed from digital ports,
they are associated with them. Support these encoders.

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-9-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-10-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-10-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-10-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-10-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-10-sean@poorly.run #v6

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-None
---
 .../drm/i915/display/intel_display_types.h    | 21 ++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 1503403a808b..811085ef3fba 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1525,6 +1525,18 @@ static inline bool intel_encoder_is_dig_port(struct intel_encoder *encoder)
 	}
 }
 
+static inline bool intel_encoder_is_mst(struct intel_encoder *encoder)
+{
+	return encoder->type == INTEL_OUTPUT_DP_MST;
+}
+
+static inline struct intel_dp_mst_encoder *
+enc_to_mst(struct intel_encoder *encoder)
+{
+	return container_of(&encoder->base, struct intel_dp_mst_encoder,
+			    base.base);
+}
+
 static inline struct intel_digital_port *
 enc_to_dig_port(struct intel_encoder *encoder)
 {
@@ -1533,6 +1545,8 @@ enc_to_dig_port(struct intel_encoder *encoder)
 	if (intel_encoder_is_dig_port(intel_encoder))
 		return container_of(&encoder->base, struct intel_digital_port,
 				    base.base);
+	else if (intel_encoder_is_mst(intel_encoder))
+		return enc_to_mst(encoder)->primary;
 	else
 		return NULL;
 }
@@ -1543,13 +1557,6 @@ intel_attached_dig_port(struct intel_connector *connector)
 	return enc_to_dig_port(intel_attached_encoder(connector));
 }
 
-static inline struct intel_dp_mst_encoder *
-enc_to_mst(struct intel_encoder *encoder)
-{
-	return container_of(&encoder->base, struct intel_dp_mst_encoder,
-			    base.base);
-}
-
 static inline struct intel_dp *enc_to_intel_dp(struct intel_encoder *encoder)
 {
 	return &enc_to_dig_port(encoder)->dp;
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 10/17] drm/i915: Support DP MST in enc_to_dig_port() function
@ 2020-06-23 15:59   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

Although DP_MST fake encoders are not subclassed from digital ports,
they are associated with them. Support these encoders.

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-9-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-10-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-10-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-10-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-10-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-10-sean@poorly.run #v6

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-None
---
 .../drm/i915/display/intel_display_types.h    | 21 ++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 1503403a808b..811085ef3fba 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1525,6 +1525,18 @@ static inline bool intel_encoder_is_dig_port(struct intel_encoder *encoder)
 	}
 }
 
+static inline bool intel_encoder_is_mst(struct intel_encoder *encoder)
+{
+	return encoder->type == INTEL_OUTPUT_DP_MST;
+}
+
+static inline struct intel_dp_mst_encoder *
+enc_to_mst(struct intel_encoder *encoder)
+{
+	return container_of(&encoder->base, struct intel_dp_mst_encoder,
+			    base.base);
+}
+
 static inline struct intel_digital_port *
 enc_to_dig_port(struct intel_encoder *encoder)
 {
@@ -1533,6 +1545,8 @@ enc_to_dig_port(struct intel_encoder *encoder)
 	if (intel_encoder_is_dig_port(intel_encoder))
 		return container_of(&encoder->base, struct intel_digital_port,
 				    base.base);
+	else if (intel_encoder_is_mst(intel_encoder))
+		return enc_to_mst(encoder)->primary;
 	else
 		return NULL;
 }
@@ -1543,13 +1557,6 @@ intel_attached_dig_port(struct intel_connector *connector)
 	return enc_to_dig_port(intel_attached_encoder(connector));
 }
 
-static inline struct intel_dp_mst_encoder *
-enc_to_mst(struct intel_encoder *encoder)
-{
-	return container_of(&encoder->base, struct intel_dp_mst_encoder,
-			    base.base);
-}
-
 static inline struct intel_dp *enc_to_intel_dp(struct intel_encoder *encoder)
 {
 	return &enc_to_dig_port(encoder)->dp;
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 11/17] drm/i915: Use ddi_update_pipe in intel_dp_mst
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:59   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

In order to act upon content_protection property changes, we'll need to
implement the .update_pipe() hook. We can re-use intel_ddi_update_pipe
for this

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-10-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-11-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-11-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-11-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-11-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-11-sean@poorly.run #v6

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_ddi.c    | 11 ++++++-----
 drivers/gpu/drm/i915/display/intel_dp.h     |  6 ++++++
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  1 +
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 536299f902b9..29f1f552e8d8 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3907,13 +3907,14 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state,
 	intel_panel_update_backlight(state, encoder, crtc_state, conn_state);
 }
 
-static void intel_ddi_update_pipe(struct intel_atomic_state *state,
-				  struct intel_encoder *encoder,
-				  const struct intel_crtc_state *crtc_state,
-				  const struct drm_connector_state *conn_state)
+void intel_ddi_update_pipe(struct intel_atomic_state *state,
+			   struct intel_encoder *encoder,
+			   const struct intel_crtc_state *crtc_state,
+			   const struct drm_connector_state *conn_state)
 {
 
-	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
+	    !intel_encoder_is_mst(encoder))
 		intel_ddi_update_pipe_dp(state, encoder, crtc_state,
 					 conn_state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 0a8950f744f6..6352c7e97e3b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -17,6 +17,7 @@ struct drm_encoder;
 struct drm_i915_private;
 struct drm_modeset_acquire_ctx;
 struct drm_dp_vsc_sdp;
+struct intel_atomic_state;
 struct intel_connector;
 struct intel_crtc_state;
 struct intel_digital_port;
@@ -128,4 +129,9 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 
 u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
 
+void intel_ddi_update_pipe(struct intel_atomic_state *state,
+			   struct intel_encoder *encoder,
+			   const struct intel_crtc_state *crtc_state,
+			   const struct drm_connector_state *conn_state);
+
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 9308b5920780..0675825dcc20 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -836,6 +836,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum
 	intel_encoder->compute_config_late = intel_dp_mst_compute_config_late;
 	intel_encoder->disable = intel_mst_disable_dp;
 	intel_encoder->post_disable = intel_mst_post_disable_dp;
+	intel_encoder->update_pipe = intel_ddi_update_pipe;
 	intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp;
 	intel_encoder->pre_enable = intel_mst_pre_enable_dp;
 	intel_encoder->enable = intel_mst_enable_dp;
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 11/17] drm/i915: Use ddi_update_pipe in intel_dp_mst
@ 2020-06-23 15:59   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

In order to act upon content_protection property changes, we'll need to
implement the .update_pipe() hook. We can re-use intel_ddi_update_pipe
for this

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-10-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-11-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-11-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-11-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-11-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-11-sean@poorly.run #v6

Changes in v2:
-None
Changes in v3:
-None
Changes in v4:
-None
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_ddi.c    | 11 ++++++-----
 drivers/gpu/drm/i915/display/intel_dp.h     |  6 ++++++
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  1 +
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 536299f902b9..29f1f552e8d8 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3907,13 +3907,14 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state,
 	intel_panel_update_backlight(state, encoder, crtc_state, conn_state);
 }
 
-static void intel_ddi_update_pipe(struct intel_atomic_state *state,
-				  struct intel_encoder *encoder,
-				  const struct intel_crtc_state *crtc_state,
-				  const struct drm_connector_state *conn_state)
+void intel_ddi_update_pipe(struct intel_atomic_state *state,
+			   struct intel_encoder *encoder,
+			   const struct intel_crtc_state *crtc_state,
+			   const struct drm_connector_state *conn_state)
 {
 
-	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
+	    !intel_encoder_is_mst(encoder))
 		intel_ddi_update_pipe_dp(state, encoder, crtc_state,
 					 conn_state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 0a8950f744f6..6352c7e97e3b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -17,6 +17,7 @@ struct drm_encoder;
 struct drm_i915_private;
 struct drm_modeset_acquire_ctx;
 struct drm_dp_vsc_sdp;
+struct intel_atomic_state;
 struct intel_connector;
 struct intel_crtc_state;
 struct intel_digital_port;
@@ -128,4 +129,9 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 
 u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
 
+void intel_ddi_update_pipe(struct intel_atomic_state *state,
+			   struct intel_encoder *encoder,
+			   const struct intel_crtc_state *crtc_state,
+			   const struct drm_connector_state *conn_state);
+
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 9308b5920780..0675825dcc20 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -836,6 +836,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum
 	intel_encoder->compute_config_late = intel_dp_mst_compute_config_late;
 	intel_encoder->disable = intel_mst_disable_dp;
 	intel_encoder->post_disable = intel_mst_post_disable_dp;
+	intel_encoder->update_pipe = intel_ddi_update_pipe;
 	intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp;
 	intel_encoder->pre_enable = intel_mst_pre_enable_dp;
 	intel_encoder->enable = intel_mst_enable_dp;
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 12/17] drm/i915: Factor out HDCP shim functions from dp for use by dp_mst
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:59   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

These functions are all the same for dp and dp_mst, so move them into a
dedicated file for both sst and mst to use.

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-11-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-12-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-12-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-12-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-12-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-12-sean@poorly.run #v6

Changes in v2:
-None
Changes in v3:
-Created intel_dp_hdcp.c for the shared functions to live (Ville)
Changes in v4:
-Rebased on new drm logging change
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-Rebased patch
---
 drivers/gpu/drm/i915/Makefile                |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c      | 606 +-----------------
 drivers/gpu/drm/i915/display/intel_dp.h      |   3 +
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 636 +++++++++++++++++++
 4 files changed, 641 insertions(+), 605 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/intel_dp_hdcp.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 41a27fd5dbc7..cba4ddb95ab1 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -233,6 +233,7 @@ i915-y += \
 	display/intel_ddi.o \
 	display/intel_dp.o \
 	display/intel_dp_aux_backlight.o \
+	display/intel_dp_hdcp.o \
 	display/intel_dp_link_training.o \
 	display/intel_dp_mst.o \
 	display/intel_dsi.o \
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index d98e45a09c28..78ce5e41d559 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -38,7 +38,6 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_edid.h>
-#include <drm/drm_hdcp.h>
 #include <drm/drm_probe_helper.h>
 
 #include "i915_debugfs.h"
@@ -6396,609 +6395,6 @@ void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
 		edp_panel_vdd_off_sync(intel_dp);
 }
 
-static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
-{
-	long ret;
-
-#define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
-	ret = wait_event_interruptible_timeout(hdcp->cp_irq_queue, C,
-					       msecs_to_jiffies(timeout));
-
-	if (!ret)
-		DRM_DEBUG_KMS("Timedout at waiting for CP_IRQ\n");
-}
-
-static
-int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
-				u8 *an)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	u8 aksv[DRM_HDCP_KSV_LEN] = {};
-	ssize_t dpcd_ret;
-
-	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN,
-				     an, DRM_HDCP_AN_LEN);
-	if (dpcd_ret != DRM_HDCP_AN_LEN) {
-		drm_dbg_kms(&i915->drm,
-			    "Failed to write An over DP/AUX (%zd)\n",
-			    dpcd_ret);
-		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
-	}
-
-	/*
-	 * Since Aksv is Oh-So-Secret, we can't access it in software. So we
-	 * send an empty buffer of the correct length through the DP helpers. On
-	 * the other side, in the transfer hook, we'll generate a flag based on
-	 * the destination address which will tickle the hardware to output the
-	 * Aksv on our behalf after the header is sent.
-	 */
-	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AKSV,
-				     aksv, DRM_HDCP_KSV_LEN);
-	if (dpcd_ret != DRM_HDCP_KSV_LEN) {
-		drm_dbg_kms(&i915->drm,
-			    "Failed to write Aksv over DP/AUX (%zd)\n",
-			    dpcd_ret);
-		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
-	}
-	return 0;
-}
-
-static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
-				   u8 *bksv)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
-			       DRM_HDCP_KSV_LEN);
-	if (ret != DRM_HDCP_KSV_LEN) {
-		drm_dbg_kms(&i915->drm,
-			    "Read Bksv from DP/AUX failed (%zd)\n", ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-	return 0;
-}
-
-static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
-				      u8 *bstatus)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-
-	/*
-	 * For some reason the HDMI and DP HDCP specs call this register
-	 * definition by different names. In the HDMI spec, it's called BSTATUS,
-	 * but in DP it's called BINFO.
-	 */
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BINFO,
-			       bstatus, DRM_HDCP_BSTATUS_LEN);
-	if (ret != DRM_HDCP_BSTATUS_LEN) {
-		drm_dbg_kms(&i915->drm,
-			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-	return 0;
-}
-
-static
-int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
-			     u8 *bcaps)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BCAPS,
-			       bcaps, 1);
-	if (ret != 1) {
-		drm_dbg_kms(&i915->drm,
-			    "Read bcaps from DP/AUX failed (%zd)\n", ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-
-	return 0;
-}
-
-static
-int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
-				   bool *repeater_present)
-{
-	ssize_t ret;
-	u8 bcaps;
-
-	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
-	if (ret)
-		return ret;
-
-	*repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT;
-	return 0;
-}
-
-static
-int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
-				u8 *ri_prime)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME,
-			       ri_prime, DRM_HDCP_RI_LEN);
-	if (ret != DRM_HDCP_RI_LEN) {
-		drm_dbg_kms(&i915->drm, "Read Ri' from DP/AUX failed (%zd)\n",
-			    ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-	return 0;
-}
-
-static
-int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
-				 bool *ksv_ready)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-	u8 bstatus;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
-			       &bstatus, 1);
-	if (ret != 1) {
-		drm_dbg_kms(&i915->drm,
-			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-	*ksv_ready = bstatus & DP_BSTATUS_READY;
-	return 0;
-}
-
-static
-int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
-				int num_downstream, u8 *ksv_fifo)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-	int i;
-
-	/* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */
-	for (i = 0; i < num_downstream; i += 3) {
-		size_t len = min(num_downstream - i, 3) * DRM_HDCP_KSV_LEN;
-		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
-				       DP_AUX_HDCP_KSV_FIFO,
-				       ksv_fifo + i * DRM_HDCP_KSV_LEN,
-				       len);
-		if (ret != len) {
-			drm_dbg_kms(&i915->drm,
-				    "Read ksv[%d] from DP/AUX failed (%zd)\n",
-				    i, ret);
-			return ret >= 0 ? -EIO : ret;
-		}
-	}
-	return 0;
-}
-
-static
-int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
-				    int i, u32 *part)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-
-	if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
-		return -EINVAL;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
-			       DP_AUX_HDCP_V_PRIME(i), part,
-			       DRM_HDCP_V_PRIME_PART_LEN);
-	if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
-		drm_dbg_kms(&i915->drm,
-			    "Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-	return 0;
-}
-
-static
-int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
-				    enum transcoder cpu_transcoder,
-				    bool enable)
-{
-	/* Not used for single stream DisplayPort setups */
-	return 0;
-}
-
-static
-bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-	u8 bstatus;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
-			       &bstatus, 1);
-	if (ret != 1) {
-		drm_dbg_kms(&i915->drm,
-			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
-		return false;
-	}
-
-	return !(bstatus & (DP_BSTATUS_LINK_FAILURE | DP_BSTATUS_REAUTH_REQ));
-}
-
-static
-int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
-			  bool *hdcp_capable)
-{
-	ssize_t ret;
-	u8 bcaps;
-
-	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
-	if (ret)
-		return ret;
-
-	*hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE;
-	return 0;
-}
-
-struct hdcp2_dp_errata_stream_type {
-	u8	msg_id;
-	u8	stream_type;
-} __packed;
-
-struct hdcp2_dp_msg_data {
-	u8 msg_id;
-	u32 offset;
-	bool msg_detectable;
-	u32 timeout;
-	u32 timeout2; /* Added for non_paired situation */
-};
-
-static const struct hdcp2_dp_msg_data hdcp2_dp_msg_data[] = {
-	{ HDCP_2_2_AKE_INIT, DP_HDCP_2_2_AKE_INIT_OFFSET, false, 0, 0 },
-	{ HDCP_2_2_AKE_SEND_CERT, DP_HDCP_2_2_AKE_SEND_CERT_OFFSET,
-	  false, HDCP_2_2_CERT_TIMEOUT_MS, 0 },
-	{ HDCP_2_2_AKE_NO_STORED_KM, DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET,
-	  false, 0, 0 },
-	{ HDCP_2_2_AKE_STORED_KM, DP_HDCP_2_2_AKE_STORED_KM_OFFSET,
-	  false, 0, 0 },
-	{ HDCP_2_2_AKE_SEND_HPRIME, DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET,
-	  true, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
-	  HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS },
-	{ HDCP_2_2_AKE_SEND_PAIRING_INFO,
-	  DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET, true,
-	  HDCP_2_2_PAIRING_TIMEOUT_MS, 0 },
-	{ HDCP_2_2_LC_INIT, DP_HDCP_2_2_LC_INIT_OFFSET, false, 0, 0 },
-	{ HDCP_2_2_LC_SEND_LPRIME, DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET,
-	  false, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, 0 },
-	{ HDCP_2_2_SKE_SEND_EKS, DP_HDCP_2_2_SKE_SEND_EKS_OFFSET, false,
-	  0, 0 },
-	{ HDCP_2_2_REP_SEND_RECVID_LIST,
-	  DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET, true,
-	  HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0 },
-	{ HDCP_2_2_REP_SEND_ACK, DP_HDCP_2_2_REP_SEND_ACK_OFFSET, false,
-	  0, 0 },
-	{ HDCP_2_2_REP_STREAM_MANAGE,
-	  DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET, false,
-	  0, 0 },
-	{ HDCP_2_2_REP_STREAM_READY, DP_HDCP_2_2_REP_STREAM_READY_OFFSET,
-	  false, HDCP_2_2_STREAM_READY_TIMEOUT_MS, 0 },
-/* local define to shovel this through the write_2_2 interface */
-#define HDCP_2_2_ERRATA_DP_STREAM_TYPE	50
-	{ HDCP_2_2_ERRATA_DP_STREAM_TYPE,
-	  DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, false,
-	  0, 0 },
-};
-
-static int
-intel_dp_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
-			      u8 *rx_status)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
-			       DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
-			       HDCP_2_2_DP_RXSTATUS_LEN);
-	if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
-		drm_dbg_kms(&i915->drm,
-			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-
-	return 0;
-}
-
-static
-int hdcp2_detect_msg_availability(struct intel_digital_port *intel_dig_port,
-				  u8 msg_id, bool *msg_ready)
-{
-	u8 rx_status;
-	int ret;
-
-	*msg_ready = false;
-	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
-	if (ret < 0)
-		return ret;
-
-	switch (msg_id) {
-	case HDCP_2_2_AKE_SEND_HPRIME:
-		if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rx_status))
-			*msg_ready = true;
-		break;
-	case HDCP_2_2_AKE_SEND_PAIRING_INFO:
-		if (HDCP_2_2_DP_RXSTATUS_PAIRING(rx_status))
-			*msg_ready = true;
-		break;
-	case HDCP_2_2_REP_SEND_RECVID_LIST:
-		if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
-			*msg_ready = true;
-		break;
-	default:
-		DRM_ERROR("Unidentified msg_id: %d\n", msg_id);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static ssize_t
-intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
-			    const struct hdcp2_dp_msg_data *hdcp2_msg_data)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	struct intel_dp *dp = &intel_dig_port->dp;
-	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
-	u8 msg_id = hdcp2_msg_data->msg_id;
-	int ret, timeout;
-	bool msg_ready = false;
-
-	if (msg_id == HDCP_2_2_AKE_SEND_HPRIME && !hdcp->is_paired)
-		timeout = hdcp2_msg_data->timeout2;
-	else
-		timeout = hdcp2_msg_data->timeout;
-
-	/*
-	 * There is no way to detect the CERT, LPRIME and STREAM_READY
-	 * availability. So Wait for timeout and read the msg.
-	 */
-	if (!hdcp2_msg_data->msg_detectable) {
-		mdelay(timeout);
-		ret = 0;
-	} else {
-		/*
-		 * As we want to check the msg availability at timeout, Ignoring
-		 * the timeout at wait for CP_IRQ.
-		 */
-		intel_dp_hdcp_wait_for_cp_irq(hdcp, timeout);
-		ret = hdcp2_detect_msg_availability(intel_dig_port,
-						    msg_id, &msg_ready);
-		if (!msg_ready)
-			ret = -ETIMEDOUT;
-	}
-
-	if (ret)
-		drm_dbg_kms(&i915->drm,
-			    "msg_id %d, ret %d, timeout(mSec): %d\n",
-			    hdcp2_msg_data->msg_id, ret, timeout);
-
-	return ret;
-}
-
-static const struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(hdcp2_dp_msg_data); i++)
-		if (hdcp2_dp_msg_data[i].msg_id == msg_id)
-			return &hdcp2_dp_msg_data[i];
-
-	return NULL;
-}
-
-static
-int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
-			     void *buf, size_t size)
-{
-	struct intel_dp *dp = &intel_dig_port->dp;
-	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
-	unsigned int offset;
-	u8 *byte = buf;
-	ssize_t ret, bytes_to_write, len;
-	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
-
-	hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
-	if (!hdcp2_msg_data)
-		return -EINVAL;
-
-	offset = hdcp2_msg_data->offset;
-
-	/* No msg_id in DP HDCP2.2 msgs */
-	bytes_to_write = size - 1;
-	byte++;
-
-	hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count);
-
-	while (bytes_to_write) {
-		len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
-				DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write;
-
-		ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
-					offset, (void *)byte, len);
-		if (ret < 0)
-			return ret;
-
-		bytes_to_write -= ret;
-		byte += ret;
-		offset += ret;
-	}
-
-	return size;
-}
-
-static
-ssize_t get_receiver_id_list_size(struct intel_digital_port *intel_dig_port)
-{
-	u8 rx_info[HDCP_2_2_RXINFO_LEN];
-	u32 dev_cnt;
-	ssize_t ret;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
-			       DP_HDCP_2_2_REG_RXINFO_OFFSET,
-			       (void *)rx_info, HDCP_2_2_RXINFO_LEN);
-	if (ret != HDCP_2_2_RXINFO_LEN)
-		return ret >= 0 ? -EIO : ret;
-
-	dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
-		   HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
-
-	if (dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
-		dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
-
-	ret = sizeof(struct hdcp2_rep_send_receiverid_list) -
-		HDCP_2_2_RECEIVER_IDS_MAX_LEN +
-		(dev_cnt * HDCP_2_2_RECEIVER_ID_LEN);
-
-	return ret;
-}
-
-static
-int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
-			    u8 msg_id, void *buf, size_t size)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	unsigned int offset;
-	u8 *byte = buf;
-	ssize_t ret, bytes_to_recv, len;
-	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
-
-	hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
-	if (!hdcp2_msg_data)
-		return -EINVAL;
-	offset = hdcp2_msg_data->offset;
-
-	ret = intel_dp_hdcp2_wait_for_msg(intel_dig_port, hdcp2_msg_data);
-	if (ret < 0)
-		return ret;
-
-	if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
-		ret = get_receiver_id_list_size(intel_dig_port);
-		if (ret < 0)
-			return ret;
-
-		size = ret;
-	}
-	bytes_to_recv = size - 1;
-
-	/* DP adaptation msgs has no msg_id */
-	byte++;
-
-	while (bytes_to_recv) {
-		len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ?
-		      DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
-
-		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, offset,
-				       (void *)byte, len);
-		if (ret < 0) {
-			drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
-				    msg_id, ret);
-			return ret;
-		}
-
-		bytes_to_recv -= ret;
-		byte += ret;
-		offset += ret;
-	}
-	byte = buf;
-	*byte = msg_id;
-
-	return size;
-}
-
-static
-int intel_dp_hdcp2_config_stream_type(struct intel_digital_port *intel_dig_port,
-				      bool is_repeater, u8 content_type)
-{
-	int ret;
-	struct hdcp2_dp_errata_stream_type stream_type_msg;
-
-	if (is_repeater)
-		return 0;
-
-	/*
-	 * Errata for DP: As Stream type is used for encryption, Receiver
-	 * should be communicated with stream type for the decryption of the
-	 * content.
-	 * Repeater will be communicated with stream type as a part of it's
-	 * auth later in time.
-	 */
-	stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
-	stream_type_msg.stream_type = content_type;
-
-	ret =  intel_dp_hdcp2_write_msg(intel_dig_port, &stream_type_msg,
-					sizeof(stream_type_msg));
-
-	return ret < 0 ? ret : 0;
-
-}
-
-static
-int intel_dp_hdcp2_check_link(struct intel_digital_port *intel_dig_port)
-{
-	u8 rx_status;
-	int ret;
-
-	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
-	if (ret)
-		return ret;
-
-	if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
-		ret = HDCP_REAUTH_REQUEST;
-	else if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
-		ret = HDCP_LINK_INTEGRITY_FAILURE;
-	else if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
-		ret = HDCP_TOPOLOGY_CHANGE;
-
-	return ret;
-}
-
-static
-int intel_dp_hdcp2_capable(struct intel_digital_port *intel_dig_port,
-			   bool *capable)
-{
-	u8 rx_caps[3];
-	int ret;
-
-	*capable = false;
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
-			       DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
-			       rx_caps, HDCP_2_2_RXCAPS_LEN);
-	if (ret != HDCP_2_2_RXCAPS_LEN)
-		return ret >= 0 ? -EIO : ret;
-
-	if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
-	    HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2]))
-		*capable = true;
-
-	return 0;
-}
-
-static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
-	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
-	.read_bksv = intel_dp_hdcp_read_bksv,
-	.read_bstatus = intel_dp_hdcp_read_bstatus,
-	.repeater_present = intel_dp_hdcp_repeater_present,
-	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
-	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
-	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
-	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
-	.toggle_signalling = intel_dp_hdcp_toggle_signalling,
-	.check_link = intel_dp_hdcp_check_link,
-	.hdcp_capable = intel_dp_hdcp_capable,
-	.write_2_2_msg = intel_dp_hdcp2_write_msg,
-	.read_2_2_msg = intel_dp_hdcp2_read_msg,
-	.config_stream_type = intel_dp_hdcp2_config_stream_type,
-	.check_2_2_link = intel_dp_hdcp2_check_link,
-	.hdcp_2_2_capable = intel_dp_hdcp2_capable,
-	.protocol = HDCP_PROTOCOL_DP,
-};
-
 static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -8232,7 +7628,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	intel_dp_add_properties(intel_dp, connector);
 
 	if (is_hdcp_supported(dev_priv, port) && !intel_dp_is_edp(intel_dp)) {
-		int ret = intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
+		int ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
 		if (ret)
 			drm_dbg_kms(&dev_priv->drm,
 				    "HDCP init failed, skipping.\n");
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 6352c7e97e3b..794f25573254 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -134,4 +134,7 @@ void intel_ddi_update_pipe(struct intel_atomic_state *state,
 			   const struct intel_crtc_state *crtc_state,
 			   const struct drm_connector_state *conn_state);
 
+int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
+		       struct intel_connector *intel_connector);
+
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
new file mode 100644
index 000000000000..0e06a1066d61
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -0,0 +1,636 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (C) 2020 Google, Inc.
+ *
+ * Authors:
+ * Sean Paul <seanpaul@chromium.org>
+ */
+
+#include <drm/drm_dp_helper.h>
+#include <drm/drm_hdcp.h>
+#include <drm/drm_print.h>
+
+#include "intel_display_types.h"
+#include "intel_dp.h"
+#include "intel_hdcp.h"
+
+static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
+{
+	long ret;
+
+#define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
+	ret = wait_event_interruptible_timeout(hdcp->cp_irq_queue, C,
+					       msecs_to_jiffies(timeout));
+
+	if (!ret)
+		DRM_DEBUG_KMS("Timedout at waiting for CP_IRQ\n");
+}
+
+static
+int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
+				u8 *an)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	u8 aksv[DRM_HDCP_KSV_LEN] = {};
+	ssize_t dpcd_ret;
+
+	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN,
+				     an, DRM_HDCP_AN_LEN);
+	if (dpcd_ret != DRM_HDCP_AN_LEN) {
+		drm_dbg_kms(&i915->drm,
+			    "Failed to write An over DP/AUX (%zd)\n",
+			    dpcd_ret);
+		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
+	}
+
+	/*
+	 * Since Aksv is Oh-So-Secret, we can't access it in software. So we
+	 * send an empty buffer of the correct length through the DP helpers. On
+	 * the other side, in the transfer hook, we'll generate a flag based on
+	 * the destination address which will tickle the hardware to output the
+	 * Aksv on our behalf after the header is sent.
+	 */
+	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AKSV,
+				     aksv, DRM_HDCP_KSV_LEN);
+	if (dpcd_ret != DRM_HDCP_KSV_LEN) {
+		drm_dbg_kms(&i915->drm,
+			    "Failed to write Aksv over DP/AUX (%zd)\n",
+			    dpcd_ret);
+		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
+	}
+	return 0;
+}
+
+static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
+				   u8 *bksv)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
+			       DRM_HDCP_KSV_LEN);
+	if (ret != DRM_HDCP_KSV_LEN) {
+		drm_dbg_kms(&i915->drm,
+			    "Read Bksv from DP/AUX failed (%zd)\n", ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+	return 0;
+}
+
+static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
+				      u8 *bstatus)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+
+	/*
+	 * For some reason the HDMI and DP HDCP specs call this register
+	 * definition by different names. In the HDMI spec, it's called BSTATUS,
+	 * but in DP it's called BINFO.
+	 */
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BINFO,
+			       bstatus, DRM_HDCP_BSTATUS_LEN);
+	if (ret != DRM_HDCP_BSTATUS_LEN) {
+		drm_dbg_kms(&i915->drm,
+			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+	return 0;
+}
+
+static
+int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
+			     u8 *bcaps)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BCAPS,
+			       bcaps, 1);
+	if (ret != 1) {
+		drm_dbg_kms(&i915->drm,
+			    "Read bcaps from DP/AUX failed (%zd)\n", ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+
+	return 0;
+}
+
+static
+int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
+				   bool *repeater_present)
+{
+	ssize_t ret;
+	u8 bcaps;
+
+	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
+	if (ret)
+		return ret;
+
+	*repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT;
+	return 0;
+}
+
+static
+int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
+				u8 *ri_prime)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME,
+			       ri_prime, DRM_HDCP_RI_LEN);
+	if (ret != DRM_HDCP_RI_LEN) {
+		drm_dbg_kms(&i915->drm, "Read Ri' from DP/AUX failed (%zd)\n",
+			    ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+	return 0;
+}
+
+static
+int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
+				 bool *ksv_ready)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+	u8 bstatus;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
+			       &bstatus, 1);
+	if (ret != 1) {
+		drm_dbg_kms(&i915->drm,
+			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+	*ksv_ready = bstatus & DP_BSTATUS_READY;
+	return 0;
+}
+
+static
+int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
+				int num_downstream, u8 *ksv_fifo)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+	int i;
+
+	/* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */
+	for (i = 0; i < num_downstream; i += 3) {
+		size_t len = min(num_downstream - i, 3) * DRM_HDCP_KSV_LEN;
+		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+				       DP_AUX_HDCP_KSV_FIFO,
+				       ksv_fifo + i * DRM_HDCP_KSV_LEN,
+				       len);
+		if (ret != len) {
+			drm_dbg_kms(&i915->drm,
+				    "Read ksv[%d] from DP/AUX failed (%zd)\n",
+				    i, ret);
+			return ret >= 0 ? -EIO : ret;
+		}
+	}
+	return 0;
+}
+
+static
+int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
+				    int i, u32 *part)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+
+	if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
+		return -EINVAL;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+			       DP_AUX_HDCP_V_PRIME(i), part,
+			       DRM_HDCP_V_PRIME_PART_LEN);
+	if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
+		drm_dbg_kms(&i915->drm,
+			    "Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+	return 0;
+}
+
+static
+int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
+				    enum transcoder cpu_transcoder,
+				    bool enable)
+{
+	/* Not used for single stream DisplayPort setups */
+	return 0;
+}
+
+static
+bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+	u8 bstatus;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
+			       &bstatus, 1);
+	if (ret != 1) {
+		drm_dbg_kms(&i915->drm,
+			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
+		return false;
+	}
+
+	return !(bstatus & (DP_BSTATUS_LINK_FAILURE | DP_BSTATUS_REAUTH_REQ));
+}
+
+static
+int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
+			  bool *hdcp_capable)
+{
+	ssize_t ret;
+	u8 bcaps;
+
+	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
+	if (ret)
+		return ret;
+
+	*hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE;
+	return 0;
+}
+
+struct hdcp2_dp_errata_stream_type {
+	u8	msg_id;
+	u8	stream_type;
+} __packed;
+
+struct hdcp2_dp_msg_data {
+	u8 msg_id;
+	u32 offset;
+	bool msg_detectable;
+	u32 timeout;
+	u32 timeout2; /* Added for non_paired situation */
+};
+
+static const struct hdcp2_dp_msg_data hdcp2_dp_msg_data[] = {
+	{ HDCP_2_2_AKE_INIT, DP_HDCP_2_2_AKE_INIT_OFFSET, false, 0, 0 },
+	{ HDCP_2_2_AKE_SEND_CERT, DP_HDCP_2_2_AKE_SEND_CERT_OFFSET,
+	  false, HDCP_2_2_CERT_TIMEOUT_MS, 0 },
+	{ HDCP_2_2_AKE_NO_STORED_KM, DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET,
+	  false, 0, 0 },
+	{ HDCP_2_2_AKE_STORED_KM, DP_HDCP_2_2_AKE_STORED_KM_OFFSET,
+	  false, 0, 0 },
+	{ HDCP_2_2_AKE_SEND_HPRIME, DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET,
+	  true, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
+	  HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS },
+	{ HDCP_2_2_AKE_SEND_PAIRING_INFO,
+	  DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET, true,
+	  HDCP_2_2_PAIRING_TIMEOUT_MS, 0 },
+	{ HDCP_2_2_LC_INIT, DP_HDCP_2_2_LC_INIT_OFFSET, false, 0, 0 },
+	{ HDCP_2_2_LC_SEND_LPRIME, DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET,
+	  false, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, 0 },
+	{ HDCP_2_2_SKE_SEND_EKS, DP_HDCP_2_2_SKE_SEND_EKS_OFFSET, false,
+	  0, 0 },
+	{ HDCP_2_2_REP_SEND_RECVID_LIST,
+	  DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET, true,
+	  HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0 },
+	{ HDCP_2_2_REP_SEND_ACK, DP_HDCP_2_2_REP_SEND_ACK_OFFSET, false,
+	  0, 0 },
+	{ HDCP_2_2_REP_STREAM_MANAGE,
+	  DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET, false,
+	  0, 0 },
+	{ HDCP_2_2_REP_STREAM_READY, DP_HDCP_2_2_REP_STREAM_READY_OFFSET,
+	  false, HDCP_2_2_STREAM_READY_TIMEOUT_MS, 0 },
+/* local define to shovel this through the write_2_2 interface */
+#define HDCP_2_2_ERRATA_DP_STREAM_TYPE	50
+	{ HDCP_2_2_ERRATA_DP_STREAM_TYPE,
+	  DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, false,
+	  0, 0 },
+};
+
+static int
+intel_dp_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
+			      u8 *rx_status)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+			       DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
+			       HDCP_2_2_DP_RXSTATUS_LEN);
+	if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
+		drm_dbg_kms(&i915->drm,
+			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+
+	return 0;
+}
+
+static
+int hdcp2_detect_msg_availability(struct intel_digital_port *intel_dig_port,
+				  u8 msg_id, bool *msg_ready)
+{
+	u8 rx_status;
+	int ret;
+
+	*msg_ready = false;
+	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
+	if (ret < 0)
+		return ret;
+
+	switch (msg_id) {
+	case HDCP_2_2_AKE_SEND_HPRIME:
+		if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rx_status))
+			*msg_ready = true;
+		break;
+	case HDCP_2_2_AKE_SEND_PAIRING_INFO:
+		if (HDCP_2_2_DP_RXSTATUS_PAIRING(rx_status))
+			*msg_ready = true;
+		break;
+	case HDCP_2_2_REP_SEND_RECVID_LIST:
+		if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
+			*msg_ready = true;
+		break;
+	default:
+		DRM_ERROR("Unidentified msg_id: %d\n", msg_id);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static ssize_t
+intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
+			    const struct hdcp2_dp_msg_data *hdcp2_msg_data)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	struct intel_dp *dp = &intel_dig_port->dp;
+	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
+	u8 msg_id = hdcp2_msg_data->msg_id;
+	int ret, timeout;
+	bool msg_ready = false;
+
+	if (msg_id == HDCP_2_2_AKE_SEND_HPRIME && !hdcp->is_paired)
+		timeout = hdcp2_msg_data->timeout2;
+	else
+		timeout = hdcp2_msg_data->timeout;
+
+	/*
+	 * There is no way to detect the CERT, LPRIME and STREAM_READY
+	 * availability. So Wait for timeout and read the msg.
+	 */
+	if (!hdcp2_msg_data->msg_detectable) {
+		mdelay(timeout);
+		ret = 0;
+	} else {
+		/*
+		 * As we want to check the msg availability at timeout, Ignoring
+		 * the timeout at wait for CP_IRQ.
+		 */
+		intel_dp_hdcp_wait_for_cp_irq(hdcp, timeout);
+		ret = hdcp2_detect_msg_availability(intel_dig_port,
+						    msg_id, &msg_ready);
+		if (!msg_ready)
+			ret = -ETIMEDOUT;
+	}
+
+	if (ret)
+		drm_dbg_kms(&i915->drm,
+			    "msg_id %d, ret %d, timeout(mSec): %d\n",
+			    hdcp2_msg_data->msg_id, ret, timeout);
+
+	return ret;
+}
+
+static const struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hdcp2_dp_msg_data); i++)
+		if (hdcp2_dp_msg_data[i].msg_id == msg_id)
+			return &hdcp2_dp_msg_data[i];
+
+	return NULL;
+}
+
+static
+int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
+			     void *buf, size_t size)
+{
+	struct intel_dp *dp = &intel_dig_port->dp;
+	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
+	unsigned int offset;
+	u8 *byte = buf;
+	ssize_t ret, bytes_to_write, len;
+	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
+
+	hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
+	if (!hdcp2_msg_data)
+		return -EINVAL;
+
+	offset = hdcp2_msg_data->offset;
+
+	/* No msg_id in DP HDCP2.2 msgs */
+	bytes_to_write = size - 1;
+	byte++;
+
+	hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count);
+
+	while (bytes_to_write) {
+		len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
+				DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write;
+
+		ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
+					offset, (void *)byte, len);
+		if (ret < 0)
+			return ret;
+
+		bytes_to_write -= ret;
+		byte += ret;
+		offset += ret;
+	}
+
+	return size;
+}
+
+static
+ssize_t get_receiver_id_list_size(struct intel_digital_port *intel_dig_port)
+{
+	u8 rx_info[HDCP_2_2_RXINFO_LEN];
+	u32 dev_cnt;
+	ssize_t ret;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+			       DP_HDCP_2_2_REG_RXINFO_OFFSET,
+			       (void *)rx_info, HDCP_2_2_RXINFO_LEN);
+	if (ret != HDCP_2_2_RXINFO_LEN)
+		return ret >= 0 ? -EIO : ret;
+
+	dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
+		   HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
+
+	if (dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
+		dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
+
+	ret = sizeof(struct hdcp2_rep_send_receiverid_list) -
+		HDCP_2_2_RECEIVER_IDS_MAX_LEN +
+		(dev_cnt * HDCP_2_2_RECEIVER_ID_LEN);
+
+	return ret;
+}
+
+static
+int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
+			    u8 msg_id, void *buf, size_t size)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	unsigned int offset;
+	u8 *byte = buf;
+	ssize_t ret, bytes_to_recv, len;
+	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
+
+	hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
+	if (!hdcp2_msg_data)
+		return -EINVAL;
+	offset = hdcp2_msg_data->offset;
+
+	ret = intel_dp_hdcp2_wait_for_msg(intel_dig_port, hdcp2_msg_data);
+	if (ret < 0)
+		return ret;
+
+	if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
+		ret = get_receiver_id_list_size(intel_dig_port);
+		if (ret < 0)
+			return ret;
+
+		size = ret;
+	}
+	bytes_to_recv = size - 1;
+
+	/* DP adaptation msgs has no msg_id */
+	byte++;
+
+	while (bytes_to_recv) {
+		len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ?
+		      DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
+
+		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, offset,
+				       (void *)byte, len);
+		if (ret < 0) {
+			drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
+				    msg_id, ret);
+			return ret;
+		}
+
+		bytes_to_recv -= ret;
+		byte += ret;
+		offset += ret;
+	}
+	byte = buf;
+	*byte = msg_id;
+
+	return size;
+}
+
+static
+int intel_dp_hdcp2_config_stream_type(struct intel_digital_port *intel_dig_port,
+				      bool is_repeater, u8 content_type)
+{
+	int ret;
+	struct hdcp2_dp_errata_stream_type stream_type_msg;
+
+	if (is_repeater)
+		return 0;
+
+	/*
+	 * Errata for DP: As Stream type is used for encryption, Receiver
+	 * should be communicated with stream type for the decryption of the
+	 * content.
+	 * Repeater will be communicated with stream type as a part of it's
+	 * auth later in time.
+	 */
+	stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
+	stream_type_msg.stream_type = content_type;
+
+	ret =  intel_dp_hdcp2_write_msg(intel_dig_port, &stream_type_msg,
+					sizeof(stream_type_msg));
+
+	return ret < 0 ? ret : 0;
+
+}
+
+static
+int intel_dp_hdcp2_check_link(struct intel_digital_port *intel_dig_port)
+{
+	u8 rx_status;
+	int ret;
+
+	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
+	if (ret)
+		return ret;
+
+	if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
+		ret = HDCP_REAUTH_REQUEST;
+	else if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
+		ret = HDCP_LINK_INTEGRITY_FAILURE;
+	else if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
+		ret = HDCP_TOPOLOGY_CHANGE;
+
+	return ret;
+}
+
+static
+int intel_dp_hdcp2_capable(struct intel_digital_port *intel_dig_port,
+			   bool *capable)
+{
+	u8 rx_caps[3];
+	int ret;
+
+	*capable = false;
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+			       DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
+			       rx_caps, HDCP_2_2_RXCAPS_LEN);
+	if (ret != HDCP_2_2_RXCAPS_LEN)
+		return ret >= 0 ? -EIO : ret;
+
+	if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
+	    HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2]))
+		*capable = true;
+
+	return 0;
+}
+
+static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
+	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
+	.read_bksv = intel_dp_hdcp_read_bksv,
+	.read_bstatus = intel_dp_hdcp_read_bstatus,
+	.repeater_present = intel_dp_hdcp_repeater_present,
+	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
+	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
+	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
+	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
+	.toggle_signalling = intel_dp_hdcp_toggle_signalling,
+	.check_link = intel_dp_hdcp_check_link,
+	.hdcp_capable = intel_dp_hdcp_capable,
+	.write_2_2_msg = intel_dp_hdcp2_write_msg,
+	.read_2_2_msg = intel_dp_hdcp2_read_msg,
+	.config_stream_type = intel_dp_hdcp2_config_stream_type,
+	.check_2_2_link = intel_dp_hdcp2_check_link,
+	.hdcp_2_2_capable = intel_dp_hdcp2_capable,
+	.protocol = HDCP_PROTOCOL_DP,
+};
+
+int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
+		       struct intel_connector *intel_connector)
+{
+	struct drm_device *dev = intel_connector->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	enum port port = intel_encoder->port;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+
+	if (!is_hdcp_supported(dev_priv, port))
+		return 0;
+
+	if (!intel_dp_is_edp(intel_dp))
+		return intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
+
+	return 0;
+}
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 12/17] drm/i915: Factor out HDCP shim functions from dp for use by dp_mst
@ 2020-06-23 15:59   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

These functions are all the same for dp and dp_mst, so move them into a
dedicated file for both sst and mst to use.

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-11-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-12-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-12-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-12-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-12-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-12-sean@poorly.run #v6

Changes in v2:
-None
Changes in v3:
-Created intel_dp_hdcp.c for the shared functions to live (Ville)
Changes in v4:
-Rebased on new drm logging change
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-Rebased patch
---
 drivers/gpu/drm/i915/Makefile                |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c      | 606 +-----------------
 drivers/gpu/drm/i915/display/intel_dp.h      |   3 +
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 636 +++++++++++++++++++
 4 files changed, 641 insertions(+), 605 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/intel_dp_hdcp.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 41a27fd5dbc7..cba4ddb95ab1 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -233,6 +233,7 @@ i915-y += \
 	display/intel_ddi.o \
 	display/intel_dp.o \
 	display/intel_dp_aux_backlight.o \
+	display/intel_dp_hdcp.o \
 	display/intel_dp_link_training.o \
 	display/intel_dp_mst.o \
 	display/intel_dsi.o \
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index d98e45a09c28..78ce5e41d559 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -38,7 +38,6 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_edid.h>
-#include <drm/drm_hdcp.h>
 #include <drm/drm_probe_helper.h>
 
 #include "i915_debugfs.h"
@@ -6396,609 +6395,6 @@ void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
 		edp_panel_vdd_off_sync(intel_dp);
 }
 
-static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
-{
-	long ret;
-
-#define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
-	ret = wait_event_interruptible_timeout(hdcp->cp_irq_queue, C,
-					       msecs_to_jiffies(timeout));
-
-	if (!ret)
-		DRM_DEBUG_KMS("Timedout at waiting for CP_IRQ\n");
-}
-
-static
-int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
-				u8 *an)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	u8 aksv[DRM_HDCP_KSV_LEN] = {};
-	ssize_t dpcd_ret;
-
-	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN,
-				     an, DRM_HDCP_AN_LEN);
-	if (dpcd_ret != DRM_HDCP_AN_LEN) {
-		drm_dbg_kms(&i915->drm,
-			    "Failed to write An over DP/AUX (%zd)\n",
-			    dpcd_ret);
-		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
-	}
-
-	/*
-	 * Since Aksv is Oh-So-Secret, we can't access it in software. So we
-	 * send an empty buffer of the correct length through the DP helpers. On
-	 * the other side, in the transfer hook, we'll generate a flag based on
-	 * the destination address which will tickle the hardware to output the
-	 * Aksv on our behalf after the header is sent.
-	 */
-	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AKSV,
-				     aksv, DRM_HDCP_KSV_LEN);
-	if (dpcd_ret != DRM_HDCP_KSV_LEN) {
-		drm_dbg_kms(&i915->drm,
-			    "Failed to write Aksv over DP/AUX (%zd)\n",
-			    dpcd_ret);
-		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
-	}
-	return 0;
-}
-
-static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
-				   u8 *bksv)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
-			       DRM_HDCP_KSV_LEN);
-	if (ret != DRM_HDCP_KSV_LEN) {
-		drm_dbg_kms(&i915->drm,
-			    "Read Bksv from DP/AUX failed (%zd)\n", ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-	return 0;
-}
-
-static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
-				      u8 *bstatus)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-
-	/*
-	 * For some reason the HDMI and DP HDCP specs call this register
-	 * definition by different names. In the HDMI spec, it's called BSTATUS,
-	 * but in DP it's called BINFO.
-	 */
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BINFO,
-			       bstatus, DRM_HDCP_BSTATUS_LEN);
-	if (ret != DRM_HDCP_BSTATUS_LEN) {
-		drm_dbg_kms(&i915->drm,
-			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-	return 0;
-}
-
-static
-int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
-			     u8 *bcaps)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BCAPS,
-			       bcaps, 1);
-	if (ret != 1) {
-		drm_dbg_kms(&i915->drm,
-			    "Read bcaps from DP/AUX failed (%zd)\n", ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-
-	return 0;
-}
-
-static
-int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
-				   bool *repeater_present)
-{
-	ssize_t ret;
-	u8 bcaps;
-
-	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
-	if (ret)
-		return ret;
-
-	*repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT;
-	return 0;
-}
-
-static
-int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
-				u8 *ri_prime)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME,
-			       ri_prime, DRM_HDCP_RI_LEN);
-	if (ret != DRM_HDCP_RI_LEN) {
-		drm_dbg_kms(&i915->drm, "Read Ri' from DP/AUX failed (%zd)\n",
-			    ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-	return 0;
-}
-
-static
-int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
-				 bool *ksv_ready)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-	u8 bstatus;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
-			       &bstatus, 1);
-	if (ret != 1) {
-		drm_dbg_kms(&i915->drm,
-			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-	*ksv_ready = bstatus & DP_BSTATUS_READY;
-	return 0;
-}
-
-static
-int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
-				int num_downstream, u8 *ksv_fifo)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-	int i;
-
-	/* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */
-	for (i = 0; i < num_downstream; i += 3) {
-		size_t len = min(num_downstream - i, 3) * DRM_HDCP_KSV_LEN;
-		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
-				       DP_AUX_HDCP_KSV_FIFO,
-				       ksv_fifo + i * DRM_HDCP_KSV_LEN,
-				       len);
-		if (ret != len) {
-			drm_dbg_kms(&i915->drm,
-				    "Read ksv[%d] from DP/AUX failed (%zd)\n",
-				    i, ret);
-			return ret >= 0 ? -EIO : ret;
-		}
-	}
-	return 0;
-}
-
-static
-int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
-				    int i, u32 *part)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-
-	if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
-		return -EINVAL;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
-			       DP_AUX_HDCP_V_PRIME(i), part,
-			       DRM_HDCP_V_PRIME_PART_LEN);
-	if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
-		drm_dbg_kms(&i915->drm,
-			    "Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-	return 0;
-}
-
-static
-int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
-				    enum transcoder cpu_transcoder,
-				    bool enable)
-{
-	/* Not used for single stream DisplayPort setups */
-	return 0;
-}
-
-static
-bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-	u8 bstatus;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
-			       &bstatus, 1);
-	if (ret != 1) {
-		drm_dbg_kms(&i915->drm,
-			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
-		return false;
-	}
-
-	return !(bstatus & (DP_BSTATUS_LINK_FAILURE | DP_BSTATUS_REAUTH_REQ));
-}
-
-static
-int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
-			  bool *hdcp_capable)
-{
-	ssize_t ret;
-	u8 bcaps;
-
-	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
-	if (ret)
-		return ret;
-
-	*hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE;
-	return 0;
-}
-
-struct hdcp2_dp_errata_stream_type {
-	u8	msg_id;
-	u8	stream_type;
-} __packed;
-
-struct hdcp2_dp_msg_data {
-	u8 msg_id;
-	u32 offset;
-	bool msg_detectable;
-	u32 timeout;
-	u32 timeout2; /* Added for non_paired situation */
-};
-
-static const struct hdcp2_dp_msg_data hdcp2_dp_msg_data[] = {
-	{ HDCP_2_2_AKE_INIT, DP_HDCP_2_2_AKE_INIT_OFFSET, false, 0, 0 },
-	{ HDCP_2_2_AKE_SEND_CERT, DP_HDCP_2_2_AKE_SEND_CERT_OFFSET,
-	  false, HDCP_2_2_CERT_TIMEOUT_MS, 0 },
-	{ HDCP_2_2_AKE_NO_STORED_KM, DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET,
-	  false, 0, 0 },
-	{ HDCP_2_2_AKE_STORED_KM, DP_HDCP_2_2_AKE_STORED_KM_OFFSET,
-	  false, 0, 0 },
-	{ HDCP_2_2_AKE_SEND_HPRIME, DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET,
-	  true, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
-	  HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS },
-	{ HDCP_2_2_AKE_SEND_PAIRING_INFO,
-	  DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET, true,
-	  HDCP_2_2_PAIRING_TIMEOUT_MS, 0 },
-	{ HDCP_2_2_LC_INIT, DP_HDCP_2_2_LC_INIT_OFFSET, false, 0, 0 },
-	{ HDCP_2_2_LC_SEND_LPRIME, DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET,
-	  false, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, 0 },
-	{ HDCP_2_2_SKE_SEND_EKS, DP_HDCP_2_2_SKE_SEND_EKS_OFFSET, false,
-	  0, 0 },
-	{ HDCP_2_2_REP_SEND_RECVID_LIST,
-	  DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET, true,
-	  HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0 },
-	{ HDCP_2_2_REP_SEND_ACK, DP_HDCP_2_2_REP_SEND_ACK_OFFSET, false,
-	  0, 0 },
-	{ HDCP_2_2_REP_STREAM_MANAGE,
-	  DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET, false,
-	  0, 0 },
-	{ HDCP_2_2_REP_STREAM_READY, DP_HDCP_2_2_REP_STREAM_READY_OFFSET,
-	  false, HDCP_2_2_STREAM_READY_TIMEOUT_MS, 0 },
-/* local define to shovel this through the write_2_2 interface */
-#define HDCP_2_2_ERRATA_DP_STREAM_TYPE	50
-	{ HDCP_2_2_ERRATA_DP_STREAM_TYPE,
-	  DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, false,
-	  0, 0 },
-};
-
-static int
-intel_dp_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
-			      u8 *rx_status)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	ssize_t ret;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
-			       DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
-			       HDCP_2_2_DP_RXSTATUS_LEN);
-	if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
-		drm_dbg_kms(&i915->drm,
-			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
-		return ret >= 0 ? -EIO : ret;
-	}
-
-	return 0;
-}
-
-static
-int hdcp2_detect_msg_availability(struct intel_digital_port *intel_dig_port,
-				  u8 msg_id, bool *msg_ready)
-{
-	u8 rx_status;
-	int ret;
-
-	*msg_ready = false;
-	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
-	if (ret < 0)
-		return ret;
-
-	switch (msg_id) {
-	case HDCP_2_2_AKE_SEND_HPRIME:
-		if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rx_status))
-			*msg_ready = true;
-		break;
-	case HDCP_2_2_AKE_SEND_PAIRING_INFO:
-		if (HDCP_2_2_DP_RXSTATUS_PAIRING(rx_status))
-			*msg_ready = true;
-		break;
-	case HDCP_2_2_REP_SEND_RECVID_LIST:
-		if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
-			*msg_ready = true;
-		break;
-	default:
-		DRM_ERROR("Unidentified msg_id: %d\n", msg_id);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static ssize_t
-intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
-			    const struct hdcp2_dp_msg_data *hdcp2_msg_data)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	struct intel_dp *dp = &intel_dig_port->dp;
-	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
-	u8 msg_id = hdcp2_msg_data->msg_id;
-	int ret, timeout;
-	bool msg_ready = false;
-
-	if (msg_id == HDCP_2_2_AKE_SEND_HPRIME && !hdcp->is_paired)
-		timeout = hdcp2_msg_data->timeout2;
-	else
-		timeout = hdcp2_msg_data->timeout;
-
-	/*
-	 * There is no way to detect the CERT, LPRIME and STREAM_READY
-	 * availability. So Wait for timeout and read the msg.
-	 */
-	if (!hdcp2_msg_data->msg_detectable) {
-		mdelay(timeout);
-		ret = 0;
-	} else {
-		/*
-		 * As we want to check the msg availability at timeout, Ignoring
-		 * the timeout at wait for CP_IRQ.
-		 */
-		intel_dp_hdcp_wait_for_cp_irq(hdcp, timeout);
-		ret = hdcp2_detect_msg_availability(intel_dig_port,
-						    msg_id, &msg_ready);
-		if (!msg_ready)
-			ret = -ETIMEDOUT;
-	}
-
-	if (ret)
-		drm_dbg_kms(&i915->drm,
-			    "msg_id %d, ret %d, timeout(mSec): %d\n",
-			    hdcp2_msg_data->msg_id, ret, timeout);
-
-	return ret;
-}
-
-static const struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(hdcp2_dp_msg_data); i++)
-		if (hdcp2_dp_msg_data[i].msg_id == msg_id)
-			return &hdcp2_dp_msg_data[i];
-
-	return NULL;
-}
-
-static
-int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
-			     void *buf, size_t size)
-{
-	struct intel_dp *dp = &intel_dig_port->dp;
-	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
-	unsigned int offset;
-	u8 *byte = buf;
-	ssize_t ret, bytes_to_write, len;
-	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
-
-	hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
-	if (!hdcp2_msg_data)
-		return -EINVAL;
-
-	offset = hdcp2_msg_data->offset;
-
-	/* No msg_id in DP HDCP2.2 msgs */
-	bytes_to_write = size - 1;
-	byte++;
-
-	hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count);
-
-	while (bytes_to_write) {
-		len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
-				DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write;
-
-		ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
-					offset, (void *)byte, len);
-		if (ret < 0)
-			return ret;
-
-		bytes_to_write -= ret;
-		byte += ret;
-		offset += ret;
-	}
-
-	return size;
-}
-
-static
-ssize_t get_receiver_id_list_size(struct intel_digital_port *intel_dig_port)
-{
-	u8 rx_info[HDCP_2_2_RXINFO_LEN];
-	u32 dev_cnt;
-	ssize_t ret;
-
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
-			       DP_HDCP_2_2_REG_RXINFO_OFFSET,
-			       (void *)rx_info, HDCP_2_2_RXINFO_LEN);
-	if (ret != HDCP_2_2_RXINFO_LEN)
-		return ret >= 0 ? -EIO : ret;
-
-	dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
-		   HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
-
-	if (dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
-		dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
-
-	ret = sizeof(struct hdcp2_rep_send_receiverid_list) -
-		HDCP_2_2_RECEIVER_IDS_MAX_LEN +
-		(dev_cnt * HDCP_2_2_RECEIVER_ID_LEN);
-
-	return ret;
-}
-
-static
-int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
-			    u8 msg_id, void *buf, size_t size)
-{
-	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	unsigned int offset;
-	u8 *byte = buf;
-	ssize_t ret, bytes_to_recv, len;
-	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
-
-	hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
-	if (!hdcp2_msg_data)
-		return -EINVAL;
-	offset = hdcp2_msg_data->offset;
-
-	ret = intel_dp_hdcp2_wait_for_msg(intel_dig_port, hdcp2_msg_data);
-	if (ret < 0)
-		return ret;
-
-	if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
-		ret = get_receiver_id_list_size(intel_dig_port);
-		if (ret < 0)
-			return ret;
-
-		size = ret;
-	}
-	bytes_to_recv = size - 1;
-
-	/* DP adaptation msgs has no msg_id */
-	byte++;
-
-	while (bytes_to_recv) {
-		len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ?
-		      DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
-
-		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, offset,
-				       (void *)byte, len);
-		if (ret < 0) {
-			drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
-				    msg_id, ret);
-			return ret;
-		}
-
-		bytes_to_recv -= ret;
-		byte += ret;
-		offset += ret;
-	}
-	byte = buf;
-	*byte = msg_id;
-
-	return size;
-}
-
-static
-int intel_dp_hdcp2_config_stream_type(struct intel_digital_port *intel_dig_port,
-				      bool is_repeater, u8 content_type)
-{
-	int ret;
-	struct hdcp2_dp_errata_stream_type stream_type_msg;
-
-	if (is_repeater)
-		return 0;
-
-	/*
-	 * Errata for DP: As Stream type is used for encryption, Receiver
-	 * should be communicated with stream type for the decryption of the
-	 * content.
-	 * Repeater will be communicated with stream type as a part of it's
-	 * auth later in time.
-	 */
-	stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
-	stream_type_msg.stream_type = content_type;
-
-	ret =  intel_dp_hdcp2_write_msg(intel_dig_port, &stream_type_msg,
-					sizeof(stream_type_msg));
-
-	return ret < 0 ? ret : 0;
-
-}
-
-static
-int intel_dp_hdcp2_check_link(struct intel_digital_port *intel_dig_port)
-{
-	u8 rx_status;
-	int ret;
-
-	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
-	if (ret)
-		return ret;
-
-	if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
-		ret = HDCP_REAUTH_REQUEST;
-	else if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
-		ret = HDCP_LINK_INTEGRITY_FAILURE;
-	else if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
-		ret = HDCP_TOPOLOGY_CHANGE;
-
-	return ret;
-}
-
-static
-int intel_dp_hdcp2_capable(struct intel_digital_port *intel_dig_port,
-			   bool *capable)
-{
-	u8 rx_caps[3];
-	int ret;
-
-	*capable = false;
-	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
-			       DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
-			       rx_caps, HDCP_2_2_RXCAPS_LEN);
-	if (ret != HDCP_2_2_RXCAPS_LEN)
-		return ret >= 0 ? -EIO : ret;
-
-	if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
-	    HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2]))
-		*capable = true;
-
-	return 0;
-}
-
-static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
-	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
-	.read_bksv = intel_dp_hdcp_read_bksv,
-	.read_bstatus = intel_dp_hdcp_read_bstatus,
-	.repeater_present = intel_dp_hdcp_repeater_present,
-	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
-	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
-	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
-	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
-	.toggle_signalling = intel_dp_hdcp_toggle_signalling,
-	.check_link = intel_dp_hdcp_check_link,
-	.hdcp_capable = intel_dp_hdcp_capable,
-	.write_2_2_msg = intel_dp_hdcp2_write_msg,
-	.read_2_2_msg = intel_dp_hdcp2_read_msg,
-	.config_stream_type = intel_dp_hdcp2_config_stream_type,
-	.check_2_2_link = intel_dp_hdcp2_check_link,
-	.hdcp_2_2_capable = intel_dp_hdcp2_capable,
-	.protocol = HDCP_PROTOCOL_DP,
-};
-
 static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -8232,7 +7628,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	intel_dp_add_properties(intel_dp, connector);
 
 	if (is_hdcp_supported(dev_priv, port) && !intel_dp_is_edp(intel_dp)) {
-		int ret = intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
+		int ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
 		if (ret)
 			drm_dbg_kms(&dev_priv->drm,
 				    "HDCP init failed, skipping.\n");
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 6352c7e97e3b..794f25573254 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -134,4 +134,7 @@ void intel_ddi_update_pipe(struct intel_atomic_state *state,
 			   const struct intel_crtc_state *crtc_state,
 			   const struct drm_connector_state *conn_state);
 
+int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
+		       struct intel_connector *intel_connector);
+
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
new file mode 100644
index 000000000000..0e06a1066d61
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -0,0 +1,636 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (C) 2020 Google, Inc.
+ *
+ * Authors:
+ * Sean Paul <seanpaul@chromium.org>
+ */
+
+#include <drm/drm_dp_helper.h>
+#include <drm/drm_hdcp.h>
+#include <drm/drm_print.h>
+
+#include "intel_display_types.h"
+#include "intel_dp.h"
+#include "intel_hdcp.h"
+
+static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
+{
+	long ret;
+
+#define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
+	ret = wait_event_interruptible_timeout(hdcp->cp_irq_queue, C,
+					       msecs_to_jiffies(timeout));
+
+	if (!ret)
+		DRM_DEBUG_KMS("Timedout at waiting for CP_IRQ\n");
+}
+
+static
+int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
+				u8 *an)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	u8 aksv[DRM_HDCP_KSV_LEN] = {};
+	ssize_t dpcd_ret;
+
+	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AN,
+				     an, DRM_HDCP_AN_LEN);
+	if (dpcd_ret != DRM_HDCP_AN_LEN) {
+		drm_dbg_kms(&i915->drm,
+			    "Failed to write An over DP/AUX (%zd)\n",
+			    dpcd_ret);
+		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
+	}
+
+	/*
+	 * Since Aksv is Oh-So-Secret, we can't access it in software. So we
+	 * send an empty buffer of the correct length through the DP helpers. On
+	 * the other side, in the transfer hook, we'll generate a flag based on
+	 * the destination address which will tickle the hardware to output the
+	 * Aksv on our behalf after the header is sent.
+	 */
+	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux, DP_AUX_HDCP_AKSV,
+				     aksv, DRM_HDCP_KSV_LEN);
+	if (dpcd_ret != DRM_HDCP_KSV_LEN) {
+		drm_dbg_kms(&i915->drm,
+			    "Failed to write Aksv over DP/AUX (%zd)\n",
+			    dpcd_ret);
+		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
+	}
+	return 0;
+}
+
+static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
+				   u8 *bksv)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
+			       DRM_HDCP_KSV_LEN);
+	if (ret != DRM_HDCP_KSV_LEN) {
+		drm_dbg_kms(&i915->drm,
+			    "Read Bksv from DP/AUX failed (%zd)\n", ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+	return 0;
+}
+
+static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
+				      u8 *bstatus)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+
+	/*
+	 * For some reason the HDMI and DP HDCP specs call this register
+	 * definition by different names. In the HDMI spec, it's called BSTATUS,
+	 * but in DP it's called BINFO.
+	 */
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BINFO,
+			       bstatus, DRM_HDCP_BSTATUS_LEN);
+	if (ret != DRM_HDCP_BSTATUS_LEN) {
+		drm_dbg_kms(&i915->drm,
+			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+	return 0;
+}
+
+static
+int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
+			     u8 *bcaps)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BCAPS,
+			       bcaps, 1);
+	if (ret != 1) {
+		drm_dbg_kms(&i915->drm,
+			    "Read bcaps from DP/AUX failed (%zd)\n", ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+
+	return 0;
+}
+
+static
+int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
+				   bool *repeater_present)
+{
+	ssize_t ret;
+	u8 bcaps;
+
+	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
+	if (ret)
+		return ret;
+
+	*repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT;
+	return 0;
+}
+
+static
+int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
+				u8 *ri_prime)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME,
+			       ri_prime, DRM_HDCP_RI_LEN);
+	if (ret != DRM_HDCP_RI_LEN) {
+		drm_dbg_kms(&i915->drm, "Read Ri' from DP/AUX failed (%zd)\n",
+			    ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+	return 0;
+}
+
+static
+int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
+				 bool *ksv_ready)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+	u8 bstatus;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
+			       &bstatus, 1);
+	if (ret != 1) {
+		drm_dbg_kms(&i915->drm,
+			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+	*ksv_ready = bstatus & DP_BSTATUS_READY;
+	return 0;
+}
+
+static
+int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
+				int num_downstream, u8 *ksv_fifo)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+	int i;
+
+	/* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */
+	for (i = 0; i < num_downstream; i += 3) {
+		size_t len = min(num_downstream - i, 3) * DRM_HDCP_KSV_LEN;
+		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+				       DP_AUX_HDCP_KSV_FIFO,
+				       ksv_fifo + i * DRM_HDCP_KSV_LEN,
+				       len);
+		if (ret != len) {
+			drm_dbg_kms(&i915->drm,
+				    "Read ksv[%d] from DP/AUX failed (%zd)\n",
+				    i, ret);
+			return ret >= 0 ? -EIO : ret;
+		}
+	}
+	return 0;
+}
+
+static
+int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
+				    int i, u32 *part)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+
+	if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
+		return -EINVAL;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+			       DP_AUX_HDCP_V_PRIME(i), part,
+			       DRM_HDCP_V_PRIME_PART_LEN);
+	if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
+		drm_dbg_kms(&i915->drm,
+			    "Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+	return 0;
+}
+
+static
+int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
+				    enum transcoder cpu_transcoder,
+				    bool enable)
+{
+	/* Not used for single stream DisplayPort setups */
+	return 0;
+}
+
+static
+bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+	u8 bstatus;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
+			       &bstatus, 1);
+	if (ret != 1) {
+		drm_dbg_kms(&i915->drm,
+			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
+		return false;
+	}
+
+	return !(bstatus & (DP_BSTATUS_LINK_FAILURE | DP_BSTATUS_REAUTH_REQ));
+}
+
+static
+int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
+			  bool *hdcp_capable)
+{
+	ssize_t ret;
+	u8 bcaps;
+
+	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
+	if (ret)
+		return ret;
+
+	*hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE;
+	return 0;
+}
+
+struct hdcp2_dp_errata_stream_type {
+	u8	msg_id;
+	u8	stream_type;
+} __packed;
+
+struct hdcp2_dp_msg_data {
+	u8 msg_id;
+	u32 offset;
+	bool msg_detectable;
+	u32 timeout;
+	u32 timeout2; /* Added for non_paired situation */
+};
+
+static const struct hdcp2_dp_msg_data hdcp2_dp_msg_data[] = {
+	{ HDCP_2_2_AKE_INIT, DP_HDCP_2_2_AKE_INIT_OFFSET, false, 0, 0 },
+	{ HDCP_2_2_AKE_SEND_CERT, DP_HDCP_2_2_AKE_SEND_CERT_OFFSET,
+	  false, HDCP_2_2_CERT_TIMEOUT_MS, 0 },
+	{ HDCP_2_2_AKE_NO_STORED_KM, DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET,
+	  false, 0, 0 },
+	{ HDCP_2_2_AKE_STORED_KM, DP_HDCP_2_2_AKE_STORED_KM_OFFSET,
+	  false, 0, 0 },
+	{ HDCP_2_2_AKE_SEND_HPRIME, DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET,
+	  true, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
+	  HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS },
+	{ HDCP_2_2_AKE_SEND_PAIRING_INFO,
+	  DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET, true,
+	  HDCP_2_2_PAIRING_TIMEOUT_MS, 0 },
+	{ HDCP_2_2_LC_INIT, DP_HDCP_2_2_LC_INIT_OFFSET, false, 0, 0 },
+	{ HDCP_2_2_LC_SEND_LPRIME, DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET,
+	  false, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, 0 },
+	{ HDCP_2_2_SKE_SEND_EKS, DP_HDCP_2_2_SKE_SEND_EKS_OFFSET, false,
+	  0, 0 },
+	{ HDCP_2_2_REP_SEND_RECVID_LIST,
+	  DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET, true,
+	  HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0 },
+	{ HDCP_2_2_REP_SEND_ACK, DP_HDCP_2_2_REP_SEND_ACK_OFFSET, false,
+	  0, 0 },
+	{ HDCP_2_2_REP_STREAM_MANAGE,
+	  DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET, false,
+	  0, 0 },
+	{ HDCP_2_2_REP_STREAM_READY, DP_HDCP_2_2_REP_STREAM_READY_OFFSET,
+	  false, HDCP_2_2_STREAM_READY_TIMEOUT_MS, 0 },
+/* local define to shovel this through the write_2_2 interface */
+#define HDCP_2_2_ERRATA_DP_STREAM_TYPE	50
+	{ HDCP_2_2_ERRATA_DP_STREAM_TYPE,
+	  DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, false,
+	  0, 0 },
+};
+
+static int
+intel_dp_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
+			      u8 *rx_status)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	ssize_t ret;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+			       DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
+			       HDCP_2_2_DP_RXSTATUS_LEN);
+	if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
+		drm_dbg_kms(&i915->drm,
+			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
+		return ret >= 0 ? -EIO : ret;
+	}
+
+	return 0;
+}
+
+static
+int hdcp2_detect_msg_availability(struct intel_digital_port *intel_dig_port,
+				  u8 msg_id, bool *msg_ready)
+{
+	u8 rx_status;
+	int ret;
+
+	*msg_ready = false;
+	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
+	if (ret < 0)
+		return ret;
+
+	switch (msg_id) {
+	case HDCP_2_2_AKE_SEND_HPRIME:
+		if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rx_status))
+			*msg_ready = true;
+		break;
+	case HDCP_2_2_AKE_SEND_PAIRING_INFO:
+		if (HDCP_2_2_DP_RXSTATUS_PAIRING(rx_status))
+			*msg_ready = true;
+		break;
+	case HDCP_2_2_REP_SEND_RECVID_LIST:
+		if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
+			*msg_ready = true;
+		break;
+	default:
+		DRM_ERROR("Unidentified msg_id: %d\n", msg_id);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static ssize_t
+intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
+			    const struct hdcp2_dp_msg_data *hdcp2_msg_data)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	struct intel_dp *dp = &intel_dig_port->dp;
+	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
+	u8 msg_id = hdcp2_msg_data->msg_id;
+	int ret, timeout;
+	bool msg_ready = false;
+
+	if (msg_id == HDCP_2_2_AKE_SEND_HPRIME && !hdcp->is_paired)
+		timeout = hdcp2_msg_data->timeout2;
+	else
+		timeout = hdcp2_msg_data->timeout;
+
+	/*
+	 * There is no way to detect the CERT, LPRIME and STREAM_READY
+	 * availability. So Wait for timeout and read the msg.
+	 */
+	if (!hdcp2_msg_data->msg_detectable) {
+		mdelay(timeout);
+		ret = 0;
+	} else {
+		/*
+		 * As we want to check the msg availability at timeout, Ignoring
+		 * the timeout at wait for CP_IRQ.
+		 */
+		intel_dp_hdcp_wait_for_cp_irq(hdcp, timeout);
+		ret = hdcp2_detect_msg_availability(intel_dig_port,
+						    msg_id, &msg_ready);
+		if (!msg_ready)
+			ret = -ETIMEDOUT;
+	}
+
+	if (ret)
+		drm_dbg_kms(&i915->drm,
+			    "msg_id %d, ret %d, timeout(mSec): %d\n",
+			    hdcp2_msg_data->msg_id, ret, timeout);
+
+	return ret;
+}
+
+static const struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hdcp2_dp_msg_data); i++)
+		if (hdcp2_dp_msg_data[i].msg_id == msg_id)
+			return &hdcp2_dp_msg_data[i];
+
+	return NULL;
+}
+
+static
+int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
+			     void *buf, size_t size)
+{
+	struct intel_dp *dp = &intel_dig_port->dp;
+	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
+	unsigned int offset;
+	u8 *byte = buf;
+	ssize_t ret, bytes_to_write, len;
+	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
+
+	hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
+	if (!hdcp2_msg_data)
+		return -EINVAL;
+
+	offset = hdcp2_msg_data->offset;
+
+	/* No msg_id in DP HDCP2.2 msgs */
+	bytes_to_write = size - 1;
+	byte++;
+
+	hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count);
+
+	while (bytes_to_write) {
+		len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
+				DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write;
+
+		ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
+					offset, (void *)byte, len);
+		if (ret < 0)
+			return ret;
+
+		bytes_to_write -= ret;
+		byte += ret;
+		offset += ret;
+	}
+
+	return size;
+}
+
+static
+ssize_t get_receiver_id_list_size(struct intel_digital_port *intel_dig_port)
+{
+	u8 rx_info[HDCP_2_2_RXINFO_LEN];
+	u32 dev_cnt;
+	ssize_t ret;
+
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+			       DP_HDCP_2_2_REG_RXINFO_OFFSET,
+			       (void *)rx_info, HDCP_2_2_RXINFO_LEN);
+	if (ret != HDCP_2_2_RXINFO_LEN)
+		return ret >= 0 ? -EIO : ret;
+
+	dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
+		   HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
+
+	if (dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
+		dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
+
+	ret = sizeof(struct hdcp2_rep_send_receiverid_list) -
+		HDCP_2_2_RECEIVER_IDS_MAX_LEN +
+		(dev_cnt * HDCP_2_2_RECEIVER_ID_LEN);
+
+	return ret;
+}
+
+static
+int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
+			    u8 msg_id, void *buf, size_t size)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	unsigned int offset;
+	u8 *byte = buf;
+	ssize_t ret, bytes_to_recv, len;
+	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
+
+	hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
+	if (!hdcp2_msg_data)
+		return -EINVAL;
+	offset = hdcp2_msg_data->offset;
+
+	ret = intel_dp_hdcp2_wait_for_msg(intel_dig_port, hdcp2_msg_data);
+	if (ret < 0)
+		return ret;
+
+	if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
+		ret = get_receiver_id_list_size(intel_dig_port);
+		if (ret < 0)
+			return ret;
+
+		size = ret;
+	}
+	bytes_to_recv = size - 1;
+
+	/* DP adaptation msgs has no msg_id */
+	byte++;
+
+	while (bytes_to_recv) {
+		len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ?
+		      DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
+
+		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, offset,
+				       (void *)byte, len);
+		if (ret < 0) {
+			drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
+				    msg_id, ret);
+			return ret;
+		}
+
+		bytes_to_recv -= ret;
+		byte += ret;
+		offset += ret;
+	}
+	byte = buf;
+	*byte = msg_id;
+
+	return size;
+}
+
+static
+int intel_dp_hdcp2_config_stream_type(struct intel_digital_port *intel_dig_port,
+				      bool is_repeater, u8 content_type)
+{
+	int ret;
+	struct hdcp2_dp_errata_stream_type stream_type_msg;
+
+	if (is_repeater)
+		return 0;
+
+	/*
+	 * Errata for DP: As Stream type is used for encryption, Receiver
+	 * should be communicated with stream type for the decryption of the
+	 * content.
+	 * Repeater will be communicated with stream type as a part of it's
+	 * auth later in time.
+	 */
+	stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
+	stream_type_msg.stream_type = content_type;
+
+	ret =  intel_dp_hdcp2_write_msg(intel_dig_port, &stream_type_msg,
+					sizeof(stream_type_msg));
+
+	return ret < 0 ? ret : 0;
+
+}
+
+static
+int intel_dp_hdcp2_check_link(struct intel_digital_port *intel_dig_port)
+{
+	u8 rx_status;
+	int ret;
+
+	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
+	if (ret)
+		return ret;
+
+	if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
+		ret = HDCP_REAUTH_REQUEST;
+	else if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
+		ret = HDCP_LINK_INTEGRITY_FAILURE;
+	else if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
+		ret = HDCP_TOPOLOGY_CHANGE;
+
+	return ret;
+}
+
+static
+int intel_dp_hdcp2_capable(struct intel_digital_port *intel_dig_port,
+			   bool *capable)
+{
+	u8 rx_caps[3];
+	int ret;
+
+	*capable = false;
+	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
+			       DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
+			       rx_caps, HDCP_2_2_RXCAPS_LEN);
+	if (ret != HDCP_2_2_RXCAPS_LEN)
+		return ret >= 0 ? -EIO : ret;
+
+	if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
+	    HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2]))
+		*capable = true;
+
+	return 0;
+}
+
+static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
+	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
+	.read_bksv = intel_dp_hdcp_read_bksv,
+	.read_bstatus = intel_dp_hdcp_read_bstatus,
+	.repeater_present = intel_dp_hdcp_repeater_present,
+	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
+	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
+	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
+	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
+	.toggle_signalling = intel_dp_hdcp_toggle_signalling,
+	.check_link = intel_dp_hdcp_check_link,
+	.hdcp_capable = intel_dp_hdcp_capable,
+	.write_2_2_msg = intel_dp_hdcp2_write_msg,
+	.read_2_2_msg = intel_dp_hdcp2_read_msg,
+	.config_stream_type = intel_dp_hdcp2_config_stream_type,
+	.check_2_2_link = intel_dp_hdcp2_check_link,
+	.hdcp_2_2_capable = intel_dp_hdcp2_capable,
+	.protocol = HDCP_PROTOCOL_DP,
+};
+
+int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
+		       struct intel_connector *intel_connector)
+{
+	struct drm_device *dev = intel_connector->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	enum port port = intel_encoder->port;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+
+	if (!is_hdcp_supported(dev_priv, port))
+		return 0;
+
+	if (!intel_dp_is_edp(intel_dp))
+		return intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
+
+	return 0;
+}
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 13/17] drm/i915: Plumb port through hdcp init
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:59   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

This patch plumbs port through hdcp init instead of relying on
intel_attached_encoder() to return a non-NULL encoder which won't work
for MST connectors.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-13-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-13-sean@poorly.run #v6

Changes in v5:
-Added to the set
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c |  3 ++-
 drivers/gpu/drm/i915/display/intel_hdcp.c    | 11 ++++++-----
 drivers/gpu/drm/i915/display/intel_hdcp.h    |  2 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c    |  2 +-
 4 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
index 0e06a1066d61..e26a45f880cb 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -630,7 +630,8 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
 		return 0;
 
 	if (!intel_dp_is_edp(intel_dp))
-		return intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
+		return intel_hdcp_init(intel_connector, port,
+				       &intel_dp_hdcp_shim);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 5679877c6b4c..d79d4142aea7 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -1955,6 +1955,7 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum transcoder cpu_transcoder)
 }
 
 static int initialize_hdcp_port_data(struct intel_connector *connector,
+				     enum port port,
 				     const struct intel_hdcp_shim *shim)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -1962,8 +1963,7 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
 	struct hdcp_port_data *data = &hdcp->port_data;
 
 	if (INTEL_GEN(dev_priv) < 12)
-		data->fw_ddi =
-			intel_get_mei_fw_ddi_index(intel_attached_encoder(connector)->port);
+		data->fw_ddi = intel_get_mei_fw_ddi_index(port);
 	else
 		/*
 		 * As per ME FW API expectation, for GEN 12+, fw_ddi is filled
@@ -2033,14 +2033,14 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
 	}
 }
 
-static void intel_hdcp2_init(struct intel_connector *connector,
+static void intel_hdcp2_init(struct intel_connector *connector, enum port port,
 			     const struct intel_hdcp_shim *shim)
 {
 	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	int ret;
 
-	ret = initialize_hdcp_port_data(connector, shim);
+	ret = initialize_hdcp_port_data(connector, port, shim);
 	if (ret) {
 		drm_dbg_kms(&i915->drm, "Mei hdcp data init failed\n");
 		return;
@@ -2050,6 +2050,7 @@ static void intel_hdcp2_init(struct intel_connector *connector,
 }
 
 int intel_hdcp_init(struct intel_connector *connector,
+		    enum port port,
 		    const struct intel_hdcp_shim *shim)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -2060,7 +2061,7 @@ int intel_hdcp_init(struct intel_connector *connector,
 		return -EINVAL;
 
 	if (is_hdcp2_supported(dev_priv))
-		intel_hdcp2_init(connector, shim);
+		intel_hdcp2_init(connector, port, shim);
 
 	ret =
 	drm_connector_attach_content_protection_property(&connector->base,
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h
index 86bbaec120cc..1bbf5b67ed0a 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.h
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.h
@@ -22,7 +22,7 @@ enum transcoder;
 void intel_hdcp_atomic_check(struct drm_connector *connector,
 			     struct drm_connector_state *old_state,
 			     struct drm_connector_state *new_state);
-int intel_hdcp_init(struct intel_connector *connector,
+int intel_hdcp_init(struct intel_connector *connector, enum port port,
 		    const struct intel_hdcp_shim *hdcp_shim);
 int intel_hdcp_enable(struct intel_connector *connector,
 		      enum transcoder cpu_transcoder, u8 content_type);
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index a59acfff456e..ca71ee3dd1c7 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -3260,7 +3260,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 	intel_hdmi->attached_connector = intel_connector;
 
 	if (is_hdcp_supported(dev_priv, port)) {
-		int ret = intel_hdcp_init(intel_connector,
+		int ret = intel_hdcp_init(intel_connector, port,
 					  &intel_hdmi_hdcp_shim);
 		if (ret)
 			drm_dbg_kms(&dev_priv->drm,
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 13/17] drm/i915: Plumb port through hdcp init
@ 2020-06-23 15:59   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

This patch plumbs port through hdcp init instead of relying on
intel_attached_encoder() to return a non-NULL encoder which won't work
for MST connectors.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-13-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-13-sean@poorly.run #v6

Changes in v5:
-Added to the set
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c |  3 ++-
 drivers/gpu/drm/i915/display/intel_hdcp.c    | 11 ++++++-----
 drivers/gpu/drm/i915/display/intel_hdcp.h    |  2 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c    |  2 +-
 4 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
index 0e06a1066d61..e26a45f880cb 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -630,7 +630,8 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
 		return 0;
 
 	if (!intel_dp_is_edp(intel_dp))
-		return intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
+		return intel_hdcp_init(intel_connector, port,
+				       &intel_dp_hdcp_shim);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 5679877c6b4c..d79d4142aea7 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -1955,6 +1955,7 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum transcoder cpu_transcoder)
 }
 
 static int initialize_hdcp_port_data(struct intel_connector *connector,
+				     enum port port,
 				     const struct intel_hdcp_shim *shim)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -1962,8 +1963,7 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
 	struct hdcp_port_data *data = &hdcp->port_data;
 
 	if (INTEL_GEN(dev_priv) < 12)
-		data->fw_ddi =
-			intel_get_mei_fw_ddi_index(intel_attached_encoder(connector)->port);
+		data->fw_ddi = intel_get_mei_fw_ddi_index(port);
 	else
 		/*
 		 * As per ME FW API expectation, for GEN 12+, fw_ddi is filled
@@ -2033,14 +2033,14 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
 	}
 }
 
-static void intel_hdcp2_init(struct intel_connector *connector,
+static void intel_hdcp2_init(struct intel_connector *connector, enum port port,
 			     const struct intel_hdcp_shim *shim)
 {
 	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	int ret;
 
-	ret = initialize_hdcp_port_data(connector, shim);
+	ret = initialize_hdcp_port_data(connector, port, shim);
 	if (ret) {
 		drm_dbg_kms(&i915->drm, "Mei hdcp data init failed\n");
 		return;
@@ -2050,6 +2050,7 @@ static void intel_hdcp2_init(struct intel_connector *connector,
 }
 
 int intel_hdcp_init(struct intel_connector *connector,
+		    enum port port,
 		    const struct intel_hdcp_shim *shim)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -2060,7 +2061,7 @@ int intel_hdcp_init(struct intel_connector *connector,
 		return -EINVAL;
 
 	if (is_hdcp2_supported(dev_priv))
-		intel_hdcp2_init(connector, shim);
+		intel_hdcp2_init(connector, port, shim);
 
 	ret =
 	drm_connector_attach_content_protection_property(&connector->base,
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h
index 86bbaec120cc..1bbf5b67ed0a 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.h
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.h
@@ -22,7 +22,7 @@ enum transcoder;
 void intel_hdcp_atomic_check(struct drm_connector *connector,
 			     struct drm_connector_state *old_state,
 			     struct drm_connector_state *new_state);
-int intel_hdcp_init(struct intel_connector *connector,
+int intel_hdcp_init(struct intel_connector *connector, enum port port,
 		    const struct intel_hdcp_shim *hdcp_shim);
 int intel_hdcp_enable(struct intel_connector *connector,
 		      enum transcoder cpu_transcoder, u8 content_type);
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index a59acfff456e..ca71ee3dd1c7 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -3260,7 +3260,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 	intel_hdmi->attached_connector = intel_connector;
 
 	if (is_hdcp_supported(dev_priv, port)) {
-		int ret = intel_hdcp_init(intel_connector,
+		int ret = intel_hdcp_init(intel_connector, port,
 					  &intel_hdmi_hdcp_shim);
 		if (ret)
 			drm_dbg_kms(&dev_priv->drm,
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 14/17] drm/i915: Add connector to hdcp_shim->check_link()
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:59   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

Currently we derive the connector from digital port in check_link(). For
MST, this isn't sufficient since the digital port passed into the
function can have multiple connectors downstream. This patch adds
connector to the check_link() arguments so we have it when we need it.

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-13-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-14-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-14-sean@poorly.run #v6

Changes in v4:
-Added to the set
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_display_types.h | 3 ++-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c       | 3 ++-
 drivers/gpu/drm/i915/display/intel_hdcp.c          | 2 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c          | 5 ++---
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 811085ef3fba..94211b8fc159 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -318,7 +318,8 @@ struct intel_hdcp_shim {
 				 bool enable);
 
 	/* Ensures the link is still protected */
-	bool (*check_link)(struct intel_digital_port *intel_dig_port);
+	bool (*check_link)(struct intel_digital_port *intel_dig_port,
+			   struct intel_connector *connector);
 
 	/* Detects panel's hdcp capability. This is optional for HDMI. */
 	int (*hdcp_capable)(struct intel_digital_port *intel_dig_port,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
index e26a45f880cb..43446a6cae8d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -223,7 +223,8 @@ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
 }
 
 static
-bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
+bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port,
+			      struct intel_connector *connector)
 {
 	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	ssize_t ret;
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index d79d4142aea7..6bd0e4616ee1 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -953,7 +953,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 		goto out;
 	}
 
-	if (hdcp->shim->check_link(intel_dig_port)) {
+	if (hdcp->shim->check_link(intel_dig_port, connector)) {
 		if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
 			intel_hdcp_update_value(connector,
 				DRM_MODE_CONTENT_PROTECTION_ENABLED, true);
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index ca71ee3dd1c7..b12f1af0611d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -1546,11 +1546,10 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
 }
 
 static
-bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port)
+bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port,
+				struct intel_connector *connector)
 {
 	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	struct intel_connector *connector =
-		intel_dig_port->hdmi.attached_connector;
 	enum port port = intel_dig_port->base.port;
 	enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder;
 	int ret;
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 14/17] drm/i915: Add connector to hdcp_shim->check_link()
@ 2020-06-23 15:59   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

Currently we derive the connector from digital port in check_link(). For
MST, this isn't sufficient since the digital port passed into the
function can have multiple connectors downstream. This patch adds
connector to the check_link() arguments so we have it when we need it.

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-13-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-14-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-14-sean@poorly.run #v6

Changes in v4:
-Added to the set
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-None
---
 drivers/gpu/drm/i915/display/intel_display_types.h | 3 ++-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c       | 3 ++-
 drivers/gpu/drm/i915/display/intel_hdcp.c          | 2 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c          | 5 ++---
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 811085ef3fba..94211b8fc159 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -318,7 +318,8 @@ struct intel_hdcp_shim {
 				 bool enable);
 
 	/* Ensures the link is still protected */
-	bool (*check_link)(struct intel_digital_port *intel_dig_port);
+	bool (*check_link)(struct intel_digital_port *intel_dig_port,
+			   struct intel_connector *connector);
 
 	/* Detects panel's hdcp capability. This is optional for HDMI. */
 	int (*hdcp_capable)(struct intel_digital_port *intel_dig_port,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
index e26a45f880cb..43446a6cae8d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -223,7 +223,8 @@ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
 }
 
 static
-bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
+bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port,
+			      struct intel_connector *connector)
 {
 	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
 	ssize_t ret;
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index d79d4142aea7..6bd0e4616ee1 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -953,7 +953,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 		goto out;
 	}
 
-	if (hdcp->shim->check_link(intel_dig_port)) {
+	if (hdcp->shim->check_link(intel_dig_port, connector)) {
 		if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
 			intel_hdcp_update_value(connector,
 				DRM_MODE_CONTENT_PROTECTION_ENABLED, true);
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index ca71ee3dd1c7..b12f1af0611d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -1546,11 +1546,10 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
 }
 
 static
-bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port)
+bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port,
+				struct intel_connector *connector)
 {
 	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
-	struct intel_connector *connector =
-		intel_dig_port->hdmi.attached_connector;
 	enum port port = intel_dig_port->base.port;
 	enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder;
 	int ret;
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:59   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

Used to query whether an MST stream is encrypted or not.

Signed-off-by: Sean Paul <seanpaul@chromium.org>

Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6

Changes in v4:
-Added to the set
Changes in v5:
-None
Changes in v6:
-Use FIELD_PREP to generate request buffer bitfields (Lyude)
-Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
Changes in v7:
-None
---
 drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
 .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
 include/drm/drm_dp_helper.h                   |   3 +
 include/drm/drm_dp_mst_helper.h               |  44 ++++++
 4 files changed, 206 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index b2f5a84b4cfb..fc68478eaeb4 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -20,11 +20,13 @@
  * OF THIS SOFTWARE.
  */
 
+#include <linux/bitfield.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/iopoll.h>
@@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
 		memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
 		idx += req->u.i2c_write.num_bytes;
 		break;
+	case DP_QUERY_STREAM_ENC_STATUS: {
+		const struct drm_dp_query_stream_enc_status *msg;
+
+		msg = &req->u.enc_status;
+		buf[idx] = msg->stream_id;
+		idx++;
+		memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
+		idx += sizeof(msg->client_id);
+		buf[idx] = 0;
+		buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
+		buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
+		buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
+		buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
+		idx++;
+		}
+		break;
 	}
 	raw->cur_len = idx;
 }
@@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
 				return -ENOMEM;
 		}
 		break;
+	case DP_QUERY_STREAM_ENC_STATUS:
+		req->u.enc_status.stream_id = buf[idx++];
+		for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
+			req->u.enc_status.client_id[i] = buf[idx++];
+
+		req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
+							   buf[idx]);
+		req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
+							 	 buf[idx]);
+		req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
+							      buf[idx]);
+		req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
+								    buf[idx]);
+		break;
 	}
 
 	return 0;
@@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
 		  req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
 		  req->u.i2c_write.bytes);
 		break;
+	case DP_QUERY_STREAM_ENC_STATUS:
+		P("stream_id=%u client_id=%*ph stream_event=%x "
+		  "valid_event=%d stream_behavior=%x valid_behavior=%d",
+		  req->u.enc_status.stream_id,
+		  (int)ARRAY_SIZE(req->u.enc_status.client_id),
+		  req->u.enc_status.client_id, req->u.enc_status.stream_event,
+		  req->u.enc_status.valid_stream_event,
+		  req->u.enc_status.stream_behavior,
+		  req->u.enc_status.valid_stream_behavior);
+		break;
 	default:
 		P("???\n");
 		break;
@@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
 	return true;
 }
 
+static bool
+drm_dp_sideband_parse_query_stream_enc_status(
+				struct drm_dp_sideband_msg_rx *raw,
+				struct drm_dp_sideband_msg_reply_body *repmsg)
+{
+	struct drm_dp_query_stream_enc_status_ack_reply *reply;
+
+	reply = &repmsg->u.enc_status;
+
+	reply->stream_id = raw->msg[3];
+
+	reply->reply_signed = raw->msg[2] & BIT(0);
+
+	reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
+	reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
+
+	reply->query_capable_device_present = raw->msg[2] & BIT(5);
+	reply->legacy_device_present = raw->msg[2] & BIT(6);
+	reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
+
+	reply->auth_completed = !!(raw->msg[1] & BIT(3));
+	reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
+	reply->repeater_present = !!(raw->msg[1] & BIT(5));
+	reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
+
+	return true;
+}
+
 static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
 					struct drm_dp_sideband_msg_reply_body *msg)
 {
@@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
 		return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
 	case DP_CLEAR_PAYLOAD_ID_TABLE:
 		return true; /* since there's nothing to parse */
+	case DP_QUERY_STREAM_ENC_STATUS:
+		return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
 	default:
 		DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
 			  drm_dp_mst_req_type_str(msg->req_type));
@@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
 	msg->path_msg = true;
 }
 
+static int
+build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
+			      u8 *q_id)
+{
+	struct drm_dp_sideband_msg_req_body req;
+
+	req.req_type = DP_QUERY_STREAM_ENC_STATUS;
+	req.u.enc_status.stream_id = stream_id;
+	memcpy(req.u.enc_status.client_id, q_id,
+	       sizeof(req.u.enc_status.client_id));
+	req.u.enc_status.stream_event = 0;
+	req.u.enc_status.valid_stream_event = false;
+	req.u.enc_status.stream_behavior = 0;
+	req.u.enc_status.valid_stream_behavior = false;
+
+	drm_dp_encode_sideband_req(&req, msg);
+	return 0;
+}
+
 static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
 					struct drm_dp_vcpi *vcpi)
 {
@@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
 }
 EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
 
+int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
+		struct drm_dp_mst_port *port,
+		struct drm_dp_query_stream_enc_status_ack_reply *status)
+{
+	struct drm_dp_sideband_msg_tx *txmsg;
+	u8 nonce[7];
+	int len, ret;
+
+	txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
+	if (!txmsg)
+		return -ENOMEM;
+
+	port = drm_dp_mst_topology_get_port_validated(mgr, port);
+	if (!port) {
+		ret = -EINVAL;
+		goto out_get_port;
+	}
+
+	get_random_bytes(nonce, sizeof(nonce));
+
+	/*
+	 * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
+	 *  transaction at the MST Branch device directly connected to the
+	 *  Source"
+	 */
+	txmsg->dst = mgr->mst_primary;
+
+	len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
+
+	drm_dp_queue_down_tx(mgr, txmsg);
+
+	ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
+	if (ret < 0) {
+		goto out;
+	} else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
+		DRM_DEBUG_KMS("query encryption status nak received\n");
+		ret = -ENXIO;
+		goto out;
+	}
+
+	ret = 0;
+	memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
+
+out:
+	drm_dp_mst_topology_put_port(port);
+out_get_port:
+	kfree(txmsg);
+	return ret;
+}
+EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
+
 static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
 				       int id,
 				       struct drm_dp_payload *payload)
diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
index bd990d178765..1d696ec001cf 100644
--- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
+++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
@@ -5,6 +5,8 @@
 
 #define PREFIX_STR "[drm_dp_mst_helper]"
 
+#include <linux/random.h>
+
 #include <drm/drm_dp_mst_helper.h>
 #include <drm/drm_print.h>
 
@@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
 	in.u.i2c_write.bytes = data;
 	DO_TEST();
 
+	in.req_type = DP_QUERY_STREAM_ENC_STATUS;
+	in.u.enc_status.stream_id = 1;
+	DO_TEST();
+	get_random_bytes(in.u.enc_status.client_id,
+			 sizeof(in.u.enc_status.client_id));
+	DO_TEST();
+	in.u.enc_status.stream_event = 3;
+	DO_TEST();
+	in.u.enc_status.valid_stream_event = 0;
+	DO_TEST();
+	in.u.enc_status.stream_behavior = 3;
+	DO_TEST();
+	in.u.enc_status.valid_stream_behavior = 1;
+	DO_TEST();
+
 #undef DO_TEST
 	return 0;
 }
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index e47dc22ebf50..e2d2df5e869e 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1108,6 +1108,9 @@
 #define DP_POWER_DOWN_PHY		0x25
 #define DP_SINK_EVENT_NOTIFY		0x30
 #define DP_QUERY_STREAM_ENC_STATUS	0x38
+#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST	0
+#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE	1
+#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE	2
 
 /* DP 1.2 MST sideband reply types */
 #define DP_SIDEBAND_REPLY_ACK		0x00
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 8b9eb4db3381..371eef8798ad 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
 	u8 port_number;
 };
 
+struct drm_dp_query_stream_enc_status_ack_reply {
+	/* Bit[23:16]- Stream Id */
+	u8 stream_id;
+
+	/* Bit[15]- Signed */
+	bool reply_signed;
+
+	/* Bit[10:8]- Stream Output Sink Type */
+	bool unauthorizable_device_present;
+	bool legacy_device_present;
+	bool query_capable_device_present;
+
+	/* Bit[12:11]- Stream Output CP Type */
+	bool hdcp_1x_device_present;
+	bool hdcp_2x_device_present;
+
+	/* Bit[4]- Stream Authentication */
+	bool auth_completed;
+
+	/* Bit[3]- Stream Encryption */
+	bool encryption_enabled;
+
+	/* Bit[2]- Stream Repeater Function Present */
+	bool repeater_present;
+
+	/* Bit[1:0]- Stream State */
+	u8 state;
+};
 
 #define DRM_DP_MAX_SDP_STREAMS 16
 struct drm_dp_allocate_payload {
@@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
 	u8 *bytes;
 };
 
+struct drm_dp_query_stream_enc_status {
+	u8 stream_id;
+	u8 client_id[7];	/* 56-bit nonce */
+	u8 stream_event;
+	bool valid_stream_event;
+	u8 stream_behavior;
+	u8 valid_stream_behavior;
+};
+
 /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
 struct drm_dp_port_number_req {
 	u8 port_number;
@@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
 
 		struct drm_dp_remote_i2c_read i2c_read;
 		struct drm_dp_remote_i2c_write i2c_write;
+
+		struct drm_dp_query_stream_enc_status enc_status;
 	} u;
 };
 
@@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
 		struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
 		struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
 		struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
+
+		struct drm_dp_query_stream_enc_status_ack_reply enc_status;
 	} u;
 };
 
@@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
 				 struct drm_dp_mst_port *port);
 int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
 				 struct drm_dp_mst_port *port, bool power_up);
+int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
+		struct drm_dp_mst_port *port,
+		struct drm_dp_query_stream_enc_status_ack_reply *status);
 int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
 
 void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
@ 2020-06-23 15:59   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

Used to query whether an MST stream is encrypted or not.

Signed-off-by: Sean Paul <seanpaul@chromium.org>

Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6

Changes in v4:
-Added to the set
Changes in v5:
-None
Changes in v6:
-Use FIELD_PREP to generate request buffer bitfields (Lyude)
-Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
Changes in v7:
-None
---
 drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
 .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
 include/drm/drm_dp_helper.h                   |   3 +
 include/drm/drm_dp_mst_helper.h               |  44 ++++++
 4 files changed, 206 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index b2f5a84b4cfb..fc68478eaeb4 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -20,11 +20,13 @@
  * OF THIS SOFTWARE.
  */
 
+#include <linux/bitfield.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/iopoll.h>
@@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
 		memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
 		idx += req->u.i2c_write.num_bytes;
 		break;
+	case DP_QUERY_STREAM_ENC_STATUS: {
+		const struct drm_dp_query_stream_enc_status *msg;
+
+		msg = &req->u.enc_status;
+		buf[idx] = msg->stream_id;
+		idx++;
+		memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
+		idx += sizeof(msg->client_id);
+		buf[idx] = 0;
+		buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
+		buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
+		buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
+		buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
+		idx++;
+		}
+		break;
 	}
 	raw->cur_len = idx;
 }
@@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
 				return -ENOMEM;
 		}
 		break;
+	case DP_QUERY_STREAM_ENC_STATUS:
+		req->u.enc_status.stream_id = buf[idx++];
+		for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
+			req->u.enc_status.client_id[i] = buf[idx++];
+
+		req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
+							   buf[idx]);
+		req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
+							 	 buf[idx]);
+		req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
+							      buf[idx]);
+		req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
+								    buf[idx]);
+		break;
 	}
 
 	return 0;
@@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
 		  req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
 		  req->u.i2c_write.bytes);
 		break;
+	case DP_QUERY_STREAM_ENC_STATUS:
+		P("stream_id=%u client_id=%*ph stream_event=%x "
+		  "valid_event=%d stream_behavior=%x valid_behavior=%d",
+		  req->u.enc_status.stream_id,
+		  (int)ARRAY_SIZE(req->u.enc_status.client_id),
+		  req->u.enc_status.client_id, req->u.enc_status.stream_event,
+		  req->u.enc_status.valid_stream_event,
+		  req->u.enc_status.stream_behavior,
+		  req->u.enc_status.valid_stream_behavior);
+		break;
 	default:
 		P("???\n");
 		break;
@@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
 	return true;
 }
 
+static bool
+drm_dp_sideband_parse_query_stream_enc_status(
+				struct drm_dp_sideband_msg_rx *raw,
+				struct drm_dp_sideband_msg_reply_body *repmsg)
+{
+	struct drm_dp_query_stream_enc_status_ack_reply *reply;
+
+	reply = &repmsg->u.enc_status;
+
+	reply->stream_id = raw->msg[3];
+
+	reply->reply_signed = raw->msg[2] & BIT(0);
+
+	reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
+	reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
+
+	reply->query_capable_device_present = raw->msg[2] & BIT(5);
+	reply->legacy_device_present = raw->msg[2] & BIT(6);
+	reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
+
+	reply->auth_completed = !!(raw->msg[1] & BIT(3));
+	reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
+	reply->repeater_present = !!(raw->msg[1] & BIT(5));
+	reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
+
+	return true;
+}
+
 static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
 					struct drm_dp_sideband_msg_reply_body *msg)
 {
@@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
 		return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
 	case DP_CLEAR_PAYLOAD_ID_TABLE:
 		return true; /* since there's nothing to parse */
+	case DP_QUERY_STREAM_ENC_STATUS:
+		return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
 	default:
 		DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
 			  drm_dp_mst_req_type_str(msg->req_type));
@@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
 	msg->path_msg = true;
 }
 
+static int
+build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
+			      u8 *q_id)
+{
+	struct drm_dp_sideband_msg_req_body req;
+
+	req.req_type = DP_QUERY_STREAM_ENC_STATUS;
+	req.u.enc_status.stream_id = stream_id;
+	memcpy(req.u.enc_status.client_id, q_id,
+	       sizeof(req.u.enc_status.client_id));
+	req.u.enc_status.stream_event = 0;
+	req.u.enc_status.valid_stream_event = false;
+	req.u.enc_status.stream_behavior = 0;
+	req.u.enc_status.valid_stream_behavior = false;
+
+	drm_dp_encode_sideband_req(&req, msg);
+	return 0;
+}
+
 static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
 					struct drm_dp_vcpi *vcpi)
 {
@@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
 }
 EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
 
+int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
+		struct drm_dp_mst_port *port,
+		struct drm_dp_query_stream_enc_status_ack_reply *status)
+{
+	struct drm_dp_sideband_msg_tx *txmsg;
+	u8 nonce[7];
+	int len, ret;
+
+	txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
+	if (!txmsg)
+		return -ENOMEM;
+
+	port = drm_dp_mst_topology_get_port_validated(mgr, port);
+	if (!port) {
+		ret = -EINVAL;
+		goto out_get_port;
+	}
+
+	get_random_bytes(nonce, sizeof(nonce));
+
+	/*
+	 * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
+	 *  transaction at the MST Branch device directly connected to the
+	 *  Source"
+	 */
+	txmsg->dst = mgr->mst_primary;
+
+	len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
+
+	drm_dp_queue_down_tx(mgr, txmsg);
+
+	ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
+	if (ret < 0) {
+		goto out;
+	} else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
+		DRM_DEBUG_KMS("query encryption status nak received\n");
+		ret = -ENXIO;
+		goto out;
+	}
+
+	ret = 0;
+	memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
+
+out:
+	drm_dp_mst_topology_put_port(port);
+out_get_port:
+	kfree(txmsg);
+	return ret;
+}
+EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
+
 static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
 				       int id,
 				       struct drm_dp_payload *payload)
diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
index bd990d178765..1d696ec001cf 100644
--- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
+++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
@@ -5,6 +5,8 @@
 
 #define PREFIX_STR "[drm_dp_mst_helper]"
 
+#include <linux/random.h>
+
 #include <drm/drm_dp_mst_helper.h>
 #include <drm/drm_print.h>
 
@@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
 	in.u.i2c_write.bytes = data;
 	DO_TEST();
 
+	in.req_type = DP_QUERY_STREAM_ENC_STATUS;
+	in.u.enc_status.stream_id = 1;
+	DO_TEST();
+	get_random_bytes(in.u.enc_status.client_id,
+			 sizeof(in.u.enc_status.client_id));
+	DO_TEST();
+	in.u.enc_status.stream_event = 3;
+	DO_TEST();
+	in.u.enc_status.valid_stream_event = 0;
+	DO_TEST();
+	in.u.enc_status.stream_behavior = 3;
+	DO_TEST();
+	in.u.enc_status.valid_stream_behavior = 1;
+	DO_TEST();
+
 #undef DO_TEST
 	return 0;
 }
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index e47dc22ebf50..e2d2df5e869e 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1108,6 +1108,9 @@
 #define DP_POWER_DOWN_PHY		0x25
 #define DP_SINK_EVENT_NOTIFY		0x30
 #define DP_QUERY_STREAM_ENC_STATUS	0x38
+#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST	0
+#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE	1
+#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE	2
 
 /* DP 1.2 MST sideband reply types */
 #define DP_SIDEBAND_REPLY_ACK		0x00
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 8b9eb4db3381..371eef8798ad 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
 	u8 port_number;
 };
 
+struct drm_dp_query_stream_enc_status_ack_reply {
+	/* Bit[23:16]- Stream Id */
+	u8 stream_id;
+
+	/* Bit[15]- Signed */
+	bool reply_signed;
+
+	/* Bit[10:8]- Stream Output Sink Type */
+	bool unauthorizable_device_present;
+	bool legacy_device_present;
+	bool query_capable_device_present;
+
+	/* Bit[12:11]- Stream Output CP Type */
+	bool hdcp_1x_device_present;
+	bool hdcp_2x_device_present;
+
+	/* Bit[4]- Stream Authentication */
+	bool auth_completed;
+
+	/* Bit[3]- Stream Encryption */
+	bool encryption_enabled;
+
+	/* Bit[2]- Stream Repeater Function Present */
+	bool repeater_present;
+
+	/* Bit[1:0]- Stream State */
+	u8 state;
+};
 
 #define DRM_DP_MAX_SDP_STREAMS 16
 struct drm_dp_allocate_payload {
@@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
 	u8 *bytes;
 };
 
+struct drm_dp_query_stream_enc_status {
+	u8 stream_id;
+	u8 client_id[7];	/* 56-bit nonce */
+	u8 stream_event;
+	bool valid_stream_event;
+	u8 stream_behavior;
+	u8 valid_stream_behavior;
+};
+
 /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
 struct drm_dp_port_number_req {
 	u8 port_number;
@@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
 
 		struct drm_dp_remote_i2c_read i2c_read;
 		struct drm_dp_remote_i2c_write i2c_write;
+
+		struct drm_dp_query_stream_enc_status enc_status;
 	} u;
 };
 
@@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
 		struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
 		struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
 		struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
+
+		struct drm_dp_query_stream_enc_status_ack_reply enc_status;
 	} u;
 };
 
@@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
 				 struct drm_dp_mst_port *port);
 int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
 				 struct drm_dp_mst_port *port, bool power_up);
+int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
+		struct drm_dp_mst_port *port,
+		struct drm_dp_query_stream_enc_status_ack_reply *status);
 int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
 
 void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 16/17] drm/i915: Print HDCP version info for all connectors
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:59   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

De-duplicate the HDCP version code for each connector and print it for
all connectors.

Cc: Juston Li <juston.li@intel.com>
Cc: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Juston Li <juston.li@intel.com>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>

Link: https://patchwork.freedesktop.org/patch/msgid/20200227185714.171466-1-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-16-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-16-sean@poorly.run #v6

Changes in v4:
- Added to the set
Changes in v5:
-Print "No connector support" for hdcp sink capability as well (Ram)
Changes in v6:
-None
Changes in v7:
-None
---
 .../drm/i915/display/intel_display_debugfs.c  | 21 ++++++++-----------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index d1cb48b3f462..1f748a480eb2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -598,6 +598,11 @@ static void intel_hdcp_info(struct seq_file *m,
 {
 	bool hdcp_cap, hdcp2_cap;
 
+	if (!intel_connector->hdcp.shim) {
+		seq_puts(m, "No Connector Support");
+		goto out;
+	}
+
 	hdcp_cap = intel_hdcp_capable(intel_connector);
 	hdcp2_cap = intel_hdcp2_capable(intel_connector);
 
@@ -609,6 +614,7 @@ static void intel_hdcp_info(struct seq_file *m,
 	if (!hdcp_cap && !hdcp2_cap)
 		seq_puts(m, "None");
 
+out:
 	seq_puts(m, "\n");
 }
 
@@ -625,10 +631,6 @@ static void intel_dp_info(struct seq_file *m,
 
 	drm_dp_downstream_debug(m, intel_dp->dpcd, intel_dp->downstream_ports,
 				&intel_dp->aux);
-	if (intel_connector->hdcp.shim) {
-		seq_puts(m, "\tHDCP version: ");
-		intel_hdcp_info(m, intel_connector);
-	}
 }
 
 static void intel_dp_mst_info(struct seq_file *m,
@@ -646,10 +648,6 @@ static void intel_hdmi_info(struct seq_file *m,
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(intel_encoder);
 
 	seq_printf(m, "\taudio support: %s\n", yesno(intel_hdmi->has_audio));
-	if (intel_connector->hdcp.shim) {
-		seq_puts(m, "\tHDCP version: ");
-		intel_hdcp_info(m, intel_connector);
-	}
 }
 
 static void intel_lvds_info(struct seq_file *m,
@@ -705,6 +703,9 @@ static void intel_connector_info(struct seq_file *m,
 		break;
 	}
 
+	seq_puts(m, "\tHDCP version: ");
+	intel_hdcp_info(m, intel_connector);
+
 	seq_printf(m, "\tmodes:\n");
 	list_for_each_entry(mode, &connector->modes, head)
 		intel_seq_print_mode(m, 2, mode);
@@ -2026,10 +2027,6 @@ static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
 	if (connector->status != connector_status_connected)
 		return -ENODEV;
 
-	/* HDCP is supported by connector */
-	if (!intel_connector->hdcp.shim)
-		return -EINVAL;
-
 	seq_printf(m, "%s:%d HDCP version: ", connector->name,
 		   connector->base.id);
 	intel_hdcp_info(m, intel_connector);
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 16/17] drm/i915: Print HDCP version info for all connectors
@ 2020-06-23 15:59   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

De-duplicate the HDCP version code for each connector and print it for
all connectors.

Cc: Juston Li <juston.li@intel.com>
Cc: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Juston Li <juston.li@intel.com>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>

Link: https://patchwork.freedesktop.org/patch/msgid/20200227185714.171466-1-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-16-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-16-sean@poorly.run #v6

Changes in v4:
- Added to the set
Changes in v5:
-Print "No connector support" for hdcp sink capability as well (Ram)
Changes in v6:
-None
Changes in v7:
-None
---
 .../drm/i915/display/intel_display_debugfs.c  | 21 ++++++++-----------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index d1cb48b3f462..1f748a480eb2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -598,6 +598,11 @@ static void intel_hdcp_info(struct seq_file *m,
 {
 	bool hdcp_cap, hdcp2_cap;
 
+	if (!intel_connector->hdcp.shim) {
+		seq_puts(m, "No Connector Support");
+		goto out;
+	}
+
 	hdcp_cap = intel_hdcp_capable(intel_connector);
 	hdcp2_cap = intel_hdcp2_capable(intel_connector);
 
@@ -609,6 +614,7 @@ static void intel_hdcp_info(struct seq_file *m,
 	if (!hdcp_cap && !hdcp2_cap)
 		seq_puts(m, "None");
 
+out:
 	seq_puts(m, "\n");
 }
 
@@ -625,10 +631,6 @@ static void intel_dp_info(struct seq_file *m,
 
 	drm_dp_downstream_debug(m, intel_dp->dpcd, intel_dp->downstream_ports,
 				&intel_dp->aux);
-	if (intel_connector->hdcp.shim) {
-		seq_puts(m, "\tHDCP version: ");
-		intel_hdcp_info(m, intel_connector);
-	}
 }
 
 static void intel_dp_mst_info(struct seq_file *m,
@@ -646,10 +648,6 @@ static void intel_hdmi_info(struct seq_file *m,
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(intel_encoder);
 
 	seq_printf(m, "\taudio support: %s\n", yesno(intel_hdmi->has_audio));
-	if (intel_connector->hdcp.shim) {
-		seq_puts(m, "\tHDCP version: ");
-		intel_hdcp_info(m, intel_connector);
-	}
 }
 
 static void intel_lvds_info(struct seq_file *m,
@@ -705,6 +703,9 @@ static void intel_connector_info(struct seq_file *m,
 		break;
 	}
 
+	seq_puts(m, "\tHDCP version: ");
+	intel_hdcp_info(m, intel_connector);
+
 	seq_printf(m, "\tmodes:\n");
 	list_for_each_entry(mode, &connector->modes, head)
 		intel_seq_print_mode(m, 2, mode);
@@ -2026,10 +2027,6 @@ static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
 	if (connector->status != connector_status_connected)
 		return -ENODEV;
 
-	/* HDCP is supported by connector */
-	if (!intel_connector->hdcp.shim)
-		return -EINVAL;
-
 	seq_printf(m, "%s:%d HDCP version: ", connector->name,
 		   connector->base.id);
 	intel_hdcp_info(m, intel_connector);
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
@ 2020-06-23 15:59   ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul, juston.li, rodrigo.vivi

From: Sean Paul <seanpaul@chromium.org>

Now that all the groundwork has been laid, we can turn on HDCP 1.4 over
MST. Everything except for toggling the HDCP signalling and HDCP 2.2
support is the same as the DP case, so we'll re-use those callbacks

Cc: Juston Li <juston.li@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-12-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-13-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-13-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-15-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-17-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-17-sean@poorly.run #v6

Changes in v2:
-Toggle HDCP from encoder disable/enable
-Don't disable HDCP on MST connector destroy, leave that for encoder
 disable, just ensure the check_work routine isn't running any longer
Changes in v3:
-Place the shim in the new intel_dp_hdcp.c file (Ville)
Changes in v4:
-Actually use the mst shim for mst connections (Juston)
-Use QUERY_STREAM_ENC_STATUS MST message to verify channel is encrypted
Changes in v5:
-Add sleep on disable signalling to match hdmi delay
Changes in v6:
-Disable HDCP over MST on GEN12+ since I'm unsure how it should work and I
 don't have hardware to test it
Changes in v7:
-Remove hdcp2 shims for MST in favor of skipping hdcp2 init (Ramalingam)
---
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 66 +++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_dp_mst.c  | 18 ++++++
 drivers/gpu/drm/i915/display/intel_hdcp.c    |  2 +-
 3 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
index 43446a6cae8d..3f67bd27fc3c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -7,10 +7,12 @@
  */
 
 #include <drm/drm_dp_helper.h>
+#include <drm/drm_dp_mst_helper.h>
 #include <drm/drm_hdcp.h>
 #include <drm/drm_print.h>
 
 #include "intel_display_types.h"
+#include "intel_ddi.h"
 #include "intel_dp.h"
 #include "intel_hdcp.h"
 
@@ -618,6 +620,65 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
 	.protocol = HDCP_PROTOCOL_DP,
 };
 
+static int
+intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
+				    enum transcoder cpu_transcoder,
+				    bool enable)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	int ret;
+
+	if (!enable)
+		usleep_range(6, 60); /* Bspec says >= 6us */
+
+	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
+					       cpu_transcoder, enable);
+	if (ret)
+		drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
+			      enable ? "Enable" : "Disable", ret);
+	return ret;
+}
+
+static
+bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
+				  struct intel_connector *connector)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct drm_dp_query_stream_enc_status_ack_reply reply;
+	int ret;
+
+	if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
+		return false;
+
+	ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
+						  connector->port, &reply);
+	if (ret) {
+		drm_dbg_kms(&i915->drm,
+			    "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
+			    connector->base.base.id, connector->base.name, ret);
+		return false;
+	}
+
+	return reply.auth_completed && reply.encryption_enabled;
+}
+
+static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
+	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
+	.read_bksv = intel_dp_hdcp_read_bksv,
+	.read_bstatus = intel_dp_hdcp_read_bstatus,
+	.repeater_present = intel_dp_hdcp_repeater_present,
+	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
+	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
+	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
+	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
+	.toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
+	.check_link = intel_dp_mst_hdcp_check_link,
+	.hdcp_capable = intel_dp_hdcp_capable,
+
+	.protocol = HDCP_PROTOCOL_DP,
+};
+
 int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
 		       struct intel_connector *intel_connector)
 {
@@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
 	if (!is_hdcp_supported(dev_priv, port))
 		return 0;
 
-	if (!intel_dp_is_edp(intel_dp))
+	if (intel_connector->mst_port)
+		return intel_hdcp_init(intel_connector, port,
+				       &intel_dp_mst_hdcp_shim);
+	else if (!intel_dp_is_edp(intel_dp))
 		return intel_hdcp_init(intel_connector, port,
 				       &intel_dp_hdcp_shim);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 0675825dcc20..abaaeeb963d2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -37,6 +37,7 @@
 #include "intel_dp.h"
 #include "intel_dp_mst.h"
 #include "intel_dpio_phy.h"
+#include "intel_hdcp.h"
 
 static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 					    struct intel_crtc_state *crtc_state,
@@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
 	drm_dbg_kms(&i915->drm, "active links %d\n",
 		    intel_dp->active_mst_links);
 
+	intel_hdcp_disable(intel_mst->connector);
+
 	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
 
 	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
@@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
 
 	if (pipe_config->has_audio)
 		intel_audio_codec_enable(encoder, pipe_config, conn_state);
+
+	/* Enable hdcp if it's desired */
+	if (conn_state->content_protection ==
+	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
+		intel_hdcp_enable(to_intel_connector(conn_state->connector),
+				  pipe_config->cpu_transcoder,
+				  (u8)conn_state->hdcp_content_type);
 }
 
 static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
@@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
 	intel_attach_force_audio_property(connector);
 	intel_attach_broadcast_rgb_property(connector);
 
+
+	/* TODO: Figure out how to make HDCP work on GEN12+ */
+	if (INTEL_GEN(dev_priv) < 12) {
+		ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
+		if (ret)
+			DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
+	}
+
 	/*
 	 * Reuse the prop from the SST connector because we're
 	 * not allowed to create new props after device registration.
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 6bd0e4616ee1..ddc9db8de2bc 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
 	if (!shim)
 		return -EINVAL;
 
-	if (is_hdcp2_supported(dev_priv))
+	if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
 		intel_hdcp2_init(connector, port, shim);
 
 	ret =
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
@ 2020-06-23 15:59   ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-23 15:59 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

Now that all the groundwork has been laid, we can turn on HDCP 1.4 over
MST. Everything except for toggling the HDCP signalling and HDCP 2.2
support is the same as the DP case, so we'll re-use those callbacks

Cc: Juston Li <juston.li@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-12-sean@poorly.run #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-13-sean@poorly.run #v2
Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-13-sean@poorly.run #v3
Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-15-sean@poorly.run #v4
Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-17-sean@poorly.run #v5
Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-17-sean@poorly.run #v6

Changes in v2:
-Toggle HDCP from encoder disable/enable
-Don't disable HDCP on MST connector destroy, leave that for encoder
 disable, just ensure the check_work routine isn't running any longer
Changes in v3:
-Place the shim in the new intel_dp_hdcp.c file (Ville)
Changes in v4:
-Actually use the mst shim for mst connections (Juston)
-Use QUERY_STREAM_ENC_STATUS MST message to verify channel is encrypted
Changes in v5:
-Add sleep on disable signalling to match hdmi delay
Changes in v6:
-Disable HDCP over MST on GEN12+ since I'm unsure how it should work and I
 don't have hardware to test it
Changes in v7:
-Remove hdcp2 shims for MST in favor of skipping hdcp2 init (Ramalingam)
---
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 66 +++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_dp_mst.c  | 18 ++++++
 drivers/gpu/drm/i915/display/intel_hdcp.c    |  2 +-
 3 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
index 43446a6cae8d..3f67bd27fc3c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -7,10 +7,12 @@
  */
 
 #include <drm/drm_dp_helper.h>
+#include <drm/drm_dp_mst_helper.h>
 #include <drm/drm_hdcp.h>
 #include <drm/drm_print.h>
 
 #include "intel_display_types.h"
+#include "intel_ddi.h"
 #include "intel_dp.h"
 #include "intel_hdcp.h"
 
@@ -618,6 +620,65 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
 	.protocol = HDCP_PROTOCOL_DP,
 };
 
+static int
+intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
+				    enum transcoder cpu_transcoder,
+				    bool enable)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	int ret;
+
+	if (!enable)
+		usleep_range(6, 60); /* Bspec says >= 6us */
+
+	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
+					       cpu_transcoder, enable);
+	if (ret)
+		drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
+			      enable ? "Enable" : "Disable", ret);
+	return ret;
+}
+
+static
+bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
+				  struct intel_connector *connector)
+{
+	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct drm_dp_query_stream_enc_status_ack_reply reply;
+	int ret;
+
+	if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
+		return false;
+
+	ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
+						  connector->port, &reply);
+	if (ret) {
+		drm_dbg_kms(&i915->drm,
+			    "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
+			    connector->base.base.id, connector->base.name, ret);
+		return false;
+	}
+
+	return reply.auth_completed && reply.encryption_enabled;
+}
+
+static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
+	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
+	.read_bksv = intel_dp_hdcp_read_bksv,
+	.read_bstatus = intel_dp_hdcp_read_bstatus,
+	.repeater_present = intel_dp_hdcp_repeater_present,
+	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
+	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
+	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
+	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
+	.toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
+	.check_link = intel_dp_mst_hdcp_check_link,
+	.hdcp_capable = intel_dp_hdcp_capable,
+
+	.protocol = HDCP_PROTOCOL_DP,
+};
+
 int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
 		       struct intel_connector *intel_connector)
 {
@@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
 	if (!is_hdcp_supported(dev_priv, port))
 		return 0;
 
-	if (!intel_dp_is_edp(intel_dp))
+	if (intel_connector->mst_port)
+		return intel_hdcp_init(intel_connector, port,
+				       &intel_dp_mst_hdcp_shim);
+	else if (!intel_dp_is_edp(intel_dp))
 		return intel_hdcp_init(intel_connector, port,
 				       &intel_dp_hdcp_shim);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 0675825dcc20..abaaeeb963d2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -37,6 +37,7 @@
 #include "intel_dp.h"
 #include "intel_dp_mst.h"
 #include "intel_dpio_phy.h"
+#include "intel_hdcp.h"
 
 static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 					    struct intel_crtc_state *crtc_state,
@@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
 	drm_dbg_kms(&i915->drm, "active links %d\n",
 		    intel_dp->active_mst_links);
 
+	intel_hdcp_disable(intel_mst->connector);
+
 	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
 
 	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
@@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
 
 	if (pipe_config->has_audio)
 		intel_audio_codec_enable(encoder, pipe_config, conn_state);
+
+	/* Enable hdcp if it's desired */
+	if (conn_state->content_protection ==
+	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
+		intel_hdcp_enable(to_intel_connector(conn_state->connector),
+				  pipe_config->cpu_transcoder,
+				  (u8)conn_state->hdcp_content_type);
 }
 
 static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
@@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
 	intel_attach_force_audio_property(connector);
 	intel_attach_broadcast_rgb_property(connector);
 
+
+	/* TODO: Figure out how to make HDCP work on GEN12+ */
+	if (INTEL_GEN(dev_priv) < 12) {
+		ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
+		if (ret)
+			DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
+	}
+
 	/*
 	 * Reuse the prop from the SST connector because we're
 	 * not allowed to create new props after device registration.
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 6bd0e4616ee1..ddc9db8de2bc 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
 	if (!shim)
 		return -EINVAL;
 
-	if (is_hdcp2_supported(dev_priv))
+	if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
 		intel_hdcp2_init(connector, port, shim);
 
 	ret =
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add support for HDCP 1.4 over MST
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
                   ` (17 preceding siblings ...)
  (?)
@ 2020-06-23 16:38 ` Patchwork
  -1 siblings, 0 replies; 98+ messages in thread
From: Patchwork @ 2020-06-23 16:38 UTC (permalink / raw)
  To: Sean Paul; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Add support for HDCP 1.4 over MST
URL   : https://patchwork.freedesktop.org/series/78749/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
40a9cf573823 drm/i915: Fix sha_text population code
-:69: WARNING:LINE_SPACING: Missing a blank line after declarations
#69: FILE: drivers/gpu/drm/i915/display/intel_hdcp.c:341:
+			u8 off = ((sizeof(sha_text) - j - 1 - sha_leftovers) * 8);
+			sha_text |= ksv[j] << off;

total: 0 errors, 1 warnings, 0 checks, 61 lines checked
fdd9116bae73 drm/i915: Clear the repeater bit on HDCP disable
26c597bb2bdf drm/i915: WARN if HDCP signalling is enabled upon disable
2dfd826048e1 drm/i915: Intercept Aksv writes in the aux hooks
f4a73566d2ac drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling
24dfa20af876 drm/i915: Factor out hdcp->value assignments
-:75: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#75: FILE: drivers/gpu/drm/i915/display/intel_hdcp.c:931:
+			intel_hdcp_update_value(connector,
+				DRM_MODE_CONTENT_PROTECTION_ENABLED, true);

-:120: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#120: FILE: drivers/gpu/drm/i915/display/intel_hdcp.c:1800:
+			intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_ENABLED,

-:132: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#132: FILE: drivers/gpu/drm/i915/display/intel_hdcp.c:1815:
+			intel_hdcp_update_value(connector,
+					DRM_MODE_CONTENT_PROTECTION_ENABLED,

-:144: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#144: FILE: drivers/gpu/drm/i915/display/intel_hdcp.c:1835:
+		intel_hdcp_update_value(connector,
+				DRM_MODE_CONTENT_PROTECTION_DESIRED, true);

total: 0 errors, 0 warnings, 4 checks, 138 lines checked
96ac1382f6c4 drm/i915: Protect workers against disappearing connectors
-:92: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#92: FILE: drivers/gpu/drm/i915/display/intel_hdcp.c:2198:
+	drm_WARN_ON(connector->base.dev,
+		connector->base.registration_state == DRM_CONNECTOR_REGISTERED);

total: 0 errors, 0 warnings, 1 checks, 71 lines checked
5bef2450359c drm/i915: Clean up intel_hdcp_disable
6adefe67fdcb drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
9118a955e697 drm/i915: Support DP MST in enc_to_dig_port() function
60fe26102e05 drm/i915: Use ddi_update_pipe in intel_dp_mst
294a579032b2 drm/i915: Factor out HDCP shim functions from dp for use by dp_mst
-:687: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#687: 
new file mode 100644

-:692: WARNING:SPDX_LICENSE_TAG: Improper SPDX comment style for 'drivers/gpu/drm/i915/display/intel_dp_hdcp.c', please use '//' instead
#692: FILE: drivers/gpu/drm/i915/display/intel_dp_hdcp.c:1:
+/* SPDX-License-Identifier: MIT */

-:692: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#692: FILE: drivers/gpu/drm/i915/display/intel_dp_hdcp.c:1:
+/* SPDX-License-Identifier: MIT */

-:872: WARNING:LINE_SPACING: Missing a blank line after declarations
#872: FILE: drivers/gpu/drm/i915/display/intel_dp_hdcp.c:181:
+		size_t len = min(num_downstream - i, 3) * DRM_HDCP_KSV_LEN;
+		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,

-:1248: CHECK:BRACES: Blank lines aren't necessary before a close brace '}'
#1248: FILE: drivers/gpu/drm/i915/display/intel_dp_hdcp.c:557:
+
+}

total: 0 errors, 4 warnings, 1 checks, 1274 lines checked
e95d4796d643 drm/i915: Plumb port through hdcp init
b159048d4ee3 drm/i915: Add connector to hdcp_shim->check_link()
43dca30ee7d8 drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
-:78: ERROR:CODE_INDENT: code indent should use tabs where possible
#78: FILE: drivers/gpu/drm/drm_dp_mst_topology.c:576:
+^I^I^I^I^I^I^I ^I buf[idx]);$

-:78: WARNING:SPACE_BEFORE_TAB: please, no space before tabs
#78: FILE: drivers/gpu/drm/drm_dp_mst_topology.c:576:
+^I^I^I^I^I^I^I ^I buf[idx]);$

-:78: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#78: FILE: drivers/gpu/drm/drm_dp_mst_topology.c:576:
+		req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
+							 	 buf[idx]);

-:109: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#109: FILE: drivers/gpu/drm/drm_dp_mst_topology.c:971:
+drm_dp_sideband_parse_query_stream_enc_status(

-:179: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#179: FILE: drivers/gpu/drm/drm_dp_mst_topology.c:3232:
+int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
+		struct drm_dp_mst_port *port,

-:359: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#359: FILE: include/drm/drm_dp_mst_helper.h:853:
+int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
+		struct drm_dp_mst_port *port,

total: 1 errors, 1 warnings, 4 checks, 307 lines checked
f415c158925f drm/i915: Print HDCP version info for all connectors
ff0e9553b262 drm/i915: Add HDCP 1.4 support for MST connectors
-:72: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#72: FILE: drivers/gpu/drm/i915/display/intel_dp_hdcp.c:638:
+		drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
+			      enable ? "Enable" : "Disable", ret);

-:170: CHECK:LINE_SPACING: Please don't use multiple blank lines
#170: FILE: drivers/gpu/drm/i915/display/intel_dp_mst.c:783:
 
+

total: 0 errors, 0 warnings, 2 checks, 138 lines checked

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/i915: Add support for HDCP 1.4 over MST
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
                   ` (18 preceding siblings ...)
  (?)
@ 2020-06-23 16:39 ` Patchwork
  -1 siblings, 0 replies; 98+ messages in thread
From: Patchwork @ 2020-06-23 16:39 UTC (permalink / raw)
  To: Sean Paul; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Add support for HDCP 1.4 over MST
URL   : https://patchwork.freedesktop.org/series/78749/
State : warning

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.0
Fast mode used, each commit won't be checked separately.
-
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:1019:47:    expected unsigned int [addressable] [usertype] ulClockParams
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:1019:47:    got restricted __le32 [usertype]
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:1019:47: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:1028:50: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:1029:49: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:1037:47: warning: too many warnings
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:184:44: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:283:14: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:320:14: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:323:14: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:326:14: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:329:18: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:330:26: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:338:30: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:340:38: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:342:30: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:346:30: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:348:30: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:353:33: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:367:43: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:369:38: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:374:67: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:375:53: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:378:66: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:389:80: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:395:57: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:402:69: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:403:53: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:406:66: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:414:66: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:423:69: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:424:69: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:473:30: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:476:45: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:477:45: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:484:54: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:52:28: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:531:35: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:53:29: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:533:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:54:26: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:55:27: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:56:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:57:26: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:577:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:581:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:58:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:583:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:586:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:590:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:59:26: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:598:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:600:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:617:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:621:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:623:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:630:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:632:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:644:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:648:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:650:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:657:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:659:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:662:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:664:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:676:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:688:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:691:47: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:697:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:796:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:797:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:800:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:801:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:804:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:805:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:812:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:813:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:816:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:817:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:820:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:821:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:828:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:829:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:832:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:833:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:836:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:837:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:844:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:845:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:848:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:849:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:852:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:853:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:916:47: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:918:49: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:920:52: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:934:47: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:936:49: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:938:52: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:956:47: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:958:49: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:960:52: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:296:34: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:330:34: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:360:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:362:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:369:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:383:40: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:406:40: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:44:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:447:53: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:451:33: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:454:61: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:455:64: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:457:54: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:483:17: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:486:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:64:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:80:17: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:80:17: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:80:17: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:85:30: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:86:24: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:98:39: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:222:29: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:226:37: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:226:37: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:226:37: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:227:37: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:233:43: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:236:44: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:239:51: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:458:41: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:458:41: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:458:41: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:464:39: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:465:30: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:466:39: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:468:24: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:140:26:    expected unsigned long long [usertype] *chunk_array_user
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:140:26:    got void [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:140:26: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:141:41:    expected void const [noderef] __user *from
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:141:41:    got unsigned long long [usertype] *chunk_array_user
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:141:41: warning: incorrect type in argument 2 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:160:27:    expected struct drm_amdgpu_cs_chunk [noderef] __user **chunk_ptr
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:160:27:    got void [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:160:27: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1613:21:    expected struct drm_amdgpu_fence *fences_user
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1613:21:    got void [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1613:21: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1614:36:    expected void const [noderef] __user *from
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1614:36:    got struct drm_amdgpu_fence *fences_user
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1614:36: warning: incorrect type in argument 2 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:161:49:    expected void const [noderef] __user *from
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:161:49:    got struct drm_amdgpu_cs_chunk [noderef] __user **chunk_ptr
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:161:49: warning: incorrect type in argument 2 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1256:25: error: incompatible types in comparison expression (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1257:17: error: incompatible types in comparison expression (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1313:17: error: incompatible types in comparison expression (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:138:17:    expected restricted __poll_t ( *poll )( ... )
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:138:17:    got unsigned int ( * )( ... )
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:138:17: warning: incorrect type in initializer (different base types)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:257:29: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:259:29:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:259:29:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:259:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:259:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:259:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:259:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:259:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:259:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:259:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:259:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:259:29: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:346:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:400:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:400:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:400:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:400:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:400:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:400:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:400:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:400:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:400:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:400:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:400:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:457:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:511:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:511:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:511:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:511:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:511:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:511:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:511:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:511:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:511:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:511:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:511:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:568:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:622:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:622:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:622:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:622:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:622:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:622:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:622:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:622:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:622:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:622:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:622:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:719:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:719:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:719:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:719:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:719:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:719:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:719:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:719:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:719:21: warning: too many warnings
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1618:65: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1625:55: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1626:50: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1627:50: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1628:56: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1630:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1631:45: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1632:51: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1633:55: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1634:57: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1636:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1637:53: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1639:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1641:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1642:46: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1646:73: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1648:33: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1650:33: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1661:73: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:260:16: error: incompatible types in comparison expression (different type sizes)
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:507:39: warning: cast removes address space '__iomem' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:527:31: warning: cast removes address space '__iomem' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:184:13: warning: cast to restricted __le32

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: Add support for HDCP 1.4 over MST
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
                   ` (19 preceding siblings ...)
  (?)
@ 2020-06-23 16:58 ` Patchwork
  -1 siblings, 0 replies; 98+ messages in thread
From: Patchwork @ 2020-06-23 16:58 UTC (permalink / raw)
  To: Sean Paul; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Add support for HDCP 1.4 over MST
URL   : https://patchwork.freedesktop.org/series/78749/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8658 -> Patchwork_18013
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/index.html

Known issues
------------

  Here are the changes found in Patchwork_18013 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@debugfs_test@read_all_entries:
    - fi-bsw-nick:        [PASS][1] -> [INCOMPLETE][2] ([i915#1250] / [i915#1436])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/fi-bsw-nick/igt@debugfs_test@read_all_entries.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/fi-bsw-nick/igt@debugfs_test@read_all_entries.html

  * igt@i915_pm_rpm@module-reload:
    - fi-bsw-n3050:       [PASS][3] -> [DMESG-WARN][4] ([i915#1982])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/fi-bsw-n3050/igt@i915_pm_rpm@module-reload.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/fi-bsw-n3050/igt@i915_pm_rpm@module-reload.html

  * igt@kms_cursor_legacy@basic-flip-after-cursor-atomic:
    - fi-icl-u2:          [PASS][5] -> [DMESG-WARN][6] ([i915#1982]) +1 similar issue
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/fi-icl-u2/igt@kms_cursor_legacy@basic-flip-after-cursor-atomic.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/fi-icl-u2/igt@kms_cursor_legacy@basic-flip-after-cursor-atomic.html

  
#### Possible fixes ####

  * igt@gem_exec_suspend@basic-s0:
    - fi-apl-guc:         [INCOMPLETE][7] ([i915#1242]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/fi-apl-guc/igt@gem_exec_suspend@basic-s0.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/fi-apl-guc/igt@gem_exec_suspend@basic-s0.html
    - fi-tgl-u2:          [FAIL][9] ([i915#1888]) -> [PASS][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/fi-tgl-u2/igt@gem_exec_suspend@basic-s0.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/fi-tgl-u2/igt@gem_exec_suspend@basic-s0.html

  * igt@i915_module_load@reload:
    - fi-bsw-kefka:       [DMESG-WARN][11] ([i915#1982]) -> [PASS][12] +1 similar issue
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/fi-bsw-kefka/igt@i915_module_load@reload.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/fi-bsw-kefka/igt@i915_module_load@reload.html

  * igt@i915_pm_rpm@basic-pci-d3-state:
    - {fi-tgl-dsi}:       [DMESG-WARN][13] ([i915#1982]) -> [PASS][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/fi-tgl-dsi/igt@i915_pm_rpm@basic-pci-d3-state.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/fi-tgl-dsi/igt@i915_pm_rpm@basic-pci-d3-state.html

  * igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1:
    - fi-icl-u2:          [DMESG-WARN][15] ([i915#1982]) -> [PASS][16]
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/fi-icl-u2/igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/fi-icl-u2/igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1.html

  * igt@kms_pipe_crc_basic@read-crc-pipe-a-frame-sequence:
    - fi-tgl-u2:          [DMESG-WARN][17] ([i915#402]) -> [PASS][18]
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/fi-tgl-u2/igt@kms_pipe_crc_basic@read-crc-pipe-a-frame-sequence.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/fi-tgl-u2/igt@kms_pipe_crc_basic@read-crc-pipe-a-frame-sequence.html

  
#### Warnings ####

  * igt@kms_force_connector_basic@prune-stale-modes:
    - fi-kbl-x1275:       [DMESG-WARN][19] ([i915#62] / [i915#92]) -> [DMESG-WARN][20] ([i915#62] / [i915#92] / [i915#95]) +5 similar issues
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/fi-kbl-x1275/igt@kms_force_connector_basic@prune-stale-modes.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/fi-kbl-x1275/igt@kms_force_connector_basic@prune-stale-modes.html

  * igt@kms_pipe_crc_basic@nonblocking-crc-pipe-a:
    - fi-kbl-x1275:       [DMESG-WARN][21] ([i915#62] / [i915#92] / [i915#95]) -> [DMESG-WARN][22] ([i915#62] / [i915#92]) +3 similar issues
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/fi-kbl-x1275/igt@kms_pipe_crc_basic@nonblocking-crc-pipe-a.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/fi-kbl-x1275/igt@kms_pipe_crc_basic@nonblocking-crc-pipe-a.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [i915#1242]: https://gitlab.freedesktop.org/drm/intel/issues/1242
  [i915#1250]: https://gitlab.freedesktop.org/drm/intel/issues/1250
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#1888]: https://gitlab.freedesktop.org/drm/intel/issues/1888
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402
  [i915#62]: https://gitlab.freedesktop.org/drm/intel/issues/62
  [i915#92]: https://gitlab.freedesktop.org/drm/intel/issues/92
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (44 -> 38)
------------------------------

  Missing    (6): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * Linux: CI_DRM_8658 -> Patchwork_18013

  CI-20190529: 20190529
  CI_DRM_8658: c86979e2fe3c106d95b5fcf2075709afa40f0f95 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5717: 725bf2dae51f0087eaa64f1931a2ef9d22f070dd @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_18013: ff0e9553b262afa612271f33b6f768d8f39093e0 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

ff0e9553b262 drm/i915: Add HDCP 1.4 support for MST connectors
f415c158925f drm/i915: Print HDCP version info for all connectors
43dca30ee7d8 drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
b159048d4ee3 drm/i915: Add connector to hdcp_shim->check_link()
e95d4796d643 drm/i915: Plumb port through hdcp init
294a579032b2 drm/i915: Factor out HDCP shim functions from dp for use by dp_mst
60fe26102e05 drm/i915: Use ddi_update_pipe in intel_dp_mst
9118a955e697 drm/i915: Support DP MST in enc_to_dig_port() function
6adefe67fdcb drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
5bef2450359c drm/i915: Clean up intel_hdcp_disable
96ac1382f6c4 drm/i915: Protect workers against disappearing connectors
24dfa20af876 drm/i915: Factor out hdcp->value assignments
f4a73566d2ac drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling
2dfd826048e1 drm/i915: Intercept Aksv writes in the aux hooks
26c597bb2bdf drm/i915: WARN if HDCP signalling is enabled upon disable
fdd9116bae73 drm/i915: Clear the repeater bit on HDCP disable
40a9cf573823 drm/i915: Fix sha_text population code

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [Intel-gfx] ✓ Fi.CI.IGT: success for drm/i915: Add support for HDCP 1.4 over MST
  2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
                   ` (20 preceding siblings ...)
  (?)
@ 2020-06-24  2:15 ` Patchwork
  -1 siblings, 0 replies; 98+ messages in thread
From: Patchwork @ 2020-06-24  2:15 UTC (permalink / raw)
  To: Sean Paul; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Add support for HDCP 1.4 over MST
URL   : https://patchwork.freedesktop.org/series/78749/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_8658_full -> Patchwork_18013_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Known issues
------------

  Here are the changes found in Patchwork_18013_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_fence@parallel@vcs0:
    - shard-glk:          [PASS][1] -> [DMESG-WARN][2] ([i915#118] / [i915#95]) +2 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-glk7/igt@gem_exec_fence@parallel@vcs0.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-glk9/igt@gem_exec_fence@parallel@vcs0.html

  * igt@i915_suspend@sysfs-reader:
    - shard-apl:          [PASS][3] -> [DMESG-WARN][4] ([i915#1635] / [i915#95]) +15 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-apl8/igt@i915_suspend@sysfs-reader.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-apl6/igt@i915_suspend@sysfs-reader.html

  * igt@kms_big_fb@linear-32bpp-rotate-180:
    - shard-skl:          [PASS][5] -> [DMESG-WARN][6] ([i915#1982]) +8 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-skl5/igt@kms_big_fb@linear-32bpp-rotate-180.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-skl2/igt@kms_big_fb@linear-32bpp-rotate-180.html

  * igt@kms_ccs@pipe-d-ccs-on-another-bo:
    - shard-tglb:         [PASS][7] -> [DMESG-WARN][8] ([i915#402])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-tglb3/igt@kms_ccs@pipe-d-ccs-on-another-bo.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-tglb1/igt@kms_ccs@pipe-d-ccs-on-another-bo.html

  * igt@kms_cursor_crc@pipe-a-cursor-256x85-onscreen:
    - shard-kbl:          [PASS][9] -> [DMESG-FAIL][10] ([i915#54] / [i915#95])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-kbl1/igt@kms_cursor_crc@pipe-a-cursor-256x85-onscreen.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-kbl6/igt@kms_cursor_crc@pipe-a-cursor-256x85-onscreen.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - shard-apl:          [PASS][11] -> [DMESG-WARN][12] ([i915#1982])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-apl3/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-apl2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions:
    - shard-skl:          [PASS][13] -> [FAIL][14] ([IGT#5])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-skl4/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-skl1/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html

  * igt@kms_draw_crc@draw-method-xrgb8888-mmap-wc-untiled:
    - shard-kbl:          [PASS][15] -> [DMESG-FAIL][16] ([fdo#108145] / [i915#54] / [i915#95])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-kbl1/igt@kms_draw_crc@draw-method-xrgb8888-mmap-wc-untiled.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-kbl6/igt@kms_draw_crc@draw-method-xrgb8888-mmap-wc-untiled.html

  * igt@kms_flip@flip-vs-suspend-interruptible@a-dp1:
    - shard-kbl:          [PASS][17] -> [DMESG-WARN][18] ([i915#180]) +7 similar issues
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-kbl3/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-kbl7/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html

  * igt@kms_flip_tiling@flip-changes-tiling:
    - shard-apl:          [PASS][19] -> [DMESG-FAIL][20] ([i915#1635] / [i915#95])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-apl8/igt@kms_flip_tiling@flip-changes-tiling.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-apl6/igt@kms_flip_tiling@flip-changes-tiling.html
    - shard-kbl:          [PASS][21] -> [DMESG-FAIL][22] ([i915#95])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-kbl7/igt@kms_flip_tiling@flip-changes-tiling.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-kbl3/igt@kms_flip_tiling@flip-changes-tiling.html

  * igt@kms_frontbuffer_tracking@psr-suspend:
    - shard-skl:          [PASS][23] -> [INCOMPLETE][24] ([i915#123] / [i915#69])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-skl3/igt@kms_frontbuffer_tracking@psr-suspend.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-skl7/igt@kms_frontbuffer_tracking@psr-suspend.html

  * igt@kms_hdr@bpc-switch-suspend:
    - shard-skl:          [PASS][25] -> [FAIL][26] ([i915#1188])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-skl4/igt@kms_hdr@bpc-switch-suspend.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-skl10/igt@kms_hdr@bpc-switch-suspend.html

  * igt@kms_invalid_dotclock:
    - shard-snb:          [PASS][27] -> [TIMEOUT][28] ([i915#1958]) +3 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-snb2/igt@kms_invalid_dotclock.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-snb4/igt@kms_invalid_dotclock.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes:
    - shard-skl:          [PASS][29] -> [INCOMPLETE][30] ([i915#69])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-skl10/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-skl4/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-c-planes.html

  * igt@kms_plane@plane-position-hole-dpms-pipe-a-planes:
    - shard-kbl:          [PASS][31] -> [DMESG-WARN][32] ([i915#93] / [i915#95])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-kbl7/igt@kms_plane@plane-position-hole-dpms-pipe-a-planes.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-kbl3/igt@kms_plane@plane-position-hole-dpms-pipe-a-planes.html

  
#### Possible fixes ####

  * igt@gem_exec_reloc@basic-concurrent0:
    - shard-glk:          [FAIL][33] ([i915#1930]) -> [PASS][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-glk5/igt@gem_exec_reloc@basic-concurrent0.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-glk4/igt@gem_exec_reloc@basic-concurrent0.html

  * igt@gem_exec_whisper@basic-contexts-all:
    - shard-glk:          [DMESG-WARN][35] ([i915#118] / [i915#95]) -> [PASS][36]
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-glk7/igt@gem_exec_whisper@basic-contexts-all.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-glk9/igt@gem_exec_whisper@basic-contexts-all.html

  * igt@gem_softpin@noreloc-s3:
    - shard-skl:          [INCOMPLETE][37] ([i915#69]) -> [PASS][38]
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-skl5/igt@gem_softpin@noreloc-s3.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-skl1/igt@gem_softpin@noreloc-s3.html

  * igt@i915_module_load@reload:
    - shard-tglb:         [DMESG-WARN][39] ([i915#402]) -> [PASS][40]
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-tglb5/igt@i915_module_load@reload.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-tglb1/igt@i915_module_load@reload.html

  * igt@kms_big_fb@x-tiled-64bpp-rotate-180:
    - shard-glk:          [DMESG-FAIL][41] ([i915#118] / [i915#95]) -> [PASS][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-glk8/igt@kms_big_fb@x-tiled-64bpp-rotate-180.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-glk1/igt@kms_big_fb@x-tiled-64bpp-rotate-180.html

  * igt@kms_big_fb@yf-tiled-32bpp-rotate-0:
    - shard-skl:          [DMESG-WARN][43] ([i915#1982]) -> [PASS][44] +8 similar issues
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-skl5/igt@kms_big_fb@yf-tiled-32bpp-rotate-0.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-skl4/igt@kms_big_fb@yf-tiled-32bpp-rotate-0.html

  * igt@kms_flip@modeset-vs-vblank-race-interruptible@a-hdmi-a1:
    - shard-glk:          [FAIL][45] ([i915#407]) -> [PASS][46]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-glk9/igt@kms_flip@modeset-vs-vblank-race-interruptible@a-hdmi-a1.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-glk6/igt@kms_flip@modeset-vs-vblank-race-interruptible@a-hdmi-a1.html

  * igt@kms_flip@plain-flip-fb-recreate@b-edp1:
    - shard-skl:          [FAIL][47] ([i915#1928]) -> [PASS][48]
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-skl5/igt@kms_flip@plain-flip-fb-recreate@b-edp1.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-skl2/igt@kms_flip@plain-flip-fb-recreate@b-edp1.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt:
    - shard-apl:          [DMESG-WARN][49] ([i915#1635] / [i915#95]) -> [PASS][50] +13 similar issues
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-apl2/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-apl1/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt.html

  * igt@kms_frontbuffer_tracking@fbc-rgb565-draw-blt:
    - shard-tglb:         [DMESG-WARN][51] ([i915#1982]) -> [PASS][52]
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-tglb7/igt@kms_frontbuffer_tracking@fbc-rgb565-draw-blt.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-tglb2/igt@kms_frontbuffer_tracking@fbc-rgb565-draw-blt.html

  * igt@kms_frontbuffer_tracking@psr-shrfb-scaledprimary:
    - shard-iclb:         [DMESG-WARN][53] ([i915#1982]) -> [PASS][54]
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-iclb3/igt@kms_frontbuffer_tracking@psr-shrfb-scaledprimary.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-iclb7/igt@kms_frontbuffer_tracking@psr-shrfb-scaledprimary.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - shard-kbl:          [DMESG-WARN][55] ([i915#180]) -> [PASS][56] +4 similar issues
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-kbl1/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-kbl4/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [FAIL][57] ([fdo#108145] / [i915#265]) -> [PASS][58]
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-skl7/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-skl1/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  
#### Warnings ####

  * igt@gem_exec_reloc@basic-concurrent16:
    - shard-snb:          [FAIL][59] ([i915#1930]) -> [TIMEOUT][60] ([i915#1958])
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-snb2/igt@gem_exec_reloc@basic-concurrent16.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-snb4/igt@gem_exec_reloc@basic-concurrent16.html

  * igt@i915_pm_dc@dc6-dpms:
    - shard-tglb:         [FAIL][61] ([i915#454]) -> [SKIP][62] ([i915#468])
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-tglb8/igt@i915_pm_dc@dc6-dpms.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-tglb2/igt@i915_pm_dc@dc6-dpms.html

  * igt@kms_color_chamelium@pipe-b-degamma:
    - shard-apl:          [SKIP][63] ([fdo#109271] / [fdo#111827] / [i915#1635]) -> [SKIP][64] ([fdo#109271] / [fdo#111827])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-apl7/igt@kms_color_chamelium@pipe-b-degamma.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-apl8/igt@kms_color_chamelium@pipe-b-degamma.html

  * igt@kms_draw_crc@draw-method-rgb565-render-ytiled:
    - shard-snb:          [SKIP][65] ([fdo#109271]) -> [TIMEOUT][66] ([i915#1958]) +1 similar issue
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-snb2/igt@kms_draw_crc@draw-method-rgb565-render-ytiled.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-snb4/igt@kms_draw_crc@draw-method-rgb565-render-ytiled.html

  * igt@kms_flip_tiling@flip-changes-tiling-yf:
    - shard-kbl:          [DMESG-FAIL][67] ([i915#95]) -> [DMESG-WARN][68] ([i915#93] / [i915#95])
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-kbl4/igt@kms_flip_tiling@flip-changes-tiling-yf.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-kbl4/igt@kms_flip_tiling@flip-changes-tiling-yf.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-cur-indfb-draw-mmap-wc:
    - shard-apl:          [SKIP][69] ([fdo#109271] / [i915#1635]) -> [SKIP][70] ([fdo#109271]) +5 similar issues
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-apl4/igt@kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-cur-indfb-draw-mmap-wc.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-apl8/igt@kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-cur-indfb-draw-mmap-wc.html

  * igt@kms_frontbuffer_tracking@psr-1p-offscren-pri-shrfb-draw-blt:
    - shard-apl:          [SKIP][71] ([fdo#109271]) -> [SKIP][72] ([fdo#109271] / [i915#1635]) +5 similar issues
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8658/shard-apl8/igt@kms_frontbuffer_tracking@psr-1p-offscren-pri-shrfb-draw-blt.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/shard-apl6/igt@kms_frontbuffer_tracking@psr-1p-offscren-pri-shrfb-draw-blt.html

  
  [IGT#5]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/issues/5
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#118]: https://gitlab.freedesktop.org/drm/intel/issues/118
  [i915#1188]: https://gitlab.freedesktop.org/drm/intel/issues/1188
  [i915#123]: https://gitlab.freedesktop.org/drm/intel/issues/123
  [i915#1635]: https://gitlab.freedesktop.org/drm/intel/issues/1635
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#1928]: https://gitlab.freedesktop.org/drm/intel/issues/1928
  [i915#1930]: https://gitlab.freedesktop.org/drm/intel/issues/1930
  [i915#1958]: https://gitlab.freedesktop.org/drm/intel/issues/1958
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402
  [i915#407]: https://gitlab.freedesktop.org/drm/intel/issues/407
  [i915#454]: https://gitlab.freedesktop.org/drm/intel/issues/454
  [i915#468]: https://gitlab.freedesktop.org/drm/intel/issues/468
  [i915#54]: https://gitlab.freedesktop.org/drm/intel/issues/54
  [i915#69]: https://gitlab.freedesktop.org/drm/intel/issues/69
  [i915#93]: https://gitlab.freedesktop.org/drm/intel/issues/93
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (11 -> 11)
------------------------------

  No changes in participating hosts


Build changes
-------------

  * Linux: CI_DRM_8658 -> Patchwork_18013

  CI-20190529: 20190529
  CI_DRM_8658: c86979e2fe3c106d95b5fcf2075709afa40f0f95 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5717: 725bf2dae51f0087eaa64f1931a2ef9d22f070dd @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_18013: ff0e9553b262afa612271f33b6f768d8f39093e0 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18013/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v7 02/17] drm/i915: Clear the repeater bit on HDCP disable
  2020-06-23 15:58   ` Sean Paul
  (?)
@ 2020-06-25 14:53     ` Sasha Levin
  -1 siblings, 0 replies; 98+ messages in thread
From: Sasha Levin @ 2020-06-25 14:53 UTC (permalink / raw)
  To: Sasha Levin, Sean Paul, Sean Paul, dri-devel, intel-gfx
  Cc: juston.li, ramalingam.c, Chris Wilson, Ramalingam C,
	Daniel Vetter, Sean Paul, Jani Nikula, Joonas Lahtinen,
	Rodrigo Vivi, intel-gfx, stable

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.7.5, v5.4.48, v4.19.129.

v5.7.5: Build OK!
v5.4.48: Failed to apply! Possible dependencies:
    692059318c0fc ("drm/i915/hdcp: Enable HDCP 1.4 and 2.2 on Gen12+")

v4.19.129: Failed to apply! Possible dependencies:
    0e39037b31655 ("drm/i915: Cache the error string")
    16e4dd0342a80 ("drm/i915: Markup paired operations on wakerefs")
    39e2f501c1b43 ("drm/i915: Split struct intel_context definition to its own header")
    408bd91786665 ("drm/i915: extract intel_hdcp.h from intel_drv.h")
    52c0fdb25c7c9 ("drm/i915: Replace global breadcrumbs with per-context interrupt tracking")
    538ef96b9dae7 ("drm/i915/gem: Track the rpm wakerefs")
    692059318c0fc ("drm/i915/hdcp: Enable HDCP 1.4 and 2.2 on Gen12+")
    6b048706f407f ("drm/i915: Forcibly flush unwanted requests in drop-caches")
    87f1ef225242d ("drm/i915: Record the sseu configuration per-context & engine")
    95fd94a645f75 ("drm/i915: avoid rebuilding i915_gpu_error.o on version string updates")
    c0a6aa7ec2c36 ("drm/i915: Show actual alongside requested frequency in debugfs/i915_rps_boost_info")
    c2400ec3b6d15 ("drm/i915: add Makefile magic for testing headers are self-contained")
    c44301fce6146 ("drm/i915: Allow control of PSR at runtime through debugfs, v6")
    e0516e83640e1 ("drm/i915: Move sandybride pcode access to intel_sideband.c")
    e1ef734eaec54 ("drm/i915: make intel_frontbuffer.h self-contained")
    e6154e4cb8b0d ("drm/i915: Skip the ERR_PTR error state")
    eb8d0f5af4ec2 ("drm/i915: Remove GPU reset dependence on struct_mutex")
    fb6f0b64e455b ("drm/i915: Prevent machine hang from Broxton's vtd w/a and error capture")


NOTE: The patch will not be queued to stable trees until it is upstream.

How should we proceed with this patch?

-- 
Thanks
Sasha

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v7 02/17] drm/i915: Clear the repeater bit on HDCP disable
@ 2020-06-25 14:53     ` Sasha Levin
  0 siblings, 0 replies; 98+ messages in thread
From: Sasha Levin @ 2020-06-25 14:53 UTC (permalink / raw)
  To: Sasha Levin, Sean Paul, Sean Paul, dri-devel, intel-gfx
  Cc: Daniel Vetter, intel-gfx, Chris Wilson, Rodrigo Vivi, Sean Paul,
	stable, juston.li

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.7.5, v5.4.48, v4.19.129.

v5.7.5: Build OK!
v5.4.48: Failed to apply! Possible dependencies:
    692059318c0fc ("drm/i915/hdcp: Enable HDCP 1.4 and 2.2 on Gen12+")

v4.19.129: Failed to apply! Possible dependencies:
    0e39037b31655 ("drm/i915: Cache the error string")
    16e4dd0342a80 ("drm/i915: Markup paired operations on wakerefs")
    39e2f501c1b43 ("drm/i915: Split struct intel_context definition to its own header")
    408bd91786665 ("drm/i915: extract intel_hdcp.h from intel_drv.h")
    52c0fdb25c7c9 ("drm/i915: Replace global breadcrumbs with per-context interrupt tracking")
    538ef96b9dae7 ("drm/i915/gem: Track the rpm wakerefs")
    692059318c0fc ("drm/i915/hdcp: Enable HDCP 1.4 and 2.2 on Gen12+")
    6b048706f407f ("drm/i915: Forcibly flush unwanted requests in drop-caches")
    87f1ef225242d ("drm/i915: Record the sseu configuration per-context & engine")
    95fd94a645f75 ("drm/i915: avoid rebuilding i915_gpu_error.o on version string updates")
    c0a6aa7ec2c36 ("drm/i915: Show actual alongside requested frequency in debugfs/i915_rps_boost_info")
    c2400ec3b6d15 ("drm/i915: add Makefile magic for testing headers are self-contained")
    c44301fce6146 ("drm/i915: Allow control of PSR at runtime through debugfs, v6")
    e0516e83640e1 ("drm/i915: Move sandybride pcode access to intel_sideband.c")
    e1ef734eaec54 ("drm/i915: make intel_frontbuffer.h self-contained")
    e6154e4cb8b0d ("drm/i915: Skip the ERR_PTR error state")
    eb8d0f5af4ec2 ("drm/i915: Remove GPU reset dependence on struct_mutex")
    fb6f0b64e455b ("drm/i915: Prevent machine hang from Broxton's vtd w/a and error capture")


NOTE: The patch will not be queued to stable trees until it is upstream.

How should we proceed with this patch?

-- 
Thanks
Sasha
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 02/17] drm/i915: Clear the repeater bit on HDCP disable
@ 2020-06-25 14:53     ` Sasha Levin
  0 siblings, 0 replies; 98+ messages in thread
From: Sasha Levin @ 2020-06-25 14:53 UTC (permalink / raw)
  To: Sasha Levin, Sean Paul, Sean Paul, dri-devel, intel-gfx
  Cc: Daniel Vetter, intel-gfx, Chris Wilson, Sean Paul, stable

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.7.5, v5.4.48, v4.19.129.

v5.7.5: Build OK!
v5.4.48: Failed to apply! Possible dependencies:
    692059318c0fc ("drm/i915/hdcp: Enable HDCP 1.4 and 2.2 on Gen12+")

v4.19.129: Failed to apply! Possible dependencies:
    0e39037b31655 ("drm/i915: Cache the error string")
    16e4dd0342a80 ("drm/i915: Markup paired operations on wakerefs")
    39e2f501c1b43 ("drm/i915: Split struct intel_context definition to its own header")
    408bd91786665 ("drm/i915: extract intel_hdcp.h from intel_drv.h")
    52c0fdb25c7c9 ("drm/i915: Replace global breadcrumbs with per-context interrupt tracking")
    538ef96b9dae7 ("drm/i915/gem: Track the rpm wakerefs")
    692059318c0fc ("drm/i915/hdcp: Enable HDCP 1.4 and 2.2 on Gen12+")
    6b048706f407f ("drm/i915: Forcibly flush unwanted requests in drop-caches")
    87f1ef225242d ("drm/i915: Record the sseu configuration per-context & engine")
    95fd94a645f75 ("drm/i915: avoid rebuilding i915_gpu_error.o on version string updates")
    c0a6aa7ec2c36 ("drm/i915: Show actual alongside requested frequency in debugfs/i915_rps_boost_info")
    c2400ec3b6d15 ("drm/i915: add Makefile magic for testing headers are self-contained")
    c44301fce6146 ("drm/i915: Allow control of PSR at runtime through debugfs, v6")
    e0516e83640e1 ("drm/i915: Move sandybride pcode access to intel_sideband.c")
    e1ef734eaec54 ("drm/i915: make intel_frontbuffer.h self-contained")
    e6154e4cb8b0d ("drm/i915: Skip the ERR_PTR error state")
    eb8d0f5af4ec2 ("drm/i915: Remove GPU reset dependence on struct_mutex")
    fb6f0b64e455b ("drm/i915: Prevent machine hang from Broxton's vtd w/a and error capture")


NOTE: The patch will not be queued to stable trees until it is upstream.

How should we proceed with this patch?

-- 
Thanks
Sasha
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v7 01/17] drm/i915: Fix sha_text population code
  2020-06-23 15:58   ` Sean Paul
  (?)
@ 2020-06-25 14:53     ` Sasha Levin
  -1 siblings, 0 replies; 98+ messages in thread
From: Sasha Levin @ 2020-06-25 14:53 UTC (permalink / raw)
  To: Sasha Levin, Sean Paul, Sean Paul, dri-devel, intel-gfx
  Cc: juston.li, ramalingam.c, Chris Wilson, Ramalingam C,
	Daniel Vetter, Sean Paul, Jani Nikula, Joonas Lahtinen,
	Rodrigo Vivi, intel-gfx, stable

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.7.5, v5.4.48, v4.19.129.

v5.7.5: Build OK!
v5.4.48: Failed to apply! Possible dependencies:
    65833c463886f ("drm/i915/hdcp: conversion to struct drm_device based logging macros.")
    667944ad77f19 ("drm/i915/hdcp: use intel_de_*() functions for register access")
    692059318c0fc ("drm/i915/hdcp: Enable HDCP 1.4 and 2.2 on Gen12+")

v4.19.129: Failed to apply! Possible dependencies:
    04707f9716363 ("drm/i915: Initialize HDCP2.2")
    09d56393c1d8d ("drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking")
    2f80d7bd8d93c ("drm/i915: drop all drmP.h includes")
    33b7f3ee6e008 ("drm/i915: Add CRTC output format YCBCR 4:2:0")
    340a44bef2342 ("drm/i915/icl: program MG_DP_MODE")
    342ac601df642 ("drm/i915: hdcp_check_link only on CP_IRQ")
    47658556da857 ("drm/i915/dp: Do not grab crtc modeset lock in intel_dp_detect()")
    667944ad77f19 ("drm/i915/hdcp: use intel_de_*() functions for register access")
    668b6c176c33f ("drm/i915: Add YCBCR 4:2:0/4:4:4 support for LSPCON")
    7b610f1fbed2a ("drm/i915/dp: Add DSC params and DSC config to intel_crtc_state")
    9055aac76589c ("drm/i915: MEI interface implementation")
    9844bc87cb7a5 ("drm/i915/dp: Fix duplication of DEVICE_SERVICE_IRQ handling")
    bdc93fe0eb82f ("drm/i915/debugfs: hdcp capability of a sink")
    cbfa8ac835cb4 ("drm/i915/dp: Kill intel_dp->detect_done flag")
    d3dacc70797b8 ("drm/i915: wrapping all hdcp var into intel_hdcp")
    d5acd97f55711 ("drm/i915/dp: Use a local variable for intel_encoder *")
    d78aa650670d2 ("drm: Add drm/drm_util.h header file")
    de25eb7f3075f ("drm/i915: introduce dp_to_i915() helper")
    f106d1005ac72 ("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?

-- 
Thanks
Sasha

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v7 01/17] drm/i915: Fix sha_text population code
@ 2020-06-25 14:53     ` Sasha Levin
  0 siblings, 0 replies; 98+ messages in thread
From: Sasha Levin @ 2020-06-25 14:53 UTC (permalink / raw)
  To: Sasha Levin, Sean Paul, Sean Paul, dri-devel, intel-gfx
  Cc: Daniel Vetter, intel-gfx, Chris Wilson, Rodrigo Vivi, Sean Paul,
	stable, juston.li

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.7.5, v5.4.48, v4.19.129.

v5.7.5: Build OK!
v5.4.48: Failed to apply! Possible dependencies:
    65833c463886f ("drm/i915/hdcp: conversion to struct drm_device based logging macros.")
    667944ad77f19 ("drm/i915/hdcp: use intel_de_*() functions for register access")
    692059318c0fc ("drm/i915/hdcp: Enable HDCP 1.4 and 2.2 on Gen12+")

v4.19.129: Failed to apply! Possible dependencies:
    04707f9716363 ("drm/i915: Initialize HDCP2.2")
    09d56393c1d8d ("drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking")
    2f80d7bd8d93c ("drm/i915: drop all drmP.h includes")
    33b7f3ee6e008 ("drm/i915: Add CRTC output format YCBCR 4:2:0")
    340a44bef2342 ("drm/i915/icl: program MG_DP_MODE")
    342ac601df642 ("drm/i915: hdcp_check_link only on CP_IRQ")
    47658556da857 ("drm/i915/dp: Do not grab crtc modeset lock in intel_dp_detect()")
    667944ad77f19 ("drm/i915/hdcp: use intel_de_*() functions for register access")
    668b6c176c33f ("drm/i915: Add YCBCR 4:2:0/4:4:4 support for LSPCON")
    7b610f1fbed2a ("drm/i915/dp: Add DSC params and DSC config to intel_crtc_state")
    9055aac76589c ("drm/i915: MEI interface implementation")
    9844bc87cb7a5 ("drm/i915/dp: Fix duplication of DEVICE_SERVICE_IRQ handling")
    bdc93fe0eb82f ("drm/i915/debugfs: hdcp capability of a sink")
    cbfa8ac835cb4 ("drm/i915/dp: Kill intel_dp->detect_done flag")
    d3dacc70797b8 ("drm/i915: wrapping all hdcp var into intel_hdcp")
    d5acd97f55711 ("drm/i915/dp: Use a local variable for intel_encoder *")
    d78aa650670d2 ("drm: Add drm/drm_util.h header file")
    de25eb7f3075f ("drm/i915: introduce dp_to_i915() helper")
    f106d1005ac72 ("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?

-- 
Thanks
Sasha
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 01/17] drm/i915: Fix sha_text population code
@ 2020-06-25 14:53     ` Sasha Levin
  0 siblings, 0 replies; 98+ messages in thread
From: Sasha Levin @ 2020-06-25 14:53 UTC (permalink / raw)
  To: Sasha Levin, Sean Paul, Sean Paul, dri-devel, intel-gfx
  Cc: Daniel Vetter, intel-gfx, Chris Wilson, Sean Paul, stable

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.7.5, v5.4.48, v4.19.129.

v5.7.5: Build OK!
v5.4.48: Failed to apply! Possible dependencies:
    65833c463886f ("drm/i915/hdcp: conversion to struct drm_device based logging macros.")
    667944ad77f19 ("drm/i915/hdcp: use intel_de_*() functions for register access")
    692059318c0fc ("drm/i915/hdcp: Enable HDCP 1.4 and 2.2 on Gen12+")

v4.19.129: Failed to apply! Possible dependencies:
    04707f9716363 ("drm/i915: Initialize HDCP2.2")
    09d56393c1d8d ("drm/i915: hdcp1.4 CP_IRQ handling and SW encryption tracking")
    2f80d7bd8d93c ("drm/i915: drop all drmP.h includes")
    33b7f3ee6e008 ("drm/i915: Add CRTC output format YCBCR 4:2:0")
    340a44bef2342 ("drm/i915/icl: program MG_DP_MODE")
    342ac601df642 ("drm/i915: hdcp_check_link only on CP_IRQ")
    47658556da857 ("drm/i915/dp: Do not grab crtc modeset lock in intel_dp_detect()")
    667944ad77f19 ("drm/i915/hdcp: use intel_de_*() functions for register access")
    668b6c176c33f ("drm/i915: Add YCBCR 4:2:0/4:4:4 support for LSPCON")
    7b610f1fbed2a ("drm/i915/dp: Add DSC params and DSC config to intel_crtc_state")
    9055aac76589c ("drm/i915: MEI interface implementation")
    9844bc87cb7a5 ("drm/i915/dp: Fix duplication of DEVICE_SERVICE_IRQ handling")
    bdc93fe0eb82f ("drm/i915/debugfs: hdcp capability of a sink")
    cbfa8ac835cb4 ("drm/i915/dp: Kill intel_dp->detect_done flag")
    d3dacc70797b8 ("drm/i915: wrapping all hdcp var into intel_hdcp")
    d5acd97f55711 ("drm/i915/dp: Use a local variable for intel_encoder *")
    d78aa650670d2 ("drm: Add drm/drm_util.h header file")
    de25eb7f3075f ("drm/i915: introduce dp_to_i915() helper")
    f106d1005ac72 ("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?

-- 
Thanks
Sasha
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
  2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
@ 2020-06-30 14:09     ` Anshuman Gupta
  -1 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-06-30 14:09 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-06-23 at 21:29:05 +0530, Sean Paul wrote:
Hi Sean,
I am new to DP MST stuff, I am looking to DP MST spec DP v1.2a.
I have looked the entire series, i will take up this opportunity to review
the series from HDCP over DP MST POV.
I think theoretically this series should work or Gen12 as well, as DP MST streams
are getting encrypted by QUERY_STREAM_ENCRYPTION_STATUS reply tranaction msg
(generating Stream State Signature L’).
I will test this on Gen12 H/W with DP MST support and will provide my inputs.

Meanwhile while going through DP MST v1.2a specs(Page 262) came to know about 
a DP irq vector LINK_SERVICE_IRQ_VECTOR_ESI0 (02005h),
Bit 2 : STREAM_STATUS_CHANGED.
When this bit set to ‘1’ indicates the source must re-check the Stream Status
with the QUERY_STREAM_ENCRYPTION_STATUS message.
Currently i feel this irq support is missing, do we require to support
above IRQ vector for DP MST stream encryption.

Thanks,
Anshuman Gupta.

> From: Sean Paul <seanpaul@chromium.org>
> 
> Used to query whether an MST stream is encrypted or not.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> 
> Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6
> 
> Changes in v4:
> -Added to the set
> Changes in v5:
> -None
> Changes in v6:
> -Use FIELD_PREP to generate request buffer bitfields (Lyude)
> -Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
> Changes in v7:
> -None
> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
>  .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
>  include/drm/drm_dp_helper.h                   |   3 +
>  include/drm/drm_dp_mst_helper.h               |  44 ++++++
>  4 files changed, 206 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> index b2f5a84b4cfb..fc68478eaeb4 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -20,11 +20,13 @@
>   * OF THIS SOFTWARE.
>   */
>  
> +#include <linux/bitfield.h>
>  #include <linux/delay.h>
>  #include <linux/errno.h>
>  #include <linux/i2c.h>
>  #include <linux/init.h>
>  #include <linux/kernel.h>
> +#include <linux/random.h>
>  #include <linux/sched.h>
>  #include <linux/seq_file.h>
>  #include <linux/iopoll.h>
> @@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
>  		memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
>  		idx += req->u.i2c_write.num_bytes;
>  		break;
> +	case DP_QUERY_STREAM_ENC_STATUS: {
> +		const struct drm_dp_query_stream_enc_status *msg;
> +
> +		msg = &req->u.enc_status;
> +		buf[idx] = msg->stream_id;
> +		idx++;
> +		memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
> +		idx += sizeof(msg->client_id);
> +		buf[idx] = 0;
> +		buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
> +		buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
> +		buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
> +		buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
> +		idx++;
> +		}
> +		break;
>  	}
>  	raw->cur_len = idx;
>  }
> @@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
>  				return -ENOMEM;
>  		}
>  		break;
> +	case DP_QUERY_STREAM_ENC_STATUS:
> +		req->u.enc_status.stream_id = buf[idx++];
> +		for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
> +			req->u.enc_status.client_id[i] = buf[idx++];
> +
> +		req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
> +							   buf[idx]);
> +		req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
> +							 	 buf[idx]);
> +		req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
> +							      buf[idx]);
> +		req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
> +								    buf[idx]);
> +		break;
>  	}
>  
>  	return 0;
> @@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
>  		  req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
>  		  req->u.i2c_write.bytes);
>  		break;
> +	case DP_QUERY_STREAM_ENC_STATUS:
> +		P("stream_id=%u client_id=%*ph stream_event=%x "
> +		  "valid_event=%d stream_behavior=%x valid_behavior=%d",
> +		  req->u.enc_status.stream_id,
> +		  (int)ARRAY_SIZE(req->u.enc_status.client_id),
> +		  req->u.enc_status.client_id, req->u.enc_status.stream_event,
> +		  req->u.enc_status.valid_stream_event,
> +		  req->u.enc_status.stream_behavior,
> +		  req->u.enc_status.valid_stream_behavior);
> +		break;
>  	default:
>  		P("???\n");
>  		break;
> @@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
>  	return true;
>  }
>  
> +static bool
> +drm_dp_sideband_parse_query_stream_enc_status(
> +				struct drm_dp_sideband_msg_rx *raw,
> +				struct drm_dp_sideband_msg_reply_body *repmsg)
> +{
> +	struct drm_dp_query_stream_enc_status_ack_reply *reply;
> +
> +	reply = &repmsg->u.enc_status;
> +
> +	reply->stream_id = raw->msg[3];
> +
> +	reply->reply_signed = raw->msg[2] & BIT(0);
> +
> +	reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> +	reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
> +
> +	reply->query_capable_device_present = raw->msg[2] & BIT(5);
> +	reply->legacy_device_present = raw->msg[2] & BIT(6);
> +	reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> +
> +	reply->auth_completed = !!(raw->msg[1] & BIT(3));
> +	reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> +	reply->repeater_present = !!(raw->msg[1] & BIT(5));
> +	reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> +
> +	return true;
> +}
> +
>  static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
>  					struct drm_dp_sideband_msg_reply_body *msg)
>  {
> @@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
>  		return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
>  	case DP_CLEAR_PAYLOAD_ID_TABLE:
>  		return true; /* since there's nothing to parse */
> +	case DP_QUERY_STREAM_ENC_STATUS:
> +		return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
>  	default:
>  		DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
>  			  drm_dp_mst_req_type_str(msg->req_type));
> @@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
>  	msg->path_msg = true;
>  }
>  
> +static int
> +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
> +			      u8 *q_id)
> +{
> +	struct drm_dp_sideband_msg_req_body req;
> +
> +	req.req_type = DP_QUERY_STREAM_ENC_STATUS;
> +	req.u.enc_status.stream_id = stream_id;
> +	memcpy(req.u.enc_status.client_id, q_id,
> +	       sizeof(req.u.enc_status.client_id));
> +	req.u.enc_status.stream_event = 0;
> +	req.u.enc_status.valid_stream_event = false;
> +	req.u.enc_status.stream_behavior = 0;
> +	req.u.enc_status.valid_stream_behavior = false;
> +
> +	drm_dp_encode_sideband_req(&req, msg);
> +	return 0;
> +}
> +
>  static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
>  					struct drm_dp_vcpi *vcpi)
>  {
> @@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
>  }
>  EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
>  
> +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> +		struct drm_dp_mst_port *port,
> +		struct drm_dp_query_stream_enc_status_ack_reply *status)
> +{
> +	struct drm_dp_sideband_msg_tx *txmsg;
> +	u8 nonce[7];
> +	int len, ret;
> +
> +	txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> +	if (!txmsg)
> +		return -ENOMEM;
> +
> +	port = drm_dp_mst_topology_get_port_validated(mgr, port);
> +	if (!port) {
> +		ret = -EINVAL;
> +		goto out_get_port;
> +	}
> +
> +	get_random_bytes(nonce, sizeof(nonce));
> +
> +	/*
> +	 * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
> +	 *  transaction at the MST Branch device directly connected to the
> +	 *  Source"
> +	 */
> +	txmsg->dst = mgr->mst_primary;
> +
> +	len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
> +
> +	drm_dp_queue_down_tx(mgr, txmsg);
> +
> +	ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
> +	if (ret < 0) {
> +		goto out;
> +	} else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
> +		DRM_DEBUG_KMS("query encryption status nak received\n");
> +		ret = -ENXIO;
> +		goto out;
> +	}
> +
> +	ret = 0;
> +	memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
> +
> +out:
> +	drm_dp_mst_topology_put_port(port);
> +out_get_port:
> +	kfree(txmsg);
> +	return ret;
> +}
> +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
> +
>  static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
>  				       int id,
>  				       struct drm_dp_payload *payload)
> diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> index bd990d178765..1d696ec001cf 100644
> --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> @@ -5,6 +5,8 @@
>  
>  #define PREFIX_STR "[drm_dp_mst_helper]"
>  
> +#include <linux/random.h>
> +
>  #include <drm/drm_dp_mst_helper.h>
>  #include <drm/drm_print.h>
>  
> @@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
>  	in.u.i2c_write.bytes = data;
>  	DO_TEST();
>  
> +	in.req_type = DP_QUERY_STREAM_ENC_STATUS;
> +	in.u.enc_status.stream_id = 1;
> +	DO_TEST();
> +	get_random_bytes(in.u.enc_status.client_id,
> +			 sizeof(in.u.enc_status.client_id));
> +	DO_TEST();
> +	in.u.enc_status.stream_event = 3;
> +	DO_TEST();
> +	in.u.enc_status.valid_stream_event = 0;
> +	DO_TEST();
> +	in.u.enc_status.stream_behavior = 3;
> +	DO_TEST();
> +	in.u.enc_status.valid_stream_behavior = 1;
> +	DO_TEST();
> +
>  #undef DO_TEST
>  	return 0;
>  }
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index e47dc22ebf50..e2d2df5e869e 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -1108,6 +1108,9 @@
>  #define DP_POWER_DOWN_PHY		0x25
>  #define DP_SINK_EVENT_NOTIFY		0x30
>  #define DP_QUERY_STREAM_ENC_STATUS	0x38
> +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST	0
> +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE	1
> +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE	2
>  
>  /* DP 1.2 MST sideband reply types */
>  #define DP_SIDEBAND_REPLY_ACK		0x00
> diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> index 8b9eb4db3381..371eef8798ad 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
>  	u8 port_number;
>  };
>  
> +struct drm_dp_query_stream_enc_status_ack_reply {
> +	/* Bit[23:16]- Stream Id */
> +	u8 stream_id;
> +
> +	/* Bit[15]- Signed */
> +	bool reply_signed;
> +
> +	/* Bit[10:8]- Stream Output Sink Type */
> +	bool unauthorizable_device_present;
> +	bool legacy_device_present;
> +	bool query_capable_device_present;
> +
> +	/* Bit[12:11]- Stream Output CP Type */
> +	bool hdcp_1x_device_present;
> +	bool hdcp_2x_device_present;
> +
> +	/* Bit[4]- Stream Authentication */
> +	bool auth_completed;
> +
> +	/* Bit[3]- Stream Encryption */
> +	bool encryption_enabled;
> +
> +	/* Bit[2]- Stream Repeater Function Present */
> +	bool repeater_present;
> +
> +	/* Bit[1:0]- Stream State */
> +	u8 state;
> +};
>  
>  #define DRM_DP_MAX_SDP_STREAMS 16
>  struct drm_dp_allocate_payload {
> @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
>  	u8 *bytes;
>  };
>  
> +struct drm_dp_query_stream_enc_status {
> +	u8 stream_id;
> +	u8 client_id[7];	/* 56-bit nonce */
> +	u8 stream_event;
> +	bool valid_stream_event;
> +	u8 stream_behavior;
> +	u8 valid_stream_behavior;
> +};
> +
>  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
>  struct drm_dp_port_number_req {
>  	u8 port_number;
> @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
>  
>  		struct drm_dp_remote_i2c_read i2c_read;
>  		struct drm_dp_remote_i2c_write i2c_write;
> +
> +		struct drm_dp_query_stream_enc_status enc_status;
>  	} u;
>  };
>  
> @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
>  		struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
>  		struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
>  		struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> +
> +		struct drm_dp_query_stream_enc_status_ack_reply enc_status;
>  	} u;
>  };
>  
> @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
>  				 struct drm_dp_mst_port *port);
>  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
>  				 struct drm_dp_mst_port *port, bool power_up);
> +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> +		struct drm_dp_mst_port *port,
> +		struct drm_dp_query_stream_enc_status_ack_reply *status);
>  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
>  
>  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
@ 2020-06-30 14:09     ` Anshuman Gupta
  0 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-06-30 14:09 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-06-23 at 21:29:05 +0530, Sean Paul wrote:
Hi Sean,
I am new to DP MST stuff, I am looking to DP MST spec DP v1.2a.
I have looked the entire series, i will take up this opportunity to review
the series from HDCP over DP MST POV.
I think theoretically this series should work or Gen12 as well, as DP MST streams
are getting encrypted by QUERY_STREAM_ENCRYPTION_STATUS reply tranaction msg
(generating Stream State Signature L’).
I will test this on Gen12 H/W with DP MST support and will provide my inputs.

Meanwhile while going through DP MST v1.2a specs(Page 262) came to know about 
a DP irq vector LINK_SERVICE_IRQ_VECTOR_ESI0 (02005h),
Bit 2 : STREAM_STATUS_CHANGED.
When this bit set to ‘1’ indicates the source must re-check the Stream Status
with the QUERY_STREAM_ENCRYPTION_STATUS message.
Currently i feel this irq support is missing, do we require to support
above IRQ vector for DP MST stream encryption.

Thanks,
Anshuman Gupta.

> From: Sean Paul <seanpaul@chromium.org>
> 
> Used to query whether an MST stream is encrypted or not.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> 
> Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6
> 
> Changes in v4:
> -Added to the set
> Changes in v5:
> -None
> Changes in v6:
> -Use FIELD_PREP to generate request buffer bitfields (Lyude)
> -Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
> Changes in v7:
> -None
> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
>  .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
>  include/drm/drm_dp_helper.h                   |   3 +
>  include/drm/drm_dp_mst_helper.h               |  44 ++++++
>  4 files changed, 206 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> index b2f5a84b4cfb..fc68478eaeb4 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -20,11 +20,13 @@
>   * OF THIS SOFTWARE.
>   */
>  
> +#include <linux/bitfield.h>
>  #include <linux/delay.h>
>  #include <linux/errno.h>
>  #include <linux/i2c.h>
>  #include <linux/init.h>
>  #include <linux/kernel.h>
> +#include <linux/random.h>
>  #include <linux/sched.h>
>  #include <linux/seq_file.h>
>  #include <linux/iopoll.h>
> @@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
>  		memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
>  		idx += req->u.i2c_write.num_bytes;
>  		break;
> +	case DP_QUERY_STREAM_ENC_STATUS: {
> +		const struct drm_dp_query_stream_enc_status *msg;
> +
> +		msg = &req->u.enc_status;
> +		buf[idx] = msg->stream_id;
> +		idx++;
> +		memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
> +		idx += sizeof(msg->client_id);
> +		buf[idx] = 0;
> +		buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
> +		buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
> +		buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
> +		buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
> +		idx++;
> +		}
> +		break;
>  	}
>  	raw->cur_len = idx;
>  }
> @@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
>  				return -ENOMEM;
>  		}
>  		break;
> +	case DP_QUERY_STREAM_ENC_STATUS:
> +		req->u.enc_status.stream_id = buf[idx++];
> +		for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
> +			req->u.enc_status.client_id[i] = buf[idx++];
> +
> +		req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
> +							   buf[idx]);
> +		req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
> +							 	 buf[idx]);
> +		req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
> +							      buf[idx]);
> +		req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
> +								    buf[idx]);
> +		break;
>  	}
>  
>  	return 0;
> @@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
>  		  req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
>  		  req->u.i2c_write.bytes);
>  		break;
> +	case DP_QUERY_STREAM_ENC_STATUS:
> +		P("stream_id=%u client_id=%*ph stream_event=%x "
> +		  "valid_event=%d stream_behavior=%x valid_behavior=%d",
> +		  req->u.enc_status.stream_id,
> +		  (int)ARRAY_SIZE(req->u.enc_status.client_id),
> +		  req->u.enc_status.client_id, req->u.enc_status.stream_event,
> +		  req->u.enc_status.valid_stream_event,
> +		  req->u.enc_status.stream_behavior,
> +		  req->u.enc_status.valid_stream_behavior);
> +		break;
>  	default:
>  		P("???\n");
>  		break;
> @@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
>  	return true;
>  }
>  
> +static bool
> +drm_dp_sideband_parse_query_stream_enc_status(
> +				struct drm_dp_sideband_msg_rx *raw,
> +				struct drm_dp_sideband_msg_reply_body *repmsg)
> +{
> +	struct drm_dp_query_stream_enc_status_ack_reply *reply;
> +
> +	reply = &repmsg->u.enc_status;
> +
> +	reply->stream_id = raw->msg[3];
> +
> +	reply->reply_signed = raw->msg[2] & BIT(0);
> +
> +	reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> +	reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
> +
> +	reply->query_capable_device_present = raw->msg[2] & BIT(5);
> +	reply->legacy_device_present = raw->msg[2] & BIT(6);
> +	reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> +
> +	reply->auth_completed = !!(raw->msg[1] & BIT(3));
> +	reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> +	reply->repeater_present = !!(raw->msg[1] & BIT(5));
> +	reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> +
> +	return true;
> +}
> +
>  static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
>  					struct drm_dp_sideband_msg_reply_body *msg)
>  {
> @@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
>  		return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
>  	case DP_CLEAR_PAYLOAD_ID_TABLE:
>  		return true; /* since there's nothing to parse */
> +	case DP_QUERY_STREAM_ENC_STATUS:
> +		return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
>  	default:
>  		DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
>  			  drm_dp_mst_req_type_str(msg->req_type));
> @@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
>  	msg->path_msg = true;
>  }
>  
> +static int
> +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
> +			      u8 *q_id)
> +{
> +	struct drm_dp_sideband_msg_req_body req;
> +
> +	req.req_type = DP_QUERY_STREAM_ENC_STATUS;
> +	req.u.enc_status.stream_id = stream_id;
> +	memcpy(req.u.enc_status.client_id, q_id,
> +	       sizeof(req.u.enc_status.client_id));
> +	req.u.enc_status.stream_event = 0;
> +	req.u.enc_status.valid_stream_event = false;
> +	req.u.enc_status.stream_behavior = 0;
> +	req.u.enc_status.valid_stream_behavior = false;
> +
> +	drm_dp_encode_sideband_req(&req, msg);
> +	return 0;
> +}
> +
>  static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
>  					struct drm_dp_vcpi *vcpi)
>  {
> @@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
>  }
>  EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
>  
> +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> +		struct drm_dp_mst_port *port,
> +		struct drm_dp_query_stream_enc_status_ack_reply *status)
> +{
> +	struct drm_dp_sideband_msg_tx *txmsg;
> +	u8 nonce[7];
> +	int len, ret;
> +
> +	txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> +	if (!txmsg)
> +		return -ENOMEM;
> +
> +	port = drm_dp_mst_topology_get_port_validated(mgr, port);
> +	if (!port) {
> +		ret = -EINVAL;
> +		goto out_get_port;
> +	}
> +
> +	get_random_bytes(nonce, sizeof(nonce));
> +
> +	/*
> +	 * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
> +	 *  transaction at the MST Branch device directly connected to the
> +	 *  Source"
> +	 */
> +	txmsg->dst = mgr->mst_primary;
> +
> +	len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
> +
> +	drm_dp_queue_down_tx(mgr, txmsg);
> +
> +	ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
> +	if (ret < 0) {
> +		goto out;
> +	} else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
> +		DRM_DEBUG_KMS("query encryption status nak received\n");
> +		ret = -ENXIO;
> +		goto out;
> +	}
> +
> +	ret = 0;
> +	memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
> +
> +out:
> +	drm_dp_mst_topology_put_port(port);
> +out_get_port:
> +	kfree(txmsg);
> +	return ret;
> +}
> +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
> +
>  static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
>  				       int id,
>  				       struct drm_dp_payload *payload)
> diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> index bd990d178765..1d696ec001cf 100644
> --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> @@ -5,6 +5,8 @@
>  
>  #define PREFIX_STR "[drm_dp_mst_helper]"
>  
> +#include <linux/random.h>
> +
>  #include <drm/drm_dp_mst_helper.h>
>  #include <drm/drm_print.h>
>  
> @@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
>  	in.u.i2c_write.bytes = data;
>  	DO_TEST();
>  
> +	in.req_type = DP_QUERY_STREAM_ENC_STATUS;
> +	in.u.enc_status.stream_id = 1;
> +	DO_TEST();
> +	get_random_bytes(in.u.enc_status.client_id,
> +			 sizeof(in.u.enc_status.client_id));
> +	DO_TEST();
> +	in.u.enc_status.stream_event = 3;
> +	DO_TEST();
> +	in.u.enc_status.valid_stream_event = 0;
> +	DO_TEST();
> +	in.u.enc_status.stream_behavior = 3;
> +	DO_TEST();
> +	in.u.enc_status.valid_stream_behavior = 1;
> +	DO_TEST();
> +
>  #undef DO_TEST
>  	return 0;
>  }
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index e47dc22ebf50..e2d2df5e869e 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -1108,6 +1108,9 @@
>  #define DP_POWER_DOWN_PHY		0x25
>  #define DP_SINK_EVENT_NOTIFY		0x30
>  #define DP_QUERY_STREAM_ENC_STATUS	0x38
> +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST	0
> +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE	1
> +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE	2
>  
>  /* DP 1.2 MST sideband reply types */
>  #define DP_SIDEBAND_REPLY_ACK		0x00
> diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> index 8b9eb4db3381..371eef8798ad 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
>  	u8 port_number;
>  };
>  
> +struct drm_dp_query_stream_enc_status_ack_reply {
> +	/* Bit[23:16]- Stream Id */
> +	u8 stream_id;
> +
> +	/* Bit[15]- Signed */
> +	bool reply_signed;
> +
> +	/* Bit[10:8]- Stream Output Sink Type */
> +	bool unauthorizable_device_present;
> +	bool legacy_device_present;
> +	bool query_capable_device_present;
> +
> +	/* Bit[12:11]- Stream Output CP Type */
> +	bool hdcp_1x_device_present;
> +	bool hdcp_2x_device_present;
> +
> +	/* Bit[4]- Stream Authentication */
> +	bool auth_completed;
> +
> +	/* Bit[3]- Stream Encryption */
> +	bool encryption_enabled;
> +
> +	/* Bit[2]- Stream Repeater Function Present */
> +	bool repeater_present;
> +
> +	/* Bit[1:0]- Stream State */
> +	u8 state;
> +};
>  
>  #define DRM_DP_MAX_SDP_STREAMS 16
>  struct drm_dp_allocate_payload {
> @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
>  	u8 *bytes;
>  };
>  
> +struct drm_dp_query_stream_enc_status {
> +	u8 stream_id;
> +	u8 client_id[7];	/* 56-bit nonce */
> +	u8 stream_event;
> +	bool valid_stream_event;
> +	u8 stream_behavior;
> +	u8 valid_stream_behavior;
> +};
> +
>  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
>  struct drm_dp_port_number_req {
>  	u8 port_number;
> @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
>  
>  		struct drm_dp_remote_i2c_read i2c_read;
>  		struct drm_dp_remote_i2c_write i2c_write;
> +
> +		struct drm_dp_query_stream_enc_status enc_status;
>  	} u;
>  };
>  
> @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
>  		struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
>  		struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
>  		struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> +
> +		struct drm_dp_query_stream_enc_status_ack_reply enc_status;
>  	} u;
>  };
>  
> @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
>  				 struct drm_dp_mst_port *port);
>  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
>  				 struct drm_dp_mst_port *port, bool power_up);
> +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> +		struct drm_dp_mst_port *port,
> +		struct drm_dp_query_stream_enc_status_ack_reply *status);
>  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
>  
>  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
  2020-06-30 14:09     ` Anshuman Gupta
@ 2020-06-30 16:48       ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-30 16:48 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On Tue, Jun 30, 2020 at 10:21 AM Anshuman Gupta
<anshuman.gupta@intel.com> wrote:
>
> On 2020-06-23 at 21:29:05 +0530, Sean Paul wrote:
> Hi Sean,
> I am new to DP MST stuff, I am looking to DP MST spec DP v1.2a.
> I have looked the entire series, i will take up this opportunity to review
> the series from HDCP over DP MST POV.
> I think theoretically this series should work or Gen12 as well, as DP MST streams
> are getting encrypted by QUERY_STREAM_ENCRYPTION_STATUS reply tranaction msg
> (generating Stream State Signature L’).
> I will test this on Gen12 H/W with DP MST support and will provide my inputs.
>
> Meanwhile while going through DP MST v1.2a specs(Page 262) came to know about
> a DP irq vector LINK_SERVICE_IRQ_VECTOR_ESI0 (02005h),
> Bit 2 : STREAM_STATUS_CHANGED.
> When this bit set to ‘1’ indicates the source must re-check the Stream Status
> with the QUERY_STREAM_ENCRYPTION_STATUS message.
> Currently i feel this irq support is missing, do we require to support
> above IRQ vector for DP MST stream encryption.
>

Hi Anshuman,
Thank you for your comments.

QUERY_STREAM_ENCRYPTION_STATUS is not necessary for HDCP 1.x, I added
this as a safety check to ensure that the streams were being
encrypted. As such, the existing integrity checks in place for DP are
sufficient to satisfy spec. When HDCP 2.2 support is added for MST,
handling QSES will need to be addressed to meet spec. Note also that
we're not validating the QSES signature for the same reason.

Sean


> Thanks,
> Anshuman Gupta.
>
> > From: Sean Paul <seanpaul@chromium.org>
> >
> > Used to query whether an MST stream is encrypted or not.
> >
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> >
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6
> >
> > Changes in v4:
> > -Added to the set
> > Changes in v5:
> > -None
> > Changes in v6:
> > -Use FIELD_PREP to generate request buffer bitfields (Lyude)
> > -Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
> > Changes in v7:
> > -None
> > ---
> >  drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
> >  .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
> >  include/drm/drm_dp_helper.h                   |   3 +
> >  include/drm/drm_dp_mst_helper.h               |  44 ++++++
> >  4 files changed, 206 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> > index b2f5a84b4cfb..fc68478eaeb4 100644
> > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > @@ -20,11 +20,13 @@
> >   * OF THIS SOFTWARE.
> >   */
> >
> > +#include <linux/bitfield.h>
> >  #include <linux/delay.h>
> >  #include <linux/errno.h>
> >  #include <linux/i2c.h>
> >  #include <linux/init.h>
> >  #include <linux/kernel.h>
> > +#include <linux/random.h>
> >  #include <linux/sched.h>
> >  #include <linux/seq_file.h>
> >  #include <linux/iopoll.h>
> > @@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
> >               memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
> >               idx += req->u.i2c_write.num_bytes;
> >               break;
> > +     case DP_QUERY_STREAM_ENC_STATUS: {
> > +             const struct drm_dp_query_stream_enc_status *msg;
> > +
> > +             msg = &req->u.enc_status;
> > +             buf[idx] = msg->stream_id;
> > +             idx++;
> > +             memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
> > +             idx += sizeof(msg->client_id);
> > +             buf[idx] = 0;
> > +             buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
> > +             buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
> > +             buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
> > +             buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
> > +             idx++;
> > +             }
> > +             break;
> >       }
> >       raw->cur_len = idx;
> >  }
> > @@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
> >                               return -ENOMEM;
> >               }
> >               break;
> > +     case DP_QUERY_STREAM_ENC_STATUS:
> > +             req->u.enc_status.stream_id = buf[idx++];
> > +             for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
> > +                     req->u.enc_status.client_id[i] = buf[idx++];
> > +
> > +             req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
> > +                                                        buf[idx]);
> > +             req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
> > +                                                              buf[idx]);
> > +             req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
> > +                                                           buf[idx]);
> > +             req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
> > +                                                                 buf[idx]);
> > +             break;
> >       }
> >
> >       return 0;
> > @@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
> >                 req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
> >                 req->u.i2c_write.bytes);
> >               break;
> > +     case DP_QUERY_STREAM_ENC_STATUS:
> > +             P("stream_id=%u client_id=%*ph stream_event=%x "
> > +               "valid_event=%d stream_behavior=%x valid_behavior=%d",
> > +               req->u.enc_status.stream_id,
> > +               (int)ARRAY_SIZE(req->u.enc_status.client_id),
> > +               req->u.enc_status.client_id, req->u.enc_status.stream_event,
> > +               req->u.enc_status.valid_stream_event,
> > +               req->u.enc_status.stream_behavior,
> > +               req->u.enc_status.valid_stream_behavior);
> > +             break;
> >       default:
> >               P("???\n");
> >               break;
> > @@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
> >       return true;
> >  }
> >
> > +static bool
> > +drm_dp_sideband_parse_query_stream_enc_status(
> > +                             struct drm_dp_sideband_msg_rx *raw,
> > +                             struct drm_dp_sideband_msg_reply_body *repmsg)
> > +{
> > +     struct drm_dp_query_stream_enc_status_ack_reply *reply;
> > +
> > +     reply = &repmsg->u.enc_status;
> > +
> > +     reply->stream_id = raw->msg[3];
> > +
> > +     reply->reply_signed = raw->msg[2] & BIT(0);
> > +
> > +     reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> > +     reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
> > +
> > +     reply->query_capable_device_present = raw->msg[2] & BIT(5);
> > +     reply->legacy_device_present = raw->msg[2] & BIT(6);
> > +     reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> > +
> > +     reply->auth_completed = !!(raw->msg[1] & BIT(3));
> > +     reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> > +     reply->repeater_present = !!(raw->msg[1] & BIT(5));
> > +     reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> > +
> > +     return true;
> > +}
> > +
> >  static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> >                                       struct drm_dp_sideband_msg_reply_body *msg)
> >  {
> > @@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> >               return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
> >       case DP_CLEAR_PAYLOAD_ID_TABLE:
> >               return true; /* since there's nothing to parse */
> > +     case DP_QUERY_STREAM_ENC_STATUS:
> > +             return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
> >       default:
> >               DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
> >                         drm_dp_mst_req_type_str(msg->req_type));
> > @@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
> >       msg->path_msg = true;
> >  }
> >
> > +static int
> > +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
> > +                           u8 *q_id)
> > +{
> > +     struct drm_dp_sideband_msg_req_body req;
> > +
> > +     req.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > +     req.u.enc_status.stream_id = stream_id;
> > +     memcpy(req.u.enc_status.client_id, q_id,
> > +            sizeof(req.u.enc_status.client_id));
> > +     req.u.enc_status.stream_event = 0;
> > +     req.u.enc_status.valid_stream_event = false;
> > +     req.u.enc_status.stream_behavior = 0;
> > +     req.u.enc_status.valid_stream_behavior = false;
> > +
> > +     drm_dp_encode_sideband_req(&req, msg);
> > +     return 0;
> > +}
> > +
> >  static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
> >                                       struct drm_dp_vcpi *vcpi)
> >  {
> > @@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> >  }
> >  EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
> >
> > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > +             struct drm_dp_mst_port *port,
> > +             struct drm_dp_query_stream_enc_status_ack_reply *status)
> > +{
> > +     struct drm_dp_sideband_msg_tx *txmsg;
> > +     u8 nonce[7];
> > +     int len, ret;
> > +
> > +     txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> > +     if (!txmsg)
> > +             return -ENOMEM;
> > +
> > +     port = drm_dp_mst_topology_get_port_validated(mgr, port);
> > +     if (!port) {
> > +             ret = -EINVAL;
> > +             goto out_get_port;
> > +     }
> > +
> > +     get_random_bytes(nonce, sizeof(nonce));
> > +
> > +     /*
> > +      * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
> > +      *  transaction at the MST Branch device directly connected to the
> > +      *  Source"
> > +      */
> > +     txmsg->dst = mgr->mst_primary;
> > +
> > +     len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
> > +
> > +     drm_dp_queue_down_tx(mgr, txmsg);
> > +
> > +     ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
> > +     if (ret < 0) {
> > +             goto out;
> > +     } else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
> > +             DRM_DEBUG_KMS("query encryption status nak received\n");
> > +             ret = -ENXIO;
> > +             goto out;
> > +     }
> > +
> > +     ret = 0;
> > +     memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
> > +
> > +out:
> > +     drm_dp_mst_topology_put_port(port);
> > +out_get_port:
> > +     kfree(txmsg);
> > +     return ret;
> > +}
> > +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
> > +
> >  static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
> >                                      int id,
> >                                      struct drm_dp_payload *payload)
> > diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > index bd990d178765..1d696ec001cf 100644
> > --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > @@ -5,6 +5,8 @@
> >
> >  #define PREFIX_STR "[drm_dp_mst_helper]"
> >
> > +#include <linux/random.h>
> > +
> >  #include <drm/drm_dp_mst_helper.h>
> >  #include <drm/drm_print.h>
> >
> > @@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
> >       in.u.i2c_write.bytes = data;
> >       DO_TEST();
> >
> > +     in.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > +     in.u.enc_status.stream_id = 1;
> > +     DO_TEST();
> > +     get_random_bytes(in.u.enc_status.client_id,
> > +                      sizeof(in.u.enc_status.client_id));
> > +     DO_TEST();
> > +     in.u.enc_status.stream_event = 3;
> > +     DO_TEST();
> > +     in.u.enc_status.valid_stream_event = 0;
> > +     DO_TEST();
> > +     in.u.enc_status.stream_behavior = 3;
> > +     DO_TEST();
> > +     in.u.enc_status.valid_stream_behavior = 1;
> > +     DO_TEST();
> > +
> >  #undef DO_TEST
> >       return 0;
> >  }
> > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > index e47dc22ebf50..e2d2df5e869e 100644
> > --- a/include/drm/drm_dp_helper.h
> > +++ b/include/drm/drm_dp_helper.h
> > @@ -1108,6 +1108,9 @@
> >  #define DP_POWER_DOWN_PHY            0x25
> >  #define DP_SINK_EVENT_NOTIFY         0x30
> >  #define DP_QUERY_STREAM_ENC_STATUS   0x38
> > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST   0
> > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE   1
> > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE     2
> >
> >  /* DP 1.2 MST sideband reply types */
> >  #define DP_SIDEBAND_REPLY_ACK                0x00
> > diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> > index 8b9eb4db3381..371eef8798ad 100644
> > --- a/include/drm/drm_dp_mst_helper.h
> > +++ b/include/drm/drm_dp_mst_helper.h
> > @@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
> >       u8 port_number;
> >  };
> >
> > +struct drm_dp_query_stream_enc_status_ack_reply {
> > +     /* Bit[23:16]- Stream Id */
> > +     u8 stream_id;
> > +
> > +     /* Bit[15]- Signed */
> > +     bool reply_signed;
> > +
> > +     /* Bit[10:8]- Stream Output Sink Type */
> > +     bool unauthorizable_device_present;
> > +     bool legacy_device_present;
> > +     bool query_capable_device_present;
> > +
> > +     /* Bit[12:11]- Stream Output CP Type */
> > +     bool hdcp_1x_device_present;
> > +     bool hdcp_2x_device_present;
> > +
> > +     /* Bit[4]- Stream Authentication */
> > +     bool auth_completed;
> > +
> > +     /* Bit[3]- Stream Encryption */
> > +     bool encryption_enabled;
> > +
> > +     /* Bit[2]- Stream Repeater Function Present */
> > +     bool repeater_present;
> > +
> > +     /* Bit[1:0]- Stream State */
> > +     u8 state;
> > +};
> >
> >  #define DRM_DP_MAX_SDP_STREAMS 16
> >  struct drm_dp_allocate_payload {
> > @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
> >       u8 *bytes;
> >  };
> >
> > +struct drm_dp_query_stream_enc_status {
> > +     u8 stream_id;
> > +     u8 client_id[7];        /* 56-bit nonce */
> > +     u8 stream_event;
> > +     bool valid_stream_event;
> > +     u8 stream_behavior;
> > +     u8 valid_stream_behavior;
> > +};
> > +
> >  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
> >  struct drm_dp_port_number_req {
> >       u8 port_number;
> > @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
> >
> >               struct drm_dp_remote_i2c_read i2c_read;
> >               struct drm_dp_remote_i2c_write i2c_write;
> > +
> > +             struct drm_dp_query_stream_enc_status enc_status;
> >       } u;
> >  };
> >
> > @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
> >               struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
> >               struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
> >               struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> > +
> > +             struct drm_dp_query_stream_enc_status_ack_reply enc_status;
> >       } u;
> >  };
> >
> > @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
> >                                struct drm_dp_mst_port *port);
> >  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> >                                struct drm_dp_mst_port *port, bool power_up);
> > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > +             struct drm_dp_mst_port *port,
> > +             struct drm_dp_query_stream_enc_status_ack_reply *status);
> >  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
> >
> >  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> > --
> > Sean Paul, Software Engineer, Google / Chromium OS
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
@ 2020-06-30 16:48       ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-06-30 16:48 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On Tue, Jun 30, 2020 at 10:21 AM Anshuman Gupta
<anshuman.gupta@intel.com> wrote:
>
> On 2020-06-23 at 21:29:05 +0530, Sean Paul wrote:
> Hi Sean,
> I am new to DP MST stuff, I am looking to DP MST spec DP v1.2a.
> I have looked the entire series, i will take up this opportunity to review
> the series from HDCP over DP MST POV.
> I think theoretically this series should work or Gen12 as well, as DP MST streams
> are getting encrypted by QUERY_STREAM_ENCRYPTION_STATUS reply tranaction msg
> (generating Stream State Signature L’).
> I will test this on Gen12 H/W with DP MST support and will provide my inputs.
>
> Meanwhile while going through DP MST v1.2a specs(Page 262) came to know about
> a DP irq vector LINK_SERVICE_IRQ_VECTOR_ESI0 (02005h),
> Bit 2 : STREAM_STATUS_CHANGED.
> When this bit set to ‘1’ indicates the source must re-check the Stream Status
> with the QUERY_STREAM_ENCRYPTION_STATUS message.
> Currently i feel this irq support is missing, do we require to support
> above IRQ vector for DP MST stream encryption.
>

Hi Anshuman,
Thank you for your comments.

QUERY_STREAM_ENCRYPTION_STATUS is not necessary for HDCP 1.x, I added
this as a safety check to ensure that the streams were being
encrypted. As such, the existing integrity checks in place for DP are
sufficient to satisfy spec. When HDCP 2.2 support is added for MST,
handling QSES will need to be addressed to meet spec. Note also that
we're not validating the QSES signature for the same reason.

Sean


> Thanks,
> Anshuman Gupta.
>
> > From: Sean Paul <seanpaul@chromium.org>
> >
> > Used to query whether an MST stream is encrypted or not.
> >
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> >
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6
> >
> > Changes in v4:
> > -Added to the set
> > Changes in v5:
> > -None
> > Changes in v6:
> > -Use FIELD_PREP to generate request buffer bitfields (Lyude)
> > -Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
> > Changes in v7:
> > -None
> > ---
> >  drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
> >  .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
> >  include/drm/drm_dp_helper.h                   |   3 +
> >  include/drm/drm_dp_mst_helper.h               |  44 ++++++
> >  4 files changed, 206 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> > index b2f5a84b4cfb..fc68478eaeb4 100644
> > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > @@ -20,11 +20,13 @@
> >   * OF THIS SOFTWARE.
> >   */
> >
> > +#include <linux/bitfield.h>
> >  #include <linux/delay.h>
> >  #include <linux/errno.h>
> >  #include <linux/i2c.h>
> >  #include <linux/init.h>
> >  #include <linux/kernel.h>
> > +#include <linux/random.h>
> >  #include <linux/sched.h>
> >  #include <linux/seq_file.h>
> >  #include <linux/iopoll.h>
> > @@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
> >               memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
> >               idx += req->u.i2c_write.num_bytes;
> >               break;
> > +     case DP_QUERY_STREAM_ENC_STATUS: {
> > +             const struct drm_dp_query_stream_enc_status *msg;
> > +
> > +             msg = &req->u.enc_status;
> > +             buf[idx] = msg->stream_id;
> > +             idx++;
> > +             memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
> > +             idx += sizeof(msg->client_id);
> > +             buf[idx] = 0;
> > +             buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
> > +             buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
> > +             buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
> > +             buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
> > +             idx++;
> > +             }
> > +             break;
> >       }
> >       raw->cur_len = idx;
> >  }
> > @@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
> >                               return -ENOMEM;
> >               }
> >               break;
> > +     case DP_QUERY_STREAM_ENC_STATUS:
> > +             req->u.enc_status.stream_id = buf[idx++];
> > +             for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
> > +                     req->u.enc_status.client_id[i] = buf[idx++];
> > +
> > +             req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
> > +                                                        buf[idx]);
> > +             req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
> > +                                                              buf[idx]);
> > +             req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
> > +                                                           buf[idx]);
> > +             req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
> > +                                                                 buf[idx]);
> > +             break;
> >       }
> >
> >       return 0;
> > @@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
> >                 req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
> >                 req->u.i2c_write.bytes);
> >               break;
> > +     case DP_QUERY_STREAM_ENC_STATUS:
> > +             P("stream_id=%u client_id=%*ph stream_event=%x "
> > +               "valid_event=%d stream_behavior=%x valid_behavior=%d",
> > +               req->u.enc_status.stream_id,
> > +               (int)ARRAY_SIZE(req->u.enc_status.client_id),
> > +               req->u.enc_status.client_id, req->u.enc_status.stream_event,
> > +               req->u.enc_status.valid_stream_event,
> > +               req->u.enc_status.stream_behavior,
> > +               req->u.enc_status.valid_stream_behavior);
> > +             break;
> >       default:
> >               P("???\n");
> >               break;
> > @@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
> >       return true;
> >  }
> >
> > +static bool
> > +drm_dp_sideband_parse_query_stream_enc_status(
> > +                             struct drm_dp_sideband_msg_rx *raw,
> > +                             struct drm_dp_sideband_msg_reply_body *repmsg)
> > +{
> > +     struct drm_dp_query_stream_enc_status_ack_reply *reply;
> > +
> > +     reply = &repmsg->u.enc_status;
> > +
> > +     reply->stream_id = raw->msg[3];
> > +
> > +     reply->reply_signed = raw->msg[2] & BIT(0);
> > +
> > +     reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> > +     reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
> > +
> > +     reply->query_capable_device_present = raw->msg[2] & BIT(5);
> > +     reply->legacy_device_present = raw->msg[2] & BIT(6);
> > +     reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> > +
> > +     reply->auth_completed = !!(raw->msg[1] & BIT(3));
> > +     reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> > +     reply->repeater_present = !!(raw->msg[1] & BIT(5));
> > +     reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> > +
> > +     return true;
> > +}
> > +
> >  static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> >                                       struct drm_dp_sideband_msg_reply_body *msg)
> >  {
> > @@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> >               return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
> >       case DP_CLEAR_PAYLOAD_ID_TABLE:
> >               return true; /* since there's nothing to parse */
> > +     case DP_QUERY_STREAM_ENC_STATUS:
> > +             return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
> >       default:
> >               DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
> >                         drm_dp_mst_req_type_str(msg->req_type));
> > @@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
> >       msg->path_msg = true;
> >  }
> >
> > +static int
> > +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
> > +                           u8 *q_id)
> > +{
> > +     struct drm_dp_sideband_msg_req_body req;
> > +
> > +     req.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > +     req.u.enc_status.stream_id = stream_id;
> > +     memcpy(req.u.enc_status.client_id, q_id,
> > +            sizeof(req.u.enc_status.client_id));
> > +     req.u.enc_status.stream_event = 0;
> > +     req.u.enc_status.valid_stream_event = false;
> > +     req.u.enc_status.stream_behavior = 0;
> > +     req.u.enc_status.valid_stream_behavior = false;
> > +
> > +     drm_dp_encode_sideband_req(&req, msg);
> > +     return 0;
> > +}
> > +
> >  static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
> >                                       struct drm_dp_vcpi *vcpi)
> >  {
> > @@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> >  }
> >  EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
> >
> > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > +             struct drm_dp_mst_port *port,
> > +             struct drm_dp_query_stream_enc_status_ack_reply *status)
> > +{
> > +     struct drm_dp_sideband_msg_tx *txmsg;
> > +     u8 nonce[7];
> > +     int len, ret;
> > +
> > +     txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> > +     if (!txmsg)
> > +             return -ENOMEM;
> > +
> > +     port = drm_dp_mst_topology_get_port_validated(mgr, port);
> > +     if (!port) {
> > +             ret = -EINVAL;
> > +             goto out_get_port;
> > +     }
> > +
> > +     get_random_bytes(nonce, sizeof(nonce));
> > +
> > +     /*
> > +      * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
> > +      *  transaction at the MST Branch device directly connected to the
> > +      *  Source"
> > +      */
> > +     txmsg->dst = mgr->mst_primary;
> > +
> > +     len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
> > +
> > +     drm_dp_queue_down_tx(mgr, txmsg);
> > +
> > +     ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
> > +     if (ret < 0) {
> > +             goto out;
> > +     } else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
> > +             DRM_DEBUG_KMS("query encryption status nak received\n");
> > +             ret = -ENXIO;
> > +             goto out;
> > +     }
> > +
> > +     ret = 0;
> > +     memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
> > +
> > +out:
> > +     drm_dp_mst_topology_put_port(port);
> > +out_get_port:
> > +     kfree(txmsg);
> > +     return ret;
> > +}
> > +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
> > +
> >  static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
> >                                      int id,
> >                                      struct drm_dp_payload *payload)
> > diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > index bd990d178765..1d696ec001cf 100644
> > --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > @@ -5,6 +5,8 @@
> >
> >  #define PREFIX_STR "[drm_dp_mst_helper]"
> >
> > +#include <linux/random.h>
> > +
> >  #include <drm/drm_dp_mst_helper.h>
> >  #include <drm/drm_print.h>
> >
> > @@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
> >       in.u.i2c_write.bytes = data;
> >       DO_TEST();
> >
> > +     in.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > +     in.u.enc_status.stream_id = 1;
> > +     DO_TEST();
> > +     get_random_bytes(in.u.enc_status.client_id,
> > +                      sizeof(in.u.enc_status.client_id));
> > +     DO_TEST();
> > +     in.u.enc_status.stream_event = 3;
> > +     DO_TEST();
> > +     in.u.enc_status.valid_stream_event = 0;
> > +     DO_TEST();
> > +     in.u.enc_status.stream_behavior = 3;
> > +     DO_TEST();
> > +     in.u.enc_status.valid_stream_behavior = 1;
> > +     DO_TEST();
> > +
> >  #undef DO_TEST
> >       return 0;
> >  }
> > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > index e47dc22ebf50..e2d2df5e869e 100644
> > --- a/include/drm/drm_dp_helper.h
> > +++ b/include/drm/drm_dp_helper.h
> > @@ -1108,6 +1108,9 @@
> >  #define DP_POWER_DOWN_PHY            0x25
> >  #define DP_SINK_EVENT_NOTIFY         0x30
> >  #define DP_QUERY_STREAM_ENC_STATUS   0x38
> > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST   0
> > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE   1
> > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE     2
> >
> >  /* DP 1.2 MST sideband reply types */
> >  #define DP_SIDEBAND_REPLY_ACK                0x00
> > diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> > index 8b9eb4db3381..371eef8798ad 100644
> > --- a/include/drm/drm_dp_mst_helper.h
> > +++ b/include/drm/drm_dp_mst_helper.h
> > @@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
> >       u8 port_number;
> >  };
> >
> > +struct drm_dp_query_stream_enc_status_ack_reply {
> > +     /* Bit[23:16]- Stream Id */
> > +     u8 stream_id;
> > +
> > +     /* Bit[15]- Signed */
> > +     bool reply_signed;
> > +
> > +     /* Bit[10:8]- Stream Output Sink Type */
> > +     bool unauthorizable_device_present;
> > +     bool legacy_device_present;
> > +     bool query_capable_device_present;
> > +
> > +     /* Bit[12:11]- Stream Output CP Type */
> > +     bool hdcp_1x_device_present;
> > +     bool hdcp_2x_device_present;
> > +
> > +     /* Bit[4]- Stream Authentication */
> > +     bool auth_completed;
> > +
> > +     /* Bit[3]- Stream Encryption */
> > +     bool encryption_enabled;
> > +
> > +     /* Bit[2]- Stream Repeater Function Present */
> > +     bool repeater_present;
> > +
> > +     /* Bit[1:0]- Stream State */
> > +     u8 state;
> > +};
> >
> >  #define DRM_DP_MAX_SDP_STREAMS 16
> >  struct drm_dp_allocate_payload {
> > @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
> >       u8 *bytes;
> >  };
> >
> > +struct drm_dp_query_stream_enc_status {
> > +     u8 stream_id;
> > +     u8 client_id[7];        /* 56-bit nonce */
> > +     u8 stream_event;
> > +     bool valid_stream_event;
> > +     u8 stream_behavior;
> > +     u8 valid_stream_behavior;
> > +};
> > +
> >  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
> >  struct drm_dp_port_number_req {
> >       u8 port_number;
> > @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
> >
> >               struct drm_dp_remote_i2c_read i2c_read;
> >               struct drm_dp_remote_i2c_write i2c_write;
> > +
> > +             struct drm_dp_query_stream_enc_status enc_status;
> >       } u;
> >  };
> >
> > @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
> >               struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
> >               struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
> >               struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> > +
> > +             struct drm_dp_query_stream_enc_status_ack_reply enc_status;
> >       } u;
> >  };
> >
> > @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
> >                                struct drm_dp_mst_port *port);
> >  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> >                                struct drm_dp_mst_port *port, bool power_up);
> > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > +             struct drm_dp_mst_port *port,
> > +             struct drm_dp_query_stream_enc_status_ack_reply *status);
> >  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
> >
> >  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> > --
> > Sean Paul, Software Engineer, Google / Chromium OS
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
  2020-06-30 16:48       ` Sean Paul
@ 2020-07-02 14:37         ` Anshuman Gupta
  -1 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-02 14:37 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-06-30 at 12:48:34 -0400, Sean Paul wrote:
> On Tue, Jun 30, 2020 at 10:21 AM Anshuman Gupta
> <anshuman.gupta@intel.com> wrote:
> >
> > On 2020-06-23 at 21:29:05 +0530, Sean Paul wrote:
> > Hi Sean,
> > I am new to DP MST stuff, I am looking to DP MST spec DP v1.2a.
> > I have looked the entire series, i will take up this opportunity to review
> > the series from HDCP over DP MST POV.
> > I think theoretically this series should work or Gen12 as well, as DP MST streams
> > are getting encrypted by QUERY_STREAM_ENCRYPTION_STATUS reply tranaction msg
> > (generating Stream State Signature L’).
> > I will test this on Gen12 H/W with DP MST support and will provide my inputs.
> >
> > Meanwhile while going through DP MST v1.2a specs(Page 262) came to know about
> > a DP irq vector LINK_SERVICE_IRQ_VECTOR_ESI0 (02005h),
> > Bit 2 : STREAM_STATUS_CHANGED.
> > When this bit set to ‘1’ indicates the source must re-check the Stream Status
> > with the QUERY_STREAM_ENCRYPTION_STATUS message.
> > Currently i feel this irq support is missing, do we require to support
> > above IRQ vector for DP MST stream encryption.
> >
> 
> Hi Anshuman,
> Thank you for your comments.
> 
> QUERY_STREAM_ENCRYPTION_STATUS is not necessary for HDCP 1.x, I added
> this as a safety check to ensure that the streams were being
> encrypted. As such, the existing integrity checks in place for DP are
> sufficient to satisfy spec. When HDCP 2.2 support is added for MST,
> handling QSES will need to be addressed to meet spec. Note also that
> we're not validating the QSES signature for the same reason.
Thanks sean for the explanation,
overall patch looks good to me but i have couple of doubt see below.
> 
> Sean
> 
> 
> > Thanks,
> > Anshuman Gupta.
> >
> > > From: Sean Paul <seanpaul@chromium.org>
> > >
> > > Used to query whether an MST stream is encrypted or not.
> > >
> > > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > >
> > > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
> > > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
> > > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6
> > >
> > > Changes in v4:
> > > -Added to the set
> > > Changes in v5:
> > > -None
> > > Changes in v6:
> > > -Use FIELD_PREP to generate request buffer bitfields (Lyude)
> > > -Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
> > > Changes in v7:
> > > -None
> > > ---
> > >  drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
> > >  .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
> > >  include/drm/drm_dp_helper.h                   |   3 +
> > >  include/drm/drm_dp_mst_helper.h               |  44 ++++++
> > >  4 files changed, 206 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > index b2f5a84b4cfb..fc68478eaeb4 100644
> > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > @@ -20,11 +20,13 @@
> > >   * OF THIS SOFTWARE.
> > >   */
> > >
> > > +#include <linux/bitfield.h>
> > >  #include <linux/delay.h>
> > >  #include <linux/errno.h>
> > >  #include <linux/i2c.h>
> > >  #include <linux/init.h>
> > >  #include <linux/kernel.h>
> > > +#include <linux/random.h>
> > >  #include <linux/sched.h>
> > >  #include <linux/seq_file.h>
> > >  #include <linux/iopoll.h>
> > > @@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
> > >               memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
> > >               idx += req->u.i2c_write.num_bytes;
> > >               break;
> > > +     case DP_QUERY_STREAM_ENC_STATUS: {
> > > +             const struct drm_dp_query_stream_enc_status *msg;
> > > +
> > > +             msg = &req->u.enc_status;
> > > +             buf[idx] = msg->stream_id;
> > > +             idx++;
> > > +             memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
> > > +             idx += sizeof(msg->client_id);
> > > +             buf[idx] = 0;
> > > +             buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
> > > +             buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
> > > +             buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
> > > +             buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
> > > +             idx++;
> > > +             }
> > > +             break;
> > >       }
> > >       raw->cur_len = idx;
> > >  }
> > > @@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
> > >                               return -ENOMEM;
> > >               }
> > >               break;
> > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > +             req->u.enc_status.stream_id = buf[idx++];
> > > +             for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
> > > +                     req->u.enc_status.client_id[i] = buf[idx++];
> > > +
> > > +             req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
> > > +                                                        buf[idx]);
> > > +             req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
> > > +                                                              buf[idx]);
> > > +             req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
> > > +                                                           buf[idx]);
> > > +             req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
> > > +                                                                 buf[idx]);
> > > +             break;
> > >       }
> > >
> > >       return 0;
> > > @@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
> > >                 req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
> > >                 req->u.i2c_write.bytes);
> > >               break;
> > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > +             P("stream_id=%u client_id=%*ph stream_event=%x "
> > > +               "valid_event=%d stream_behavior=%x valid_behavior=%d",
> > > +               req->u.enc_status.stream_id,
> > > +               (int)ARRAY_SIZE(req->u.enc_status.client_id),
> > > +               req->u.enc_status.client_id, req->u.enc_status.stream_event,
> > > +               req->u.enc_status.valid_stream_event,
> > > +               req->u.enc_status.stream_behavior,
> > > +               req->u.enc_status.valid_stream_behavior);
> > > +             break;
> > >       default:
> > >               P("???\n");
> > >               break;
> > > @@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
> > >       return true;
> > >  }
> > >
> > > +static bool
> > > +drm_dp_sideband_parse_query_stream_enc_status(
> > > +                             struct drm_dp_sideband_msg_rx *raw,
> > > +                             struct drm_dp_sideband_msg_reply_body *repmsg)
> > > +{
> > > +     struct drm_dp_query_stream_enc_status_ack_reply *reply;
> > > +
> > > +     reply = &repmsg->u.enc_status;
> > > +
> > > +     reply->stream_id = raw->msg[3];
It seems msg[0] is not part of reply data,
could you help me with pointers, where msg is formatted.
> > > +
> > > +     reply->reply_signed = raw->msg[2] & BIT(0);
> > > +
> > > +     reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> > > +     reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
> > > +
> > > +     reply->query_capable_device_present = raw->msg[2] & BIT(5);
> > > +     reply->legacy_device_present = raw->msg[2] & BIT(6);
> > > +     reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> > > +
> > > +     reply->auth_completed = !!(raw->msg[1] & BIT(3));
> > > +     reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> > > +     reply->repeater_present = !!(raw->msg[1] & BIT(5));
> > > +     reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> > > +
> > > +     return true;
> > > +}
> > > +
> > >  static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > >                                       struct drm_dp_sideband_msg_reply_body *msg)
> > >  {
> > > @@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > >               return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
> > >       case DP_CLEAR_PAYLOAD_ID_TABLE:
> > >               return true; /* since there's nothing to parse */
> > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > +             return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
> > >       default:
> > >               DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
> > >                         drm_dp_mst_req_type_str(msg->req_type));
> > > @@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
> > >       msg->path_msg = true;
> > >  }
> > >
> > > +static int
> > > +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
> > > +                           u8 *q_id)
> > > +{
> > > +     struct drm_dp_sideband_msg_req_body req;
> > > +
> > > +     req.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > +     req.u.enc_status.stream_id = stream_id;
> > > +     memcpy(req.u.enc_status.client_id, q_id,
> > > +            sizeof(req.u.enc_status.client_id));
> > > +     req.u.enc_status.stream_event = 0;
> > > +     req.u.enc_status.valid_stream_event = false;
> > > +     req.u.enc_status.stream_behavior = 0;
> > > +     req.u.enc_status.valid_stream_behavior = false;
> > > +
> > > +     drm_dp_encode_sideband_req(&req, msg);
> > > +     return 0;
> > > +}
> > > +
> > >  static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
> > >                                       struct drm_dp_vcpi *vcpi)
> > >  {
> > > @@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > >  }
> > >  EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
> > >
> > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > +             struct drm_dp_mst_port *port,
> > > +             struct drm_dp_query_stream_enc_status_ack_reply *status)
> > > +{
> > > +     struct drm_dp_sideband_msg_tx *txmsg;
> > > +     u8 nonce[7];
> > > +     int len, ret;
> > > +
> > > +     txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> > > +     if (!txmsg)
> > > +             return -ENOMEM;
> > > +
> > > +     port = drm_dp_mst_topology_get_port_validated(mgr, port);
> > > +     if (!port) {
> > > +             ret = -EINVAL;
> > > +             goto out_get_port;
> > > +     }
> > > +
> > > +     get_random_bytes(nonce, sizeof(nonce));
> > > +
> > > +     /*
> > > +      * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
> > > +      *  transaction at the MST Branch device directly connected to the
> > > +      *  Source"
> > > +      */
> > > +     txmsg->dst = mgr->mst_primary;
> > > +
> > > +     len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
> > > +
> > > +     drm_dp_queue_down_tx(mgr, txmsg);
> > > +
> > > +     ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
> > > +     if (ret < 0) {
> > > +             goto out;
> > > +     } else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
> > > +             DRM_DEBUG_KMS("query encryption status nak received\n");
> > > +             ret = -ENXIO;
> > > +             goto out;
> > > +     }
> > > +
> > > +     ret = 0;
> > > +     memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
> > > +
> > > +out:
> > > +     drm_dp_mst_topology_put_port(port);
> > > +out_get_port:
> > > +     kfree(txmsg);
> > > +     return ret;
> > > +}
> > > +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
> > > +
> > >  static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
> > >                                      int id,
> > >                                      struct drm_dp_payload *payload)
> > > diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > index bd990d178765..1d696ec001cf 100644
> > > --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > @@ -5,6 +5,8 @@
> > >
> > >  #define PREFIX_STR "[drm_dp_mst_helper]"
> > >
> > > +#include <linux/random.h>
> > > +
> > >  #include <drm/drm_dp_mst_helper.h>
> > >  #include <drm/drm_print.h>
> > >
> > > @@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
> > >       in.u.i2c_write.bytes = data;
> > >       DO_TEST();
> > >
> > > +     in.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > +     in.u.enc_status.stream_id = 1;
> > > +     DO_TEST();
> > > +     get_random_bytes(in.u.enc_status.client_id,
> > > +                      sizeof(in.u.enc_status.client_id));
> > > +     DO_TEST();
> > > +     in.u.enc_status.stream_event = 3;
> > > +     DO_TEST();
> > > +     in.u.enc_status.valid_stream_event = 0;
> > > +     DO_TEST();
> > > +     in.u.enc_status.stream_behavior = 3;
> > > +     DO_TEST();
> > > +     in.u.enc_status.valid_stream_behavior = 1;
> > > +     DO_TEST();
> > > +
> > >  #undef DO_TEST
> > >       return 0;
> > >  }
> > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > > index e47dc22ebf50..e2d2df5e869e 100644
> > > --- a/include/drm/drm_dp_helper.h
> > > +++ b/include/drm/drm_dp_helper.h
> > > @@ -1108,6 +1108,9 @@
> > >  #define DP_POWER_DOWN_PHY            0x25
> > >  #define DP_SINK_EVENT_NOTIFY         0x30
> > >  #define DP_QUERY_STREAM_ENC_STATUS   0x38
> > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST   0
> > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE   1
> > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE     2
> > >
> > >  /* DP 1.2 MST sideband reply types */
> > >  #define DP_SIDEBAND_REPLY_ACK                0x00
> > > diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> > > index 8b9eb4db3381..371eef8798ad 100644
> > > --- a/include/drm/drm_dp_mst_helper.h
> > > +++ b/include/drm/drm_dp_mst_helper.h
> > > @@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
> > >       u8 port_number;
> > >  };
> > >
> > > +struct drm_dp_query_stream_enc_status_ack_reply {
> > > +     /* Bit[23:16]- Stream Id */
> > > +     u8 stream_id;
> > > +
> > > +     /* Bit[15]- Signed */
> > > +     bool reply_signed;
> > > +
> > > +     /* Bit[10:8]- Stream Output Sink Type */
> > > +     bool unauthorizable_device_present;
> > > +     bool legacy_device_present;
> > > +     bool query_capable_device_present;
> > > +
> > > +     /* Bit[12:11]- Stream Output CP Type */
> > > +     bool hdcp_1x_device_present;
> > > +     bool hdcp_2x_device_present;
> > > +
> > > +     /* Bit[4]- Stream Authentication */
> > > +     bool auth_completed;
> > > +
> > > +     /* Bit[3]- Stream Encryption */
> > > +     bool encryption_enabled;
> > > +
> > > +     /* Bit[2]- Stream Repeater Function Present */
> > > +     bool repeater_present;
> > > +
> > > +     /* Bit[1:0]- Stream State */
> > > +     u8 state;
reply msg also has 20 byte of signature L' (HDCP 1.4),
AFAIU it has lefted out for HDCP 2.2 implementation, which is of 32 bytes for HDCP 2.2.
Please correct me if i am wrong here.
Thanks,
Anshuman Gupta.
> > > +};
> > >
> > >  #define DRM_DP_MAX_SDP_STREAMS 16
> > >  struct drm_dp_allocate_payload {
> > > @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
> > >       u8 *bytes;
> > >  };
> > >
> > > +struct drm_dp_query_stream_enc_status {
> > > +     u8 stream_id;
> > > +     u8 client_id[7];        /* 56-bit nonce */
> > > +     u8 stream_event;
> > > +     bool valid_stream_event;
> > > +     u8 stream_behavior;
> > > +     u8 valid_stream_behavior;
> > > +};
> > > +
> > >  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
> > >  struct drm_dp_port_number_req {
> > >       u8 port_number;
> > > @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
> > >
> > >               struct drm_dp_remote_i2c_read i2c_read;
> > >               struct drm_dp_remote_i2c_write i2c_write;
> > > +
> > > +             struct drm_dp_query_stream_enc_status enc_status;
> > >       } u;
> > >  };
> > >
> > > @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
> > >               struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
> > >               struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
> > >               struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> > > +
> > > +             struct drm_dp_query_stream_enc_status_ack_reply enc_status;
> > >       } u;
> > >  };
> > >
> > > @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
> > >                                struct drm_dp_mst_port *port);
> > >  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > >                                struct drm_dp_mst_port *port, bool power_up);
> > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > +             struct drm_dp_mst_port *port,
> > > +             struct drm_dp_query_stream_enc_status_ack_reply *status);
> > >  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
> > >
> > >  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> > > --
> > > Sean Paul, Software Engineer, Google / Chromium OS
> > >
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
@ 2020-07-02 14:37         ` Anshuman Gupta
  0 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-02 14:37 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-06-30 at 12:48:34 -0400, Sean Paul wrote:
> On Tue, Jun 30, 2020 at 10:21 AM Anshuman Gupta
> <anshuman.gupta@intel.com> wrote:
> >
> > On 2020-06-23 at 21:29:05 +0530, Sean Paul wrote:
> > Hi Sean,
> > I am new to DP MST stuff, I am looking to DP MST spec DP v1.2a.
> > I have looked the entire series, i will take up this opportunity to review
> > the series from HDCP over DP MST POV.
> > I think theoretically this series should work or Gen12 as well, as DP MST streams
> > are getting encrypted by QUERY_STREAM_ENCRYPTION_STATUS reply tranaction msg
> > (generating Stream State Signature L’).
> > I will test this on Gen12 H/W with DP MST support and will provide my inputs.
> >
> > Meanwhile while going through DP MST v1.2a specs(Page 262) came to know about
> > a DP irq vector LINK_SERVICE_IRQ_VECTOR_ESI0 (02005h),
> > Bit 2 : STREAM_STATUS_CHANGED.
> > When this bit set to ‘1’ indicates the source must re-check the Stream Status
> > with the QUERY_STREAM_ENCRYPTION_STATUS message.
> > Currently i feel this irq support is missing, do we require to support
> > above IRQ vector for DP MST stream encryption.
> >
> 
> Hi Anshuman,
> Thank you for your comments.
> 
> QUERY_STREAM_ENCRYPTION_STATUS is not necessary for HDCP 1.x, I added
> this as a safety check to ensure that the streams were being
> encrypted. As such, the existing integrity checks in place for DP are
> sufficient to satisfy spec. When HDCP 2.2 support is added for MST,
> handling QSES will need to be addressed to meet spec. Note also that
> we're not validating the QSES signature for the same reason.
Thanks sean for the explanation,
overall patch looks good to me but i have couple of doubt see below.
> 
> Sean
> 
> 
> > Thanks,
> > Anshuman Gupta.
> >
> > > From: Sean Paul <seanpaul@chromium.org>
> > >
> > > Used to query whether an MST stream is encrypted or not.
> > >
> > > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > >
> > > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
> > > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
> > > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6
> > >
> > > Changes in v4:
> > > -Added to the set
> > > Changes in v5:
> > > -None
> > > Changes in v6:
> > > -Use FIELD_PREP to generate request buffer bitfields (Lyude)
> > > -Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
> > > Changes in v7:
> > > -None
> > > ---
> > >  drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
> > >  .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
> > >  include/drm/drm_dp_helper.h                   |   3 +
> > >  include/drm/drm_dp_mst_helper.h               |  44 ++++++
> > >  4 files changed, 206 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > index b2f5a84b4cfb..fc68478eaeb4 100644
> > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > @@ -20,11 +20,13 @@
> > >   * OF THIS SOFTWARE.
> > >   */
> > >
> > > +#include <linux/bitfield.h>
> > >  #include <linux/delay.h>
> > >  #include <linux/errno.h>
> > >  #include <linux/i2c.h>
> > >  #include <linux/init.h>
> > >  #include <linux/kernel.h>
> > > +#include <linux/random.h>
> > >  #include <linux/sched.h>
> > >  #include <linux/seq_file.h>
> > >  #include <linux/iopoll.h>
> > > @@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
> > >               memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
> > >               idx += req->u.i2c_write.num_bytes;
> > >               break;
> > > +     case DP_QUERY_STREAM_ENC_STATUS: {
> > > +             const struct drm_dp_query_stream_enc_status *msg;
> > > +
> > > +             msg = &req->u.enc_status;
> > > +             buf[idx] = msg->stream_id;
> > > +             idx++;
> > > +             memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
> > > +             idx += sizeof(msg->client_id);
> > > +             buf[idx] = 0;
> > > +             buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
> > > +             buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
> > > +             buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
> > > +             buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
> > > +             idx++;
> > > +             }
> > > +             break;
> > >       }
> > >       raw->cur_len = idx;
> > >  }
> > > @@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
> > >                               return -ENOMEM;
> > >               }
> > >               break;
> > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > +             req->u.enc_status.stream_id = buf[idx++];
> > > +             for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
> > > +                     req->u.enc_status.client_id[i] = buf[idx++];
> > > +
> > > +             req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
> > > +                                                        buf[idx]);
> > > +             req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
> > > +                                                              buf[idx]);
> > > +             req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
> > > +                                                           buf[idx]);
> > > +             req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
> > > +                                                                 buf[idx]);
> > > +             break;
> > >       }
> > >
> > >       return 0;
> > > @@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
> > >                 req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
> > >                 req->u.i2c_write.bytes);
> > >               break;
> > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > +             P("stream_id=%u client_id=%*ph stream_event=%x "
> > > +               "valid_event=%d stream_behavior=%x valid_behavior=%d",
> > > +               req->u.enc_status.stream_id,
> > > +               (int)ARRAY_SIZE(req->u.enc_status.client_id),
> > > +               req->u.enc_status.client_id, req->u.enc_status.stream_event,
> > > +               req->u.enc_status.valid_stream_event,
> > > +               req->u.enc_status.stream_behavior,
> > > +               req->u.enc_status.valid_stream_behavior);
> > > +             break;
> > >       default:
> > >               P("???\n");
> > >               break;
> > > @@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
> > >       return true;
> > >  }
> > >
> > > +static bool
> > > +drm_dp_sideband_parse_query_stream_enc_status(
> > > +                             struct drm_dp_sideband_msg_rx *raw,
> > > +                             struct drm_dp_sideband_msg_reply_body *repmsg)
> > > +{
> > > +     struct drm_dp_query_stream_enc_status_ack_reply *reply;
> > > +
> > > +     reply = &repmsg->u.enc_status;
> > > +
> > > +     reply->stream_id = raw->msg[3];
It seems msg[0] is not part of reply data,
could you help me with pointers, where msg is formatted.
> > > +
> > > +     reply->reply_signed = raw->msg[2] & BIT(0);
> > > +
> > > +     reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> > > +     reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
> > > +
> > > +     reply->query_capable_device_present = raw->msg[2] & BIT(5);
> > > +     reply->legacy_device_present = raw->msg[2] & BIT(6);
> > > +     reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> > > +
> > > +     reply->auth_completed = !!(raw->msg[1] & BIT(3));
> > > +     reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> > > +     reply->repeater_present = !!(raw->msg[1] & BIT(5));
> > > +     reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> > > +
> > > +     return true;
> > > +}
> > > +
> > >  static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > >                                       struct drm_dp_sideband_msg_reply_body *msg)
> > >  {
> > > @@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > >               return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
> > >       case DP_CLEAR_PAYLOAD_ID_TABLE:
> > >               return true; /* since there's nothing to parse */
> > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > +             return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
> > >       default:
> > >               DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
> > >                         drm_dp_mst_req_type_str(msg->req_type));
> > > @@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
> > >       msg->path_msg = true;
> > >  }
> > >
> > > +static int
> > > +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
> > > +                           u8 *q_id)
> > > +{
> > > +     struct drm_dp_sideband_msg_req_body req;
> > > +
> > > +     req.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > +     req.u.enc_status.stream_id = stream_id;
> > > +     memcpy(req.u.enc_status.client_id, q_id,
> > > +            sizeof(req.u.enc_status.client_id));
> > > +     req.u.enc_status.stream_event = 0;
> > > +     req.u.enc_status.valid_stream_event = false;
> > > +     req.u.enc_status.stream_behavior = 0;
> > > +     req.u.enc_status.valid_stream_behavior = false;
> > > +
> > > +     drm_dp_encode_sideband_req(&req, msg);
> > > +     return 0;
> > > +}
> > > +
> > >  static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
> > >                                       struct drm_dp_vcpi *vcpi)
> > >  {
> > > @@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > >  }
> > >  EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
> > >
> > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > +             struct drm_dp_mst_port *port,
> > > +             struct drm_dp_query_stream_enc_status_ack_reply *status)
> > > +{
> > > +     struct drm_dp_sideband_msg_tx *txmsg;
> > > +     u8 nonce[7];
> > > +     int len, ret;
> > > +
> > > +     txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> > > +     if (!txmsg)
> > > +             return -ENOMEM;
> > > +
> > > +     port = drm_dp_mst_topology_get_port_validated(mgr, port);
> > > +     if (!port) {
> > > +             ret = -EINVAL;
> > > +             goto out_get_port;
> > > +     }
> > > +
> > > +     get_random_bytes(nonce, sizeof(nonce));
> > > +
> > > +     /*
> > > +      * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
> > > +      *  transaction at the MST Branch device directly connected to the
> > > +      *  Source"
> > > +      */
> > > +     txmsg->dst = mgr->mst_primary;
> > > +
> > > +     len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
> > > +
> > > +     drm_dp_queue_down_tx(mgr, txmsg);
> > > +
> > > +     ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
> > > +     if (ret < 0) {
> > > +             goto out;
> > > +     } else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
> > > +             DRM_DEBUG_KMS("query encryption status nak received\n");
> > > +             ret = -ENXIO;
> > > +             goto out;
> > > +     }
> > > +
> > > +     ret = 0;
> > > +     memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
> > > +
> > > +out:
> > > +     drm_dp_mst_topology_put_port(port);
> > > +out_get_port:
> > > +     kfree(txmsg);
> > > +     return ret;
> > > +}
> > > +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
> > > +
> > >  static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
> > >                                      int id,
> > >                                      struct drm_dp_payload *payload)
> > > diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > index bd990d178765..1d696ec001cf 100644
> > > --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > @@ -5,6 +5,8 @@
> > >
> > >  #define PREFIX_STR "[drm_dp_mst_helper]"
> > >
> > > +#include <linux/random.h>
> > > +
> > >  #include <drm/drm_dp_mst_helper.h>
> > >  #include <drm/drm_print.h>
> > >
> > > @@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
> > >       in.u.i2c_write.bytes = data;
> > >       DO_TEST();
> > >
> > > +     in.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > +     in.u.enc_status.stream_id = 1;
> > > +     DO_TEST();
> > > +     get_random_bytes(in.u.enc_status.client_id,
> > > +                      sizeof(in.u.enc_status.client_id));
> > > +     DO_TEST();
> > > +     in.u.enc_status.stream_event = 3;
> > > +     DO_TEST();
> > > +     in.u.enc_status.valid_stream_event = 0;
> > > +     DO_TEST();
> > > +     in.u.enc_status.stream_behavior = 3;
> > > +     DO_TEST();
> > > +     in.u.enc_status.valid_stream_behavior = 1;
> > > +     DO_TEST();
> > > +
> > >  #undef DO_TEST
> > >       return 0;
> > >  }
> > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > > index e47dc22ebf50..e2d2df5e869e 100644
> > > --- a/include/drm/drm_dp_helper.h
> > > +++ b/include/drm/drm_dp_helper.h
> > > @@ -1108,6 +1108,9 @@
> > >  #define DP_POWER_DOWN_PHY            0x25
> > >  #define DP_SINK_EVENT_NOTIFY         0x30
> > >  #define DP_QUERY_STREAM_ENC_STATUS   0x38
> > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST   0
> > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE   1
> > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE     2
> > >
> > >  /* DP 1.2 MST sideband reply types */
> > >  #define DP_SIDEBAND_REPLY_ACK                0x00
> > > diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> > > index 8b9eb4db3381..371eef8798ad 100644
> > > --- a/include/drm/drm_dp_mst_helper.h
> > > +++ b/include/drm/drm_dp_mst_helper.h
> > > @@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
> > >       u8 port_number;
> > >  };
> > >
> > > +struct drm_dp_query_stream_enc_status_ack_reply {
> > > +     /* Bit[23:16]- Stream Id */
> > > +     u8 stream_id;
> > > +
> > > +     /* Bit[15]- Signed */
> > > +     bool reply_signed;
> > > +
> > > +     /* Bit[10:8]- Stream Output Sink Type */
> > > +     bool unauthorizable_device_present;
> > > +     bool legacy_device_present;
> > > +     bool query_capable_device_present;
> > > +
> > > +     /* Bit[12:11]- Stream Output CP Type */
> > > +     bool hdcp_1x_device_present;
> > > +     bool hdcp_2x_device_present;
> > > +
> > > +     /* Bit[4]- Stream Authentication */
> > > +     bool auth_completed;
> > > +
> > > +     /* Bit[3]- Stream Encryption */
> > > +     bool encryption_enabled;
> > > +
> > > +     /* Bit[2]- Stream Repeater Function Present */
> > > +     bool repeater_present;
> > > +
> > > +     /* Bit[1:0]- Stream State */
> > > +     u8 state;
reply msg also has 20 byte of signature L' (HDCP 1.4),
AFAIU it has lefted out for HDCP 2.2 implementation, which is of 32 bytes for HDCP 2.2.
Please correct me if i am wrong here.
Thanks,
Anshuman Gupta.
> > > +};
> > >
> > >  #define DRM_DP_MAX_SDP_STREAMS 16
> > >  struct drm_dp_allocate_payload {
> > > @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
> > >       u8 *bytes;
> > >  };
> > >
> > > +struct drm_dp_query_stream_enc_status {
> > > +     u8 stream_id;
> > > +     u8 client_id[7];        /* 56-bit nonce */
> > > +     u8 stream_event;
> > > +     bool valid_stream_event;
> > > +     u8 stream_behavior;
> > > +     u8 valid_stream_behavior;
> > > +};
> > > +
> > >  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
> > >  struct drm_dp_port_number_req {
> > >       u8 port_number;
> > > @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
> > >
> > >               struct drm_dp_remote_i2c_read i2c_read;
> > >               struct drm_dp_remote_i2c_write i2c_write;
> > > +
> > > +             struct drm_dp_query_stream_enc_status enc_status;
> > >       } u;
> > >  };
> > >
> > > @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
> > >               struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
> > >               struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
> > >               struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> > > +
> > > +             struct drm_dp_query_stream_enc_status_ack_reply enc_status;
> > >       } u;
> > >  };
> > >
> > > @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
> > >                                struct drm_dp_mst_port *port);
> > >  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > >                                struct drm_dp_mst_port *port, bool power_up);
> > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > +             struct drm_dp_mst_port *port,
> > > +             struct drm_dp_query_stream_enc_status_ack_reply *status);
> > >  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
> > >
> > >  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> > > --
> > > Sean Paul, Software Engineer, Google / Chromium OS
> > >
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 14/17] drm/i915: Add connector to hdcp_shim->check_link()
  2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
@ 2020-07-03 10:13     ` Anshuman Gupta
  -1 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-03 10:13 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-06-23 at 21:29:04 +0530, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> Currently we derive the connector from digital port in check_link(). For
> MST, this isn't sufficient since the digital port passed into the
> function can have multiple connectors downstream. This patch adds
> connector to the check_link() arguments so we have it when we need it.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Looks good to me, this require a rebase on latest drm-tip
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
> Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-13-sean@poorly.run #v4
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-14-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-14-sean@poorly.run #v6
> 
> Changes in v4:
> -Added to the set
> Changes in v5:
> -None
> Changes in v6:
> -None
> Changes in v7:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_display_types.h | 3 ++-
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c       | 3 ++-
>  drivers/gpu/drm/i915/display/intel_hdcp.c          | 2 +-
>  drivers/gpu/drm/i915/display/intel_hdmi.c          | 5 ++---
>  4 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 811085ef3fba..94211b8fc159 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -318,7 +318,8 @@ struct intel_hdcp_shim {
>  				 bool enable);
>  
>  	/* Ensures the link is still protected */
> -	bool (*check_link)(struct intel_digital_port *intel_dig_port);
> +	bool (*check_link)(struct intel_digital_port *intel_dig_port,
> +			   struct intel_connector *connector);
>  
>  	/* Detects panel's hdcp capability. This is optional for HDMI. */
>  	int (*hdcp_capable)(struct intel_digital_port *intel_dig_port,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> index e26a45f880cb..43446a6cae8d 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -223,7 +223,8 @@ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
>  }
>  
>  static
> -bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
> +bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> +			      struct intel_connector *connector)
>  {
>  	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
>  	ssize_t ret;
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index d79d4142aea7..6bd0e4616ee1 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -953,7 +953,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
>  		goto out;
>  	}
>  
> -	if (hdcp->shim->check_link(intel_dig_port)) {
> +	if (hdcp->shim->check_link(intel_dig_port, connector)) {
>  		if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
>  			intel_hdcp_update_value(connector,
>  				DRM_MODE_CONTENT_PROTECTION_ENABLED, true);
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index ca71ee3dd1c7..b12f1af0611d 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -1546,11 +1546,10 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
>  }
>  
>  static
> -bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port)
> +bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> +				struct intel_connector *connector)
>  {
>  	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> -	struct intel_connector *connector =
> -		intel_dig_port->hdmi.attached_connector;
>  	enum port port = intel_dig_port->base.port;
>  	enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder;
>  	int ret;
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 14/17] drm/i915: Add connector to hdcp_shim->check_link()
@ 2020-07-03 10:13     ` Anshuman Gupta
  0 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-03 10:13 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-06-23 at 21:29:04 +0530, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> Currently we derive the connector from digital port in check_link(). For
> MST, this isn't sufficient since the digital port passed into the
> function can have multiple connectors downstream. This patch adds
> connector to the check_link() arguments so we have it when we need it.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Looks good to me, this require a rebase on latest drm-tip
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
> Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-13-sean@poorly.run #v4
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-14-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-14-sean@poorly.run #v6
> 
> Changes in v4:
> -Added to the set
> Changes in v5:
> -None
> Changes in v6:
> -None
> Changes in v7:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_display_types.h | 3 ++-
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c       | 3 ++-
>  drivers/gpu/drm/i915/display/intel_hdcp.c          | 2 +-
>  drivers/gpu/drm/i915/display/intel_hdmi.c          | 5 ++---
>  4 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 811085ef3fba..94211b8fc159 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -318,7 +318,8 @@ struct intel_hdcp_shim {
>  				 bool enable);
>  
>  	/* Ensures the link is still protected */
> -	bool (*check_link)(struct intel_digital_port *intel_dig_port);
> +	bool (*check_link)(struct intel_digital_port *intel_dig_port,
> +			   struct intel_connector *connector);
>  
>  	/* Detects panel's hdcp capability. This is optional for HDMI. */
>  	int (*hdcp_capable)(struct intel_digital_port *intel_dig_port,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> index e26a45f880cb..43446a6cae8d 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -223,7 +223,8 @@ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
>  }
>  
>  static
> -bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
> +bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> +			      struct intel_connector *connector)
>  {
>  	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
>  	ssize_t ret;
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index d79d4142aea7..6bd0e4616ee1 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -953,7 +953,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
>  		goto out;
>  	}
>  
> -	if (hdcp->shim->check_link(intel_dig_port)) {
> +	if (hdcp->shim->check_link(intel_dig_port, connector)) {
>  		if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
>  			intel_hdcp_update_value(connector,
>  				DRM_MODE_CONTENT_PROTECTION_ENABLED, true);
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index ca71ee3dd1c7..b12f1af0611d 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -1546,11 +1546,10 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
>  }
>  
>  static
> -bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port)
> +bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> +				struct intel_connector *connector)
>  {
>  	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> -	struct intel_connector *connector =
> -		intel_dig_port->hdmi.attached_connector;
>  	enum port port = intel_dig_port->base.port;
>  	enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder;
>  	int ret;
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 13/17] drm/i915: Plumb port through hdcp init
  2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
@ 2020-07-03 10:22     ` Anshuman Gupta
  -1 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-03 10:22 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-06-23 at 21:29:03 +0530, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> This patch plumbs port through hdcp init instead of relying on
> intel_attached_encoder() to return a non-NULL encoder which won't work
> for MST connectors.
Looks good to me,
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-13-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-13-sean@poorly.run #v6
> 
> Changes in v5:
> -Added to the set
> Changes in v6:
> -None
> Changes in v7:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c |  3 ++-
>  drivers/gpu/drm/i915/display/intel_hdcp.c    | 11 ++++++-----
>  drivers/gpu/drm/i915/display/intel_hdcp.h    |  2 +-
>  drivers/gpu/drm/i915/display/intel_hdmi.c    |  2 +-
>  4 files changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> index 0e06a1066d61..e26a45f880cb 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -630,7 +630,8 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
>  		return 0;
>  
>  	if (!intel_dp_is_edp(intel_dp))
> -		return intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
> +		return intel_hdcp_init(intel_connector, port,
> +				       &intel_dp_hdcp_shim);
>  
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 5679877c6b4c..d79d4142aea7 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -1955,6 +1955,7 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum transcoder cpu_transcoder)
>  }
>  
>  static int initialize_hdcp_port_data(struct intel_connector *connector,
> +				     enum port port,
>  				     const struct intel_hdcp_shim *shim)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> @@ -1962,8 +1963,7 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
>  	struct hdcp_port_data *data = &hdcp->port_data;
>  
>  	if (INTEL_GEN(dev_priv) < 12)
> -		data->fw_ddi =
> -			intel_get_mei_fw_ddi_index(intel_attached_encoder(connector)->port);
> +		data->fw_ddi = intel_get_mei_fw_ddi_index(port);
>  	else
>  		/*
>  		 * As per ME FW API expectation, for GEN 12+, fw_ddi is filled
> @@ -2033,14 +2033,14 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
>  	}
>  }
>  
> -static void intel_hdcp2_init(struct intel_connector *connector,
> +static void intel_hdcp2_init(struct intel_connector *connector, enum port port,
>  			     const struct intel_hdcp_shim *shim)
>  {
>  	struct drm_i915_private *i915 = to_i915(connector->base.dev);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	int ret;
>  
> -	ret = initialize_hdcp_port_data(connector, shim);
> +	ret = initialize_hdcp_port_data(connector, port, shim);
>  	if (ret) {
>  		drm_dbg_kms(&i915->drm, "Mei hdcp data init failed\n");
>  		return;
> @@ -2050,6 +2050,7 @@ static void intel_hdcp2_init(struct intel_connector *connector,
>  }
>  
>  int intel_hdcp_init(struct intel_connector *connector,
> +		    enum port port,
>  		    const struct intel_hdcp_shim *shim)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> @@ -2060,7 +2061,7 @@ int intel_hdcp_init(struct intel_connector *connector,
>  		return -EINVAL;
>  
>  	if (is_hdcp2_supported(dev_priv))
> -		intel_hdcp2_init(connector, shim);
> +		intel_hdcp2_init(connector, port, shim);
>  
>  	ret =
>  	drm_connector_attach_content_protection_property(&connector->base,
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h
> index 86bbaec120cc..1bbf5b67ed0a 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.h
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.h
> @@ -22,7 +22,7 @@ enum transcoder;
>  void intel_hdcp_atomic_check(struct drm_connector *connector,
>  			     struct drm_connector_state *old_state,
>  			     struct drm_connector_state *new_state);
> -int intel_hdcp_init(struct intel_connector *connector,
> +int intel_hdcp_init(struct intel_connector *connector, enum port port,
>  		    const struct intel_hdcp_shim *hdcp_shim);
>  int intel_hdcp_enable(struct intel_connector *connector,
>  		      enum transcoder cpu_transcoder, u8 content_type);
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index a59acfff456e..ca71ee3dd1c7 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -3260,7 +3260,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
>  	intel_hdmi->attached_connector = intel_connector;
>  
>  	if (is_hdcp_supported(dev_priv, port)) {
> -		int ret = intel_hdcp_init(intel_connector,
> +		int ret = intel_hdcp_init(intel_connector, port,
>  					  &intel_hdmi_hdcp_shim);
>  		if (ret)
>  			drm_dbg_kms(&dev_priv->drm,
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 13/17] drm/i915: Plumb port through hdcp init
@ 2020-07-03 10:22     ` Anshuman Gupta
  0 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-03 10:22 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-06-23 at 21:29:03 +0530, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> This patch plumbs port through hdcp init instead of relying on
> intel_attached_encoder() to return a non-NULL encoder which won't work
> for MST connectors.
Looks good to me,
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-13-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-13-sean@poorly.run #v6
> 
> Changes in v5:
> -Added to the set
> Changes in v6:
> -None
> Changes in v7:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c |  3 ++-
>  drivers/gpu/drm/i915/display/intel_hdcp.c    | 11 ++++++-----
>  drivers/gpu/drm/i915/display/intel_hdcp.h    |  2 +-
>  drivers/gpu/drm/i915/display/intel_hdmi.c    |  2 +-
>  4 files changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> index 0e06a1066d61..e26a45f880cb 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -630,7 +630,8 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
>  		return 0;
>  
>  	if (!intel_dp_is_edp(intel_dp))
> -		return intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
> +		return intel_hdcp_init(intel_connector, port,
> +				       &intel_dp_hdcp_shim);
>  
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 5679877c6b4c..d79d4142aea7 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -1955,6 +1955,7 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum transcoder cpu_transcoder)
>  }
>  
>  static int initialize_hdcp_port_data(struct intel_connector *connector,
> +				     enum port port,
>  				     const struct intel_hdcp_shim *shim)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> @@ -1962,8 +1963,7 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
>  	struct hdcp_port_data *data = &hdcp->port_data;
>  
>  	if (INTEL_GEN(dev_priv) < 12)
> -		data->fw_ddi =
> -			intel_get_mei_fw_ddi_index(intel_attached_encoder(connector)->port);
> +		data->fw_ddi = intel_get_mei_fw_ddi_index(port);
>  	else
>  		/*
>  		 * As per ME FW API expectation, for GEN 12+, fw_ddi is filled
> @@ -2033,14 +2033,14 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
>  	}
>  }
>  
> -static void intel_hdcp2_init(struct intel_connector *connector,
> +static void intel_hdcp2_init(struct intel_connector *connector, enum port port,
>  			     const struct intel_hdcp_shim *shim)
>  {
>  	struct drm_i915_private *i915 = to_i915(connector->base.dev);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	int ret;
>  
> -	ret = initialize_hdcp_port_data(connector, shim);
> +	ret = initialize_hdcp_port_data(connector, port, shim);
>  	if (ret) {
>  		drm_dbg_kms(&i915->drm, "Mei hdcp data init failed\n");
>  		return;
> @@ -2050,6 +2050,7 @@ static void intel_hdcp2_init(struct intel_connector *connector,
>  }
>  
>  int intel_hdcp_init(struct intel_connector *connector,
> +		    enum port port,
>  		    const struct intel_hdcp_shim *shim)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> @@ -2060,7 +2061,7 @@ int intel_hdcp_init(struct intel_connector *connector,
>  		return -EINVAL;
>  
>  	if (is_hdcp2_supported(dev_priv))
> -		intel_hdcp2_init(connector, shim);
> +		intel_hdcp2_init(connector, port, shim);
>  
>  	ret =
>  	drm_connector_attach_content_protection_property(&connector->base,
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h
> index 86bbaec120cc..1bbf5b67ed0a 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.h
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.h
> @@ -22,7 +22,7 @@ enum transcoder;
>  void intel_hdcp_atomic_check(struct drm_connector *connector,
>  			     struct drm_connector_state *old_state,
>  			     struct drm_connector_state *new_state);
> -int intel_hdcp_init(struct intel_connector *connector,
> +int intel_hdcp_init(struct intel_connector *connector, enum port port,
>  		    const struct intel_hdcp_shim *hdcp_shim);
>  int intel_hdcp_enable(struct intel_connector *connector,
>  		      enum transcoder cpu_transcoder, u8 content_type);
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index a59acfff456e..ca71ee3dd1c7 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -3260,7 +3260,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
>  	intel_hdmi->attached_connector = intel_connector;
>  
>  	if (is_hdcp_supported(dev_priv, port)) {
> -		int ret = intel_hdcp_init(intel_connector,
> +		int ret = intel_hdcp_init(intel_connector, port,
>  					  &intel_hdmi_hdcp_shim);
>  		if (ret)
>  			drm_dbg_kms(&dev_priv->drm,
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
  2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
@ 2020-07-03 11:18     ` Anshuman Gupta
  -1 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-03 11:18 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-06-23 at 21:29:07 +0530, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> Now that all the groundwork has been laid, we can turn on HDCP 1.4 over
> MST. Everything except for toggling the HDCP signalling and HDCP 2.2
> support is the same as the DP case, so we'll re-use those callbacks
> 
> Cc: Juston Li <juston.li@intel.com>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-12-sean@poorly.run #v1
> Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-13-sean@poorly.run #v2
> Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-13-sean@poorly.run #v3
> Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-15-sean@poorly.run #v4
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-17-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-17-sean@poorly.run #v6
> 
> Changes in v2:
> -Toggle HDCP from encoder disable/enable
> -Don't disable HDCP on MST connector destroy, leave that for encoder
>  disable, just ensure the check_work routine isn't running any longer
> Changes in v3:
> -Place the shim in the new intel_dp_hdcp.c file (Ville)
> Changes in v4:
> -Actually use the mst shim for mst connections (Juston)
> -Use QUERY_STREAM_ENC_STATUS MST message to verify channel is encrypted
> Changes in v5:
> -Add sleep on disable signalling to match hdmi delay
> Changes in v6:
> -Disable HDCP over MST on GEN12+ since I'm unsure how it should work and I
>  don't have hardware to test it
> Changes in v7:
> -Remove hdcp2 shims for MST in favor of skipping hdcp2 init (Ramalingam)
> ---
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 66 +++++++++++++++++++-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  | 18 ++++++
>  drivers/gpu/drm/i915/display/intel_hdcp.c    |  2 +-
>  3 files changed, 84 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> index 43446a6cae8d..3f67bd27fc3c 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -7,10 +7,12 @@
>   */
>  
>  #include <drm/drm_dp_helper.h>
> +#include <drm/drm_dp_mst_helper.h>
>  #include <drm/drm_hdcp.h>
>  #include <drm/drm_print.h>
>  
>  #include "intel_display_types.h"
> +#include "intel_ddi.h"
>  #include "intel_dp.h"
>  #include "intel_hdcp.h"
>  
> @@ -618,6 +620,65 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
>  	.protocol = HDCP_PROTOCOL_DP,
>  };
>  
> +static int
> +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> +				    enum transcoder cpu_transcoder,
> +				    bool enable)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> +	int ret;
> +
> +	if (!enable)
> +		usleep_range(6, 60); /* Bspec says >= 6us */
> +
> +	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> +					       cpu_transcoder, enable);
> +	if (ret)
> +		drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> +			      enable ? "Enable" : "Disable", ret);
> +	return ret;
> +}
> +
> +static
> +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> +				  struct intel_connector *connector)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> +	struct intel_dp *intel_dp = &intel_dig_port->dp;
> +	struct drm_dp_query_stream_enc_status_ack_reply reply;
> +	int ret;
> +
> +	if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> +		return false;
> +
> +	ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> +						  connector->port, &reply);
> +	if (ret) {
> +		drm_dbg_kms(&i915->drm,
> +			    "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> +			    connector->base.base.id, connector->base.name, ret);
> +		return false;
> +	}
> +
> +	return reply.auth_completed && reply.encryption_enabled;
> +}
> +
> +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> +	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
> +	.read_bksv = intel_dp_hdcp_read_bksv,
> +	.read_bstatus = intel_dp_hdcp_read_bstatus,
> +	.repeater_present = intel_dp_hdcp_repeater_present,
> +	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
> +	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> +	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> +	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> +	.toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> +	.check_link = intel_dp_mst_hdcp_check_link,
> +	.hdcp_capable = intel_dp_hdcp_capable,
> +
> +	.protocol = HDCP_PROTOCOL_DP,
> +};
> +
>  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
>  		       struct intel_connector *intel_connector)
>  {
> @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
>  	if (!is_hdcp_supported(dev_priv, port))
>  		return 0;
>  
> -	if (!intel_dp_is_edp(intel_dp))
> +	if (intel_connector->mst_port)
> +		return intel_hdcp_init(intel_connector, port,
> +				       &intel_dp_mst_hdcp_shim);
> +	else if (!intel_dp_is_edp(intel_dp))
>  		return intel_hdcp_init(intel_connector, port,
>  				       &intel_dp_hdcp_shim);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 0675825dcc20..abaaeeb963d2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -37,6 +37,7 @@
>  #include "intel_dp.h"
>  #include "intel_dp_mst.h"
>  #include "intel_dpio_phy.h"
> +#include "intel_hdcp.h"
>  
>  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>  					    struct intel_crtc_state *crtc_state,
> @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
>  	drm_dbg_kms(&i915->drm, "active links %d\n",
>  		    intel_dp->active_mst_links);
>  
> +	intel_hdcp_disable(intel_mst->connector);
> +
>  	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
>  
>  	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
>  
>  	if (pipe_config->has_audio)
>  		intel_audio_codec_enable(encoder, pipe_config, conn_state);
> +
> +	/* Enable hdcp if it's desired */
> +	if (conn_state->content_protection ==
> +	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
> +		intel_hdcp_enable(to_intel_connector(conn_state->connector),
> +				  pipe_config->cpu_transcoder,
> +				  (u8)conn_state->hdcp_content_type);
I am not sure about that, do we need to enable HDCP for every
DP-MST connector here, it should be only immediate downstream connector
we should authenticate as repeater, after that it should be repeater
responsibility to authenticate further downstream connectors.

Tested this entire series on Gen12 H/W after removing the Gen12 restriction
condition with daisy-chain of two DP MST display.
Master DP MST connector has failed the repeater downstream authentication
due to error "KSV list failed to become ready" ETIMEDOUT.
Slave DP MST connector passes the authentication stage but failed to
enable the encryption.
Thanks,
Anshuman Gupta.
>  }
>  
>  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
>  	intel_attach_force_audio_property(connector);
>  	intel_attach_broadcast_rgb_property(connector);
>  
> +
> +	/* TODO: Figure out how to make HDCP work on GEN12+ */
> +	if (INTEL_GEN(dev_priv) < 12) {
> +		ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> +		if (ret)
> +			DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> +	}
> +
>  	/*
>  	 * Reuse the prop from the SST connector because we're
>  	 * not allowed to create new props after device registration.
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 6bd0e4616ee1..ddc9db8de2bc 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
>  	if (!shim)
>  		return -EINVAL;
>  
> -	if (is_hdcp2_supported(dev_priv))
> +	if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
>  		intel_hdcp2_init(connector, port, shim);
>  
>  	ret =
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
@ 2020-07-03 11:18     ` Anshuman Gupta
  0 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-03 11:18 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-06-23 at 21:29:07 +0530, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> Now that all the groundwork has been laid, we can turn on HDCP 1.4 over
> MST. Everything except for toggling the HDCP signalling and HDCP 2.2
> support is the same as the DP case, so we'll re-use those callbacks
> 
> Cc: Juston Li <juston.li@intel.com>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-12-sean@poorly.run #v1
> Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-13-sean@poorly.run #v2
> Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-13-sean@poorly.run #v3
> Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-15-sean@poorly.run #v4
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-17-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-17-sean@poorly.run #v6
> 
> Changes in v2:
> -Toggle HDCP from encoder disable/enable
> -Don't disable HDCP on MST connector destroy, leave that for encoder
>  disable, just ensure the check_work routine isn't running any longer
> Changes in v3:
> -Place the shim in the new intel_dp_hdcp.c file (Ville)
> Changes in v4:
> -Actually use the mst shim for mst connections (Juston)
> -Use QUERY_STREAM_ENC_STATUS MST message to verify channel is encrypted
> Changes in v5:
> -Add sleep on disable signalling to match hdmi delay
> Changes in v6:
> -Disable HDCP over MST on GEN12+ since I'm unsure how it should work and I
>  don't have hardware to test it
> Changes in v7:
> -Remove hdcp2 shims for MST in favor of skipping hdcp2 init (Ramalingam)
> ---
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 66 +++++++++++++++++++-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  | 18 ++++++
>  drivers/gpu/drm/i915/display/intel_hdcp.c    |  2 +-
>  3 files changed, 84 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> index 43446a6cae8d..3f67bd27fc3c 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -7,10 +7,12 @@
>   */
>  
>  #include <drm/drm_dp_helper.h>
> +#include <drm/drm_dp_mst_helper.h>
>  #include <drm/drm_hdcp.h>
>  #include <drm/drm_print.h>
>  
>  #include "intel_display_types.h"
> +#include "intel_ddi.h"
>  #include "intel_dp.h"
>  #include "intel_hdcp.h"
>  
> @@ -618,6 +620,65 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
>  	.protocol = HDCP_PROTOCOL_DP,
>  };
>  
> +static int
> +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> +				    enum transcoder cpu_transcoder,
> +				    bool enable)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> +	int ret;
> +
> +	if (!enable)
> +		usleep_range(6, 60); /* Bspec says >= 6us */
> +
> +	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> +					       cpu_transcoder, enable);
> +	if (ret)
> +		drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> +			      enable ? "Enable" : "Disable", ret);
> +	return ret;
> +}
> +
> +static
> +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> +				  struct intel_connector *connector)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> +	struct intel_dp *intel_dp = &intel_dig_port->dp;
> +	struct drm_dp_query_stream_enc_status_ack_reply reply;
> +	int ret;
> +
> +	if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> +		return false;
> +
> +	ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> +						  connector->port, &reply);
> +	if (ret) {
> +		drm_dbg_kms(&i915->drm,
> +			    "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> +			    connector->base.base.id, connector->base.name, ret);
> +		return false;
> +	}
> +
> +	return reply.auth_completed && reply.encryption_enabled;
> +}
> +
> +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> +	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
> +	.read_bksv = intel_dp_hdcp_read_bksv,
> +	.read_bstatus = intel_dp_hdcp_read_bstatus,
> +	.repeater_present = intel_dp_hdcp_repeater_present,
> +	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
> +	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> +	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> +	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> +	.toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> +	.check_link = intel_dp_mst_hdcp_check_link,
> +	.hdcp_capable = intel_dp_hdcp_capable,
> +
> +	.protocol = HDCP_PROTOCOL_DP,
> +};
> +
>  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
>  		       struct intel_connector *intel_connector)
>  {
> @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
>  	if (!is_hdcp_supported(dev_priv, port))
>  		return 0;
>  
> -	if (!intel_dp_is_edp(intel_dp))
> +	if (intel_connector->mst_port)
> +		return intel_hdcp_init(intel_connector, port,
> +				       &intel_dp_mst_hdcp_shim);
> +	else if (!intel_dp_is_edp(intel_dp))
>  		return intel_hdcp_init(intel_connector, port,
>  				       &intel_dp_hdcp_shim);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 0675825dcc20..abaaeeb963d2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -37,6 +37,7 @@
>  #include "intel_dp.h"
>  #include "intel_dp_mst.h"
>  #include "intel_dpio_phy.h"
> +#include "intel_hdcp.h"
>  
>  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>  					    struct intel_crtc_state *crtc_state,
> @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
>  	drm_dbg_kms(&i915->drm, "active links %d\n",
>  		    intel_dp->active_mst_links);
>  
> +	intel_hdcp_disable(intel_mst->connector);
> +
>  	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
>  
>  	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
>  
>  	if (pipe_config->has_audio)
>  		intel_audio_codec_enable(encoder, pipe_config, conn_state);
> +
> +	/* Enable hdcp if it's desired */
> +	if (conn_state->content_protection ==
> +	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
> +		intel_hdcp_enable(to_intel_connector(conn_state->connector),
> +				  pipe_config->cpu_transcoder,
> +				  (u8)conn_state->hdcp_content_type);
I am not sure about that, do we need to enable HDCP for every
DP-MST connector here, it should be only immediate downstream connector
we should authenticate as repeater, after that it should be repeater
responsibility to authenticate further downstream connectors.

Tested this entire series on Gen12 H/W after removing the Gen12 restriction
condition with daisy-chain of two DP MST display.
Master DP MST connector has failed the repeater downstream authentication
due to error "KSV list failed to become ready" ETIMEDOUT.
Slave DP MST connector passes the authentication stage but failed to
enable the encryption.
Thanks,
Anshuman Gupta.
>  }
>  
>  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
>  	intel_attach_force_audio_property(connector);
>  	intel_attach_broadcast_rgb_property(connector);
>  
> +
> +	/* TODO: Figure out how to make HDCP work on GEN12+ */
> +	if (INTEL_GEN(dev_priv) < 12) {
> +		ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> +		if (ret)
> +			DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> +	}
> +
>  	/*
>  	 * Reuse the prop from the SST connector because we're
>  	 * not allowed to create new props after device registration.
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 6bd0e4616ee1..ddc9db8de2bc 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
>  	if (!shim)
>  		return -EINVAL;
>  
> -	if (is_hdcp2_supported(dev_priv))
> +	if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
>  		intel_hdcp2_init(connector, port, shim);
>  
>  	ret =
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 08/17] drm/i915: Clean up intel_hdcp_disable
  2020-06-23 15:58   ` [Intel-gfx] " Sean Paul
@ 2020-07-03 11:36     ` Anshuman Gupta
  -1 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-03 11:36 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-06-23 at 21:28:58 +0530, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> Add an out label and un-indent hdcp disable in preparation for
> hdcp_mutex. No functional changes
LGTM
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-9-sean@poorly.run #v6
> 
> Changes in v7:
> -Split into separate patch (Ramalingam)
> ---
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 19 ++++++++++---------
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 62cab3aea745..16bf0fbe5f17 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -2113,16 +2113,17 @@ int intel_hdcp_disable(struct intel_connector *connector)
>  
>  	mutex_lock(&hdcp->mutex);
>  
> -	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
> -		intel_hdcp_update_value(connector,
> -					DRM_MODE_CONTENT_PROTECTION_UNDESIRED,
> -					false);
> -		if (hdcp->hdcp2_encrypted)
> -			ret = _intel_hdcp2_disable(connector);
> -		else if (hdcp->hdcp_encrypted)
> -			ret = _intel_hdcp_disable(connector);
> -	}
> +	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
> +		goto out;
>  
> +	intel_hdcp_update_value(connector,
> +				DRM_MODE_CONTENT_PROTECTION_UNDESIRED, false);
> +	if (hdcp->hdcp2_encrypted)
> +		ret = _intel_hdcp2_disable(connector);
> +	else if (hdcp->hdcp_encrypted)
> +		ret = _intel_hdcp_disable(connector);
> +
> +out:
>  	mutex_unlock(&hdcp->mutex);
>  	cancel_delayed_work_sync(&hdcp->check_work);
>  	return ret;
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 08/17] drm/i915: Clean up intel_hdcp_disable
@ 2020-07-03 11:36     ` Anshuman Gupta
  0 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-03 11:36 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-06-23 at 21:28:58 +0530, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> Add an out label and un-indent hdcp disable in preparation for
> hdcp_mutex. No functional changes
LGTM
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-9-sean@poorly.run #v6
> 
> Changes in v7:
> -Split into separate patch (Ramalingam)
> ---
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 19 ++++++++++---------
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 62cab3aea745..16bf0fbe5f17 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -2113,16 +2113,17 @@ int intel_hdcp_disable(struct intel_connector *connector)
>  
>  	mutex_lock(&hdcp->mutex);
>  
> -	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
> -		intel_hdcp_update_value(connector,
> -					DRM_MODE_CONTENT_PROTECTION_UNDESIRED,
> -					false);
> -		if (hdcp->hdcp2_encrypted)
> -			ret = _intel_hdcp2_disable(connector);
> -		else if (hdcp->hdcp_encrypted)
> -			ret = _intel_hdcp_disable(connector);
> -	}
> +	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
> +		goto out;
>  
> +	intel_hdcp_update_value(connector,
> +				DRM_MODE_CONTENT_PROTECTION_UNDESIRED, false);
> +	if (hdcp->hdcp2_encrypted)
> +		ret = _intel_hdcp2_disable(connector);
> +	else if (hdcp->hdcp_encrypted)
> +		ret = _intel_hdcp_disable(connector);
> +
> +out:
>  	mutex_unlock(&hdcp->mutex);
>  	cancel_delayed_work_sync(&hdcp->check_work);
>  	return ret;
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
  2020-07-03 11:18     ` Anshuman Gupta
@ 2020-07-03 14:55       ` Anshuman Gupta
  -1 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-03 14:55 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-07-03 at 16:48:27 +0530, Anshuman Gupta wrote:
> On 2020-06-23 at 21:29:07 +0530, Sean Paul wrote:
> > From: Sean Paul <seanpaul@chromium.org>
> > 
> > Now that all the groundwork has been laid, we can turn on HDCP 1.4 over
> > MST. Everything except for toggling the HDCP signalling and HDCP 2.2
> > support is the same as the DP case, so we'll re-use those callbacks
> > 
> > Cc: Juston Li <juston.li@intel.com>
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-12-sean@poorly.run #v1
> > Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-13-sean@poorly.run #v2
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-13-sean@poorly.run #v3
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-15-sean@poorly.run #v4
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-17-sean@poorly.run #v5
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-17-sean@poorly.run #v6
> > 
> > Changes in v2:
> > -Toggle HDCP from encoder disable/enable
> > -Don't disable HDCP on MST connector destroy, leave that for encoder
> >  disable, just ensure the check_work routine isn't running any longer
> > Changes in v3:
> > -Place the shim in the new intel_dp_hdcp.c file (Ville)
> > Changes in v4:
> > -Actually use the mst shim for mst connections (Juston)
> > -Use QUERY_STREAM_ENC_STATUS MST message to verify channel is encrypted
> > Changes in v5:
> > -Add sleep on disable signalling to match hdmi delay
> > Changes in v6:
> > -Disable HDCP over MST on GEN12+ since I'm unsure how it should work and I
> >  don't have hardware to test it
> > Changes in v7:
> > -Remove hdcp2 shims for MST in favor of skipping hdcp2 init (Ramalingam)
> > ---
> >  drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 66 +++++++++++++++++++-
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c  | 18 ++++++
> >  drivers/gpu/drm/i915/display/intel_hdcp.c    |  2 +-
> >  3 files changed, 84 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> > index 43446a6cae8d..3f67bd27fc3c 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> > @@ -7,10 +7,12 @@
> >   */
> >  
> >  #include <drm/drm_dp_helper.h>
> > +#include <drm/drm_dp_mst_helper.h>
> >  #include <drm/drm_hdcp.h>
> >  #include <drm/drm_print.h>
> >  
> >  #include "intel_display_types.h"
> > +#include "intel_ddi.h"
> >  #include "intel_dp.h"
> >  #include "intel_hdcp.h"
> >  
> > @@ -618,6 +620,65 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
> >  	.protocol = HDCP_PROTOCOL_DP,
> >  };
> >  
> > +static int
> > +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> > +				    enum transcoder cpu_transcoder,
> > +				    bool enable)
> > +{
> > +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > +	int ret;
> > +
> > +	if (!enable)
> > +		usleep_range(6, 60); /* Bspec says >= 6us */
> > +
> > +	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> > +					       cpu_transcoder, enable);
> > +	if (ret)
> > +		drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> > +			      enable ? "Enable" : "Disable", ret);
> > +	return ret;
> > +}
> > +
> > +static
> > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> > +				  struct intel_connector *connector)
> > +{
> > +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > +	struct intel_dp *intel_dp = &intel_dig_port->dp;
> > +	struct drm_dp_query_stream_enc_status_ack_reply reply;
> > +	int ret;
> > +
> > +	if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> > +		return false;
> > +
> > +	ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> > +						  connector->port, &reply);
> > +	if (ret) {
> > +		drm_dbg_kms(&i915->drm,
> > +			    "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> > +			    connector->base.base.id, connector->base.name, ret);
> > +		return false;
> > +	}
> > +
> > +	return reply.auth_completed && reply.encryption_enabled;
> > +}
> > +
> > +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> > +	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > +	.read_bksv = intel_dp_hdcp_read_bksv,
> > +	.read_bstatus = intel_dp_hdcp_read_bstatus,
> > +	.repeater_present = intel_dp_hdcp_repeater_present,
> > +	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
> > +	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> > +	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> > +	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> > +	.toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> > +	.check_link = intel_dp_mst_hdcp_check_link,
> > +	.hdcp_capable = intel_dp_hdcp_capable,
> > +
> > +	.protocol = HDCP_PROTOCOL_DP,
> > +};
> > +
> >  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> >  		       struct intel_connector *intel_connector)
> >  {
> > @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> >  	if (!is_hdcp_supported(dev_priv, port))
> >  		return 0;
> >  
> > -	if (!intel_dp_is_edp(intel_dp))
> > +	if (intel_connector->mst_port)
> > +		return intel_hdcp_init(intel_connector, port,
> > +				       &intel_dp_mst_hdcp_shim);
> > +	else if (!intel_dp_is_edp(intel_dp))
> >  		return intel_hdcp_init(intel_connector, port,
> >  				       &intel_dp_hdcp_shim);
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index 0675825dcc20..abaaeeb963d2 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -37,6 +37,7 @@
> >  #include "intel_dp.h"
> >  #include "intel_dp_mst.h"
> >  #include "intel_dpio_phy.h"
> > +#include "intel_hdcp.h"
> >  
> >  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> >  					    struct intel_crtc_state *crtc_state,
> > @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
> >  	drm_dbg_kms(&i915->drm, "active links %d\n",
> >  		    intel_dp->active_mst_links);
> >  
> > +	intel_hdcp_disable(intel_mst->connector);
> > +
> >  	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
> >  
> >  	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> > @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
> >  
> >  	if (pipe_config->has_audio)
> >  		intel_audio_codec_enable(encoder, pipe_config, conn_state);
> > +
> > +	/* Enable hdcp if it's desired */
> > +	if (conn_state->content_protection ==
> > +	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > +		intel_hdcp_enable(to_intel_connector(conn_state->connector),
> > +				  pipe_config->cpu_transcoder,
> > +				  (u8)conn_state->hdcp_content_type);
> I am not sure about that, do we need to enable HDCP for every
> DP-MST connector here, it should be only immediate downstream connector
> we should authenticate as repeater, after that it should be repeater
> responsibility to authenticate further downstream connectors.
> 
> Tested this entire series on Gen12 H/W after removing the Gen12 restriction
> condition with daisy-chain of two DP MST display.
> Master DP MST connector has failed the repeater downstream authentication
> due to error "KSV list failed to become ready" ETIMEDOUT.
> Slave DP MST connector passes the authentication stage but failed to
> enable the encryption.
For Gen12 we should pass pipe_config->mst_master_transcoder as Gen12 has
HDCP instance per transcoder, after passing mst_master_transcoder, 
HDCP encryption is enabled on slave DP MST connector. 
(it authenticated as repeater with three downstream deivce) but master 
DP MST connector continue to fails the repeater downstream authentication due to
KSV list were not ready error.
Thanks,
Anshuman Gupta.
> Thanks,
> Anshuman Gupta.
> >  }
> >  
> >  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> > @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
> >  	intel_attach_force_audio_property(connector);
> >  	intel_attach_broadcast_rgb_property(connector);
> >  
> > +
> > +	/* TODO: Figure out how to make HDCP work on GEN12+ */
> > +	if (INTEL_GEN(dev_priv) < 12) {
> > +		ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> > +		if (ret)
> > +			DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> > +	}
> > +
> >  	/*
> >  	 * Reuse the prop from the SST connector because we're
> >  	 * not allowed to create new props after device registration.
> > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > index 6bd0e4616ee1..ddc9db8de2bc 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
> >  	if (!shim)
> >  		return -EINVAL;
> >  
> > -	if (is_hdcp2_supported(dev_priv))
> > +	if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
> >  		intel_hdcp2_init(connector, port, shim);
> >  
> >  	ret =
> > -- 
> > Sean Paul, Software Engineer, Google / Chromium OS
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
@ 2020-07-03 14:55       ` Anshuman Gupta
  0 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-03 14:55 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-07-03 at 16:48:27 +0530, Anshuman Gupta wrote:
> On 2020-06-23 at 21:29:07 +0530, Sean Paul wrote:
> > From: Sean Paul <seanpaul@chromium.org>
> > 
> > Now that all the groundwork has been laid, we can turn on HDCP 1.4 over
> > MST. Everything except for toggling the HDCP signalling and HDCP 2.2
> > support is the same as the DP case, so we'll re-use those callbacks
> > 
> > Cc: Juston Li <juston.li@intel.com>
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-12-sean@poorly.run #v1
> > Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-13-sean@poorly.run #v2
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-13-sean@poorly.run #v3
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-15-sean@poorly.run #v4
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-17-sean@poorly.run #v5
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-17-sean@poorly.run #v6
> > 
> > Changes in v2:
> > -Toggle HDCP from encoder disable/enable
> > -Don't disable HDCP on MST connector destroy, leave that for encoder
> >  disable, just ensure the check_work routine isn't running any longer
> > Changes in v3:
> > -Place the shim in the new intel_dp_hdcp.c file (Ville)
> > Changes in v4:
> > -Actually use the mst shim for mst connections (Juston)
> > -Use QUERY_STREAM_ENC_STATUS MST message to verify channel is encrypted
> > Changes in v5:
> > -Add sleep on disable signalling to match hdmi delay
> > Changes in v6:
> > -Disable HDCP over MST on GEN12+ since I'm unsure how it should work and I
> >  don't have hardware to test it
> > Changes in v7:
> > -Remove hdcp2 shims for MST in favor of skipping hdcp2 init (Ramalingam)
> > ---
> >  drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 66 +++++++++++++++++++-
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c  | 18 ++++++
> >  drivers/gpu/drm/i915/display/intel_hdcp.c    |  2 +-
> >  3 files changed, 84 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> > index 43446a6cae8d..3f67bd27fc3c 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> > @@ -7,10 +7,12 @@
> >   */
> >  
> >  #include <drm/drm_dp_helper.h>
> > +#include <drm/drm_dp_mst_helper.h>
> >  #include <drm/drm_hdcp.h>
> >  #include <drm/drm_print.h>
> >  
> >  #include "intel_display_types.h"
> > +#include "intel_ddi.h"
> >  #include "intel_dp.h"
> >  #include "intel_hdcp.h"
> >  
> > @@ -618,6 +620,65 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
> >  	.protocol = HDCP_PROTOCOL_DP,
> >  };
> >  
> > +static int
> > +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> > +				    enum transcoder cpu_transcoder,
> > +				    bool enable)
> > +{
> > +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > +	int ret;
> > +
> > +	if (!enable)
> > +		usleep_range(6, 60); /* Bspec says >= 6us */
> > +
> > +	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> > +					       cpu_transcoder, enable);
> > +	if (ret)
> > +		drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> > +			      enable ? "Enable" : "Disable", ret);
> > +	return ret;
> > +}
> > +
> > +static
> > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> > +				  struct intel_connector *connector)
> > +{
> > +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > +	struct intel_dp *intel_dp = &intel_dig_port->dp;
> > +	struct drm_dp_query_stream_enc_status_ack_reply reply;
> > +	int ret;
> > +
> > +	if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> > +		return false;
> > +
> > +	ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> > +						  connector->port, &reply);
> > +	if (ret) {
> > +		drm_dbg_kms(&i915->drm,
> > +			    "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> > +			    connector->base.base.id, connector->base.name, ret);
> > +		return false;
> > +	}
> > +
> > +	return reply.auth_completed && reply.encryption_enabled;
> > +}
> > +
> > +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> > +	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > +	.read_bksv = intel_dp_hdcp_read_bksv,
> > +	.read_bstatus = intel_dp_hdcp_read_bstatus,
> > +	.repeater_present = intel_dp_hdcp_repeater_present,
> > +	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
> > +	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> > +	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> > +	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> > +	.toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> > +	.check_link = intel_dp_mst_hdcp_check_link,
> > +	.hdcp_capable = intel_dp_hdcp_capable,
> > +
> > +	.protocol = HDCP_PROTOCOL_DP,
> > +};
> > +
> >  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> >  		       struct intel_connector *intel_connector)
> >  {
> > @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> >  	if (!is_hdcp_supported(dev_priv, port))
> >  		return 0;
> >  
> > -	if (!intel_dp_is_edp(intel_dp))
> > +	if (intel_connector->mst_port)
> > +		return intel_hdcp_init(intel_connector, port,
> > +				       &intel_dp_mst_hdcp_shim);
> > +	else if (!intel_dp_is_edp(intel_dp))
> >  		return intel_hdcp_init(intel_connector, port,
> >  				       &intel_dp_hdcp_shim);
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index 0675825dcc20..abaaeeb963d2 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -37,6 +37,7 @@
> >  #include "intel_dp.h"
> >  #include "intel_dp_mst.h"
> >  #include "intel_dpio_phy.h"
> > +#include "intel_hdcp.h"
> >  
> >  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> >  					    struct intel_crtc_state *crtc_state,
> > @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
> >  	drm_dbg_kms(&i915->drm, "active links %d\n",
> >  		    intel_dp->active_mst_links);
> >  
> > +	intel_hdcp_disable(intel_mst->connector);
> > +
> >  	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
> >  
> >  	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> > @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
> >  
> >  	if (pipe_config->has_audio)
> >  		intel_audio_codec_enable(encoder, pipe_config, conn_state);
> > +
> > +	/* Enable hdcp if it's desired */
> > +	if (conn_state->content_protection ==
> > +	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > +		intel_hdcp_enable(to_intel_connector(conn_state->connector),
> > +				  pipe_config->cpu_transcoder,
> > +				  (u8)conn_state->hdcp_content_type);
> I am not sure about that, do we need to enable HDCP for every
> DP-MST connector here, it should be only immediate downstream connector
> we should authenticate as repeater, after that it should be repeater
> responsibility to authenticate further downstream connectors.
> 
> Tested this entire series on Gen12 H/W after removing the Gen12 restriction
> condition with daisy-chain of two DP MST display.
> Master DP MST connector has failed the repeater downstream authentication
> due to error "KSV list failed to become ready" ETIMEDOUT.
> Slave DP MST connector passes the authentication stage but failed to
> enable the encryption.
For Gen12 we should pass pipe_config->mst_master_transcoder as Gen12 has
HDCP instance per transcoder, after passing mst_master_transcoder, 
HDCP encryption is enabled on slave DP MST connector. 
(it authenticated as repeater with three downstream deivce) but master 
DP MST connector continue to fails the repeater downstream authentication due to
KSV list were not ready error.
Thanks,
Anshuman Gupta.
> Thanks,
> Anshuman Gupta.
> >  }
> >  
> >  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> > @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
> >  	intel_attach_force_audio_property(connector);
> >  	intel_attach_broadcast_rgb_property(connector);
> >  
> > +
> > +	/* TODO: Figure out how to make HDCP work on GEN12+ */
> > +	if (INTEL_GEN(dev_priv) < 12) {
> > +		ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> > +		if (ret)
> > +			DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> > +	}
> > +
> >  	/*
> >  	 * Reuse the prop from the SST connector because we're
> >  	 * not allowed to create new props after device registration.
> > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > index 6bd0e4616ee1..ddc9db8de2bc 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
> >  	if (!shim)
> >  		return -EINVAL;
> >  
> > -	if (is_hdcp2_supported(dev_priv))
> > +	if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
> >  		intel_hdcp2_init(connector, port, shim);
> >  
> >  	ret =
> > -- 
> > Sean Paul, Software Engineer, Google / Chromium OS
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v7 08/17] drm/i915: Clean up intel_hdcp_disable
  2020-06-23 15:58   ` [Intel-gfx] " Sean Paul
@ 2020-07-09  5:40     ` Ramalingam C
  -1 siblings, 0 replies; 98+ messages in thread
From: Ramalingam C @ 2020-07-09  5:40 UTC (permalink / raw)
  To: Sean Paul
  Cc: dri-devel, daniel.vetter, intel-gfx, Sean Paul, juston.li, rodrigo.vivi

On 2020-06-23 at 11:58:58 -0400, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> Add an out label and un-indent hdcp disable in preparation for
> hdcp_mutex. No functional changes
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-9-sean@poorly.run #v6
> 
> Changes in v7:
> -Split into separate patch (Ramalingam)
> ---
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 19 ++++++++++---------
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 62cab3aea745..16bf0fbe5f17 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -2113,16 +2113,17 @@ int intel_hdcp_disable(struct intel_connector *connector)
>  
>  	mutex_lock(&hdcp->mutex);
>  
> -	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
> -		intel_hdcp_update_value(connector,
> -					DRM_MODE_CONTENT_PROTECTION_UNDESIRED,
> -					false);
> -		if (hdcp->hdcp2_encrypted)
> -			ret = _intel_hdcp2_disable(connector);
> -		else if (hdcp->hdcp_encrypted)
> -			ret = _intel_hdcp_disable(connector);
> -	}
> +	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
> +		goto out;
>  
> +	intel_hdcp_update_value(connector,
> +				DRM_MODE_CONTENT_PROTECTION_UNDESIRED, false);
> +	if (hdcp->hdcp2_encrypted)
> +		ret = _intel_hdcp2_disable(connector);
> +	else if (hdcp->hdcp_encrypted)
> +		ret = _intel_hdcp_disable(connector);
> +
> +out:
>  	mutex_unlock(&hdcp->mutex);
>  	cancel_delayed_work_sync(&hdcp->check_work);
>  	return ret;
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 08/17] drm/i915: Clean up intel_hdcp_disable
@ 2020-07-09  5:40     ` Ramalingam C
  0 siblings, 0 replies; 98+ messages in thread
From: Ramalingam C @ 2020-07-09  5:40 UTC (permalink / raw)
  To: Sean Paul; +Cc: dri-devel, daniel.vetter, intel-gfx, Sean Paul

On 2020-06-23 at 11:58:58 -0400, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> Add an out label and un-indent hdcp disable in preparation for
> hdcp_mutex. No functional changes
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-9-sean@poorly.run #v6
> 
> Changes in v7:
> -Split into separate patch (Ramalingam)
> ---
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 19 ++++++++++---------
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 62cab3aea745..16bf0fbe5f17 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -2113,16 +2113,17 @@ int intel_hdcp_disable(struct intel_connector *connector)
>  
>  	mutex_lock(&hdcp->mutex);
>  
> -	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
> -		intel_hdcp_update_value(connector,
> -					DRM_MODE_CONTENT_PROTECTION_UNDESIRED,
> -					false);
> -		if (hdcp->hdcp2_encrypted)
> -			ret = _intel_hdcp2_disable(connector);
> -		else if (hdcp->hdcp_encrypted)
> -			ret = _intel_hdcp_disable(connector);
> -	}
> +	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
> +		goto out;
>  
> +	intel_hdcp_update_value(connector,
> +				DRM_MODE_CONTENT_PROTECTION_UNDESIRED, false);
> +	if (hdcp->hdcp2_encrypted)
> +		ret = _intel_hdcp2_disable(connector);
> +	else if (hdcp->hdcp_encrypted)
> +		ret = _intel_hdcp_disable(connector);
> +
> +out:
>  	mutex_unlock(&hdcp->mutex);
>  	cancel_delayed_work_sync(&hdcp->check_work);
>  	return ret;
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v7 09/17] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
  2020-06-23 15:58   ` [Intel-gfx] " Sean Paul
@ 2020-07-09  5:57     ` Ramalingam C
  -1 siblings, 0 replies; 98+ messages in thread
From: Ramalingam C @ 2020-07-09  5:57 UTC (permalink / raw)
  To: Sean Paul
  Cc: dri-devel, daniel.vetter, intel-gfx, Sean Paul, juston.li, rodrigo.vivi

On 2020-06-23 at 11:58:59 -0400, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> This patch is required for HDCP over MST. If a port is being used for
> multiple HDCP streams, we don't want to fully disable HDCP on a port if
> one of them is disabled. Instead, we just disable the HDCP signalling on
> that particular pipe and exit early. The last pipe to disable HDCP will
> also bring down HDCP on the port.
> 
> In order to achieve this, we need to keep a refcount in intel_digital_port
> and protect it using a new hdcp_mutex.
> 
> Cc: Ramalingam C <ramalingam.c@intel.com>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-8-sean@poorly.run #v1
> Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-9-sean@poorly.run #v2
> Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-9-sean@poorly.run #v3
> Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-9-sean@poorly.run #v4
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-9-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-9-sean@poorly.run #v6
> 
> Changes in v2:
> -Move the toggle_signalling call into _intel_hdcp_disable so it's called from check_work
> Changes in v3:
> -None
> Changes in v4:
> -None
> Changes in v5:
> -Change WARN_ON to drm_WARN_ON
> Changes in v6:
> -None
> Changes in v7:
> -Split minor intel_hdcp_disable refactor into separate patch (Ramalingam)
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  3 ++
>  .../drm/i915/display/intel_display_types.h    |  5 +++
>  drivers/gpu/drm/i915/display/intel_dp.c       |  2 ++
>  drivers/gpu/drm/i915/display/intel_hdcp.c     | 33 +++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_hdmi.c     |  2 ++
>  5 files changed, 45 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 4153a0d1e07d..536299f902b9 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4884,6 +4884,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
>  	drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
>  			 DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port));
>  
> +	mutex_init(&intel_dig_port->hdcp_mutex);
> +	intel_dig_port->num_hdcp_streams = 0;
> +
>  	encoder->hotplug = intel_ddi_hotplug;
>  	encoder->compute_output_type = intel_ddi_compute_output_type;
>  	encoder->compute_config = intel_ddi_compute_config;
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index fc0befd55420..1503403a808b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1410,6 +1410,11 @@ struct intel_digital_port {
>  	enum phy_fia tc_phy_fia;
>  	u8 tc_phy_fia_idx;
>  
> +	/* protects num_hdcp_streams reference count */
> +	struct mutex hdcp_mutex;
> +	/* the number of pipes using HDCP signalling out of this port */
> +	unsigned int num_hdcp_streams;
> +
>  	void (*write_infoframe)(struct intel_encoder *encoder,
>  				const struct intel_crtc_state *crtc_state,
>  				unsigned int type,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index d0fea51f5dec..d98e45a09c28 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -8276,6 +8276,8 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
>  	intel_encoder = &intel_dig_port->base;
>  	encoder = &intel_encoder->base;
>  
> +	mutex_init(&intel_dig_port->hdcp_mutex);
> +
>  	if (drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
>  			     &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS,
>  			     "DP %c", port_name(port)))
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 16bf0fbe5f17..5679877c6b4c 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -801,6 +801,19 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
>  	drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP is being disabled...\n",
>  		    connector->base.name, connector->base.base.id);
>  
> +	/*
> +	 * If there are other connectors on this port using HDCP, don't disable
> +	 * it. Instead, toggle the HDCP signalling off on that particular
> +	 * connector/pipe and exit.
> +	 */
> +	if (intel_dig_port->num_hdcp_streams > 0) {
> +		ret = hdcp->shim->toggle_signalling(intel_dig_port,
> +						    cpu_transcoder, false);
Sean,

Toggling for DP SST was empty. For MST also HW spec doesn't say the bit
is applicable (This bit is ignored when not in HDMI or DVI modes.)

Is there anywhere you saw this is needed for MST?

Leaving this discussion for mst shim implementation patch 17/17, and considering
this function is dummy as it was for DP SST,

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> +		if (ret)
> +			DRM_ERROR("Failed to disable HDCP signalling\n");
> +		return ret;
> +	}
> +
>  	hdcp->hdcp_encrypted = false;
>  	intel_de_write(dev_priv, HDCP_CONF(dev_priv, cpu_transcoder, port), 0);
>  	if (intel_de_wait_for_clear(dev_priv,
> @@ -880,6 +893,8 @@ static struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
>  static void intel_hdcp_update_value(struct intel_connector *connector,
>  				    u64 value, bool update_property)
>  {
> +	struct drm_device *dev = connector->base.dev;
> +	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  
>  	drm_WARN_ON(connector->base.dev, !mutex_is_locked(&hdcp->mutex));
> @@ -887,6 +902,15 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
>  	if (hdcp->value == value)
>  		return;
>  
> +	drm_WARN_ON(dev, !mutex_is_locked(&intel_dig_port->hdcp_mutex));
> +
> +	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
> +		if (!drm_WARN_ON(dev, intel_dig_port->num_hdcp_streams == 0))
> +			intel_dig_port->num_hdcp_streams--;
> +	} else if (value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
> +		intel_dig_port->num_hdcp_streams++;
> +	}
> +
>  	hdcp->value = value;
>  	if (update_property) {
>  		drm_connector_get(&connector->base);
> @@ -905,6 +929,8 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
>  	int ret = 0;
>  
>  	mutex_lock(&hdcp->mutex);
> +	mutex_lock(&intel_dig_port->hdcp_mutex);
> +
>  	cpu_transcoder = hdcp->cpu_transcoder;
>  
>  	/* Check_link valid only when HDCP1.4 is enabled */
> @@ -958,6 +984,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
>  	}
>  
>  out:
> +	mutex_unlock(&intel_dig_port->hdcp_mutex);
>  	mutex_unlock(&hdcp->mutex);
>  	return ret;
>  }
> @@ -2057,6 +2084,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
>  		      enum transcoder cpu_transcoder, u8 content_type)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
>  	int ret = -EINVAL;
> @@ -2065,6 +2093,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
>  		return -ENOENT;
>  
>  	mutex_lock(&hdcp->mutex);
> +	mutex_lock(&intel_dig_port->hdcp_mutex);
>  	drm_WARN_ON(&dev_priv->drm,
>  		    hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
>  	hdcp->content_type = content_type;
> @@ -2099,12 +2128,14 @@ int intel_hdcp_enable(struct intel_connector *connector,
>  					true);
>  	}
>  
> +	mutex_unlock(&intel_dig_port->hdcp_mutex);
>  	mutex_unlock(&hdcp->mutex);
>  	return ret;
>  }
>  
>  int intel_hdcp_disable(struct intel_connector *connector)
>  {
> +	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	int ret = 0;
>  
> @@ -2112,6 +2143,7 @@ int intel_hdcp_disable(struct intel_connector *connector)
>  		return -ENOENT;
>  
>  	mutex_lock(&hdcp->mutex);
> +	mutex_lock(&intel_dig_port->hdcp_mutex);
>  
>  	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
>  		goto out;
> @@ -2124,6 +2156,7 @@ int intel_hdcp_disable(struct intel_connector *connector)
>  		ret = _intel_hdcp_disable(connector);
>  
>  out:
> +	mutex_unlock(&intel_dig_port->hdcp_mutex);
>  	mutex_unlock(&hdcp->mutex);
>  	cancel_delayed_work_sync(&hdcp->check_work);
>  	return ret;
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index ab7bddf0dfdc..a59acfff456e 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -3331,6 +3331,8 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
>  
>  	intel_encoder = &intel_dig_port->base;
>  
> +	mutex_init(&intel_dig_port->hdcp_mutex);
> +
>  	drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
>  			 &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,
>  			 "HDMI %c", port_name(port));
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 09/17] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
@ 2020-07-09  5:57     ` Ramalingam C
  0 siblings, 0 replies; 98+ messages in thread
From: Ramalingam C @ 2020-07-09  5:57 UTC (permalink / raw)
  To: Sean Paul; +Cc: dri-devel, daniel.vetter, intel-gfx, Sean Paul

On 2020-06-23 at 11:58:59 -0400, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> This patch is required for HDCP over MST. If a port is being used for
> multiple HDCP streams, we don't want to fully disable HDCP on a port if
> one of them is disabled. Instead, we just disable the HDCP signalling on
> that particular pipe and exit early. The last pipe to disable HDCP will
> also bring down HDCP on the port.
> 
> In order to achieve this, we need to keep a refcount in intel_digital_port
> and protect it using a new hdcp_mutex.
> 
> Cc: Ramalingam C <ramalingam.c@intel.com>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-8-sean@poorly.run #v1
> Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-9-sean@poorly.run #v2
> Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-9-sean@poorly.run #v3
> Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-9-sean@poorly.run #v4
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-9-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-9-sean@poorly.run #v6
> 
> Changes in v2:
> -Move the toggle_signalling call into _intel_hdcp_disable so it's called from check_work
> Changes in v3:
> -None
> Changes in v4:
> -None
> Changes in v5:
> -Change WARN_ON to drm_WARN_ON
> Changes in v6:
> -None
> Changes in v7:
> -Split minor intel_hdcp_disable refactor into separate patch (Ramalingam)
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  3 ++
>  .../drm/i915/display/intel_display_types.h    |  5 +++
>  drivers/gpu/drm/i915/display/intel_dp.c       |  2 ++
>  drivers/gpu/drm/i915/display/intel_hdcp.c     | 33 +++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_hdmi.c     |  2 ++
>  5 files changed, 45 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 4153a0d1e07d..536299f902b9 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4884,6 +4884,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
>  	drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
>  			 DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port));
>  
> +	mutex_init(&intel_dig_port->hdcp_mutex);
> +	intel_dig_port->num_hdcp_streams = 0;
> +
>  	encoder->hotplug = intel_ddi_hotplug;
>  	encoder->compute_output_type = intel_ddi_compute_output_type;
>  	encoder->compute_config = intel_ddi_compute_config;
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index fc0befd55420..1503403a808b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1410,6 +1410,11 @@ struct intel_digital_port {
>  	enum phy_fia tc_phy_fia;
>  	u8 tc_phy_fia_idx;
>  
> +	/* protects num_hdcp_streams reference count */
> +	struct mutex hdcp_mutex;
> +	/* the number of pipes using HDCP signalling out of this port */
> +	unsigned int num_hdcp_streams;
> +
>  	void (*write_infoframe)(struct intel_encoder *encoder,
>  				const struct intel_crtc_state *crtc_state,
>  				unsigned int type,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index d0fea51f5dec..d98e45a09c28 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -8276,6 +8276,8 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
>  	intel_encoder = &intel_dig_port->base;
>  	encoder = &intel_encoder->base;
>  
> +	mutex_init(&intel_dig_port->hdcp_mutex);
> +
>  	if (drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
>  			     &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS,
>  			     "DP %c", port_name(port)))
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 16bf0fbe5f17..5679877c6b4c 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -801,6 +801,19 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
>  	drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP is being disabled...\n",
>  		    connector->base.name, connector->base.base.id);
>  
> +	/*
> +	 * If there are other connectors on this port using HDCP, don't disable
> +	 * it. Instead, toggle the HDCP signalling off on that particular
> +	 * connector/pipe and exit.
> +	 */
> +	if (intel_dig_port->num_hdcp_streams > 0) {
> +		ret = hdcp->shim->toggle_signalling(intel_dig_port,
> +						    cpu_transcoder, false);
Sean,

Toggling for DP SST was empty. For MST also HW spec doesn't say the bit
is applicable (This bit is ignored when not in HDMI or DVI modes.)

Is there anywhere you saw this is needed for MST?

Leaving this discussion for mst shim implementation patch 17/17, and considering
this function is dummy as it was for DP SST,

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> +		if (ret)
> +			DRM_ERROR("Failed to disable HDCP signalling\n");
> +		return ret;
> +	}
> +
>  	hdcp->hdcp_encrypted = false;
>  	intel_de_write(dev_priv, HDCP_CONF(dev_priv, cpu_transcoder, port), 0);
>  	if (intel_de_wait_for_clear(dev_priv,
> @@ -880,6 +893,8 @@ static struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
>  static void intel_hdcp_update_value(struct intel_connector *connector,
>  				    u64 value, bool update_property)
>  {
> +	struct drm_device *dev = connector->base.dev;
> +	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  
>  	drm_WARN_ON(connector->base.dev, !mutex_is_locked(&hdcp->mutex));
> @@ -887,6 +902,15 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
>  	if (hdcp->value == value)
>  		return;
>  
> +	drm_WARN_ON(dev, !mutex_is_locked(&intel_dig_port->hdcp_mutex));
> +
> +	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
> +		if (!drm_WARN_ON(dev, intel_dig_port->num_hdcp_streams == 0))
> +			intel_dig_port->num_hdcp_streams--;
> +	} else if (value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
> +		intel_dig_port->num_hdcp_streams++;
> +	}
> +
>  	hdcp->value = value;
>  	if (update_property) {
>  		drm_connector_get(&connector->base);
> @@ -905,6 +929,8 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
>  	int ret = 0;
>  
>  	mutex_lock(&hdcp->mutex);
> +	mutex_lock(&intel_dig_port->hdcp_mutex);
> +
>  	cpu_transcoder = hdcp->cpu_transcoder;
>  
>  	/* Check_link valid only when HDCP1.4 is enabled */
> @@ -958,6 +984,7 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
>  	}
>  
>  out:
> +	mutex_unlock(&intel_dig_port->hdcp_mutex);
>  	mutex_unlock(&hdcp->mutex);
>  	return ret;
>  }
> @@ -2057,6 +2084,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
>  		      enum transcoder cpu_transcoder, u8 content_type)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> +	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
>  	int ret = -EINVAL;
> @@ -2065,6 +2093,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
>  		return -ENOENT;
>  
>  	mutex_lock(&hdcp->mutex);
> +	mutex_lock(&intel_dig_port->hdcp_mutex);
>  	drm_WARN_ON(&dev_priv->drm,
>  		    hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
>  	hdcp->content_type = content_type;
> @@ -2099,12 +2128,14 @@ int intel_hdcp_enable(struct intel_connector *connector,
>  					true);
>  	}
>  
> +	mutex_unlock(&intel_dig_port->hdcp_mutex);
>  	mutex_unlock(&hdcp->mutex);
>  	return ret;
>  }
>  
>  int intel_hdcp_disable(struct intel_connector *connector)
>  {
> +	struct intel_digital_port *intel_dig_port = intel_attached_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	int ret = 0;
>  
> @@ -2112,6 +2143,7 @@ int intel_hdcp_disable(struct intel_connector *connector)
>  		return -ENOENT;
>  
>  	mutex_lock(&hdcp->mutex);
> +	mutex_lock(&intel_dig_port->hdcp_mutex);
>  
>  	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
>  		goto out;
> @@ -2124,6 +2156,7 @@ int intel_hdcp_disable(struct intel_connector *connector)
>  		ret = _intel_hdcp_disable(connector);
>  
>  out:
> +	mutex_unlock(&intel_dig_port->hdcp_mutex);
>  	mutex_unlock(&hdcp->mutex);
>  	cancel_delayed_work_sync(&hdcp->check_work);
>  	return ret;
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index ab7bddf0dfdc..a59acfff456e 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -3331,6 +3331,8 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
>  
>  	intel_encoder = &intel_dig_port->base;
>  
> +	mutex_init(&intel_dig_port->hdcp_mutex);
> +
>  	drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
>  			 &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,
>  			 "HDMI %c", port_name(port));
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v7 10/17] drm/i915: Support DP MST in enc_to_dig_port() function
  2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
@ 2020-07-09 10:16     ` Ramalingam C
  -1 siblings, 0 replies; 98+ messages in thread
From: Ramalingam C @ 2020-07-09 10:16 UTC (permalink / raw)
  To: Sean Paul
  Cc: dri-devel, daniel.vetter, intel-gfx, Sean Paul, juston.li, rodrigo.vivi

On 2020-06-23 at 11:59:00 -0400, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> Although DP_MST fake encoders are not subclassed from digital ports,
> they are associated with them. Support these encoders.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-9-sean@poorly.run #v1
> Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-10-sean@poorly.run #v2
> Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-10-sean@poorly.run #v3
> Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-10-sean@poorly.run #v4
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-10-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-10-sean@poorly.run #v6
> 
> Changes in v2:
> -None
> Changes in v3:
> -None
> Changes in v4:
> -None
> Changes in v5:
> -None
> Changes in v6:
> -None
> Changes in v7:
> -None
> ---
>  .../drm/i915/display/intel_display_types.h    | 21 ++++++++++++-------
>  1 file changed, 14 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 1503403a808b..811085ef3fba 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1525,6 +1525,18 @@ static inline bool intel_encoder_is_dig_port(struct intel_encoder *encoder)
>  	}
>  }
>  
> +static inline bool intel_encoder_is_mst(struct intel_encoder *encoder)
> +{
> +	return encoder->type == INTEL_OUTPUT_DP_MST;
> +}
> +
> +static inline struct intel_dp_mst_encoder *
> +enc_to_mst(struct intel_encoder *encoder)
> +{
> +	return container_of(&encoder->base, struct intel_dp_mst_encoder,
> +			    base.base);
> +}
> +
>  static inline struct intel_digital_port *
>  enc_to_dig_port(struct intel_encoder *encoder)
>  {
> @@ -1533,6 +1545,8 @@ enc_to_dig_port(struct intel_encoder *encoder)
>  	if (intel_encoder_is_dig_port(intel_encoder))
>  		return container_of(&encoder->base, struct intel_digital_port,
>  				    base.base);
> +	else if (intel_encoder_is_mst(intel_encoder))
> +		return enc_to_mst(encoder)->primary;
>  	else
>  		return NULL;
>  }
> @@ -1543,13 +1557,6 @@ intel_attached_dig_port(struct intel_connector *connector)
>  	return enc_to_dig_port(intel_attached_encoder(connector));
>  }
>  
> -static inline struct intel_dp_mst_encoder *
> -enc_to_mst(struct intel_encoder *encoder)
> -{
> -	return container_of(&encoder->base, struct intel_dp_mst_encoder,
> -			    base.base);
> -}
> -
>  static inline struct intel_dp *enc_to_intel_dp(struct intel_encoder *encoder)
>  {
>  	return &enc_to_dig_port(encoder)->dp;
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 10/17] drm/i915: Support DP MST in enc_to_dig_port() function
@ 2020-07-09 10:16     ` Ramalingam C
  0 siblings, 0 replies; 98+ messages in thread
From: Ramalingam C @ 2020-07-09 10:16 UTC (permalink / raw)
  To: Sean Paul; +Cc: dri-devel, daniel.vetter, intel-gfx, Sean Paul

On 2020-06-23 at 11:59:00 -0400, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> Although DP_MST fake encoders are not subclassed from digital ports,
> they are associated with them. Support these encoders.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-9-sean@poorly.run #v1
> Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-10-sean@poorly.run #v2
> Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-10-sean@poorly.run #v3
> Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-10-sean@poorly.run #v4
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-10-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-10-sean@poorly.run #v6
> 
> Changes in v2:
> -None
> Changes in v3:
> -None
> Changes in v4:
> -None
> Changes in v5:
> -None
> Changes in v6:
> -None
> Changes in v7:
> -None
> ---
>  .../drm/i915/display/intel_display_types.h    | 21 ++++++++++++-------
>  1 file changed, 14 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 1503403a808b..811085ef3fba 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1525,6 +1525,18 @@ static inline bool intel_encoder_is_dig_port(struct intel_encoder *encoder)
>  	}
>  }
>  
> +static inline bool intel_encoder_is_mst(struct intel_encoder *encoder)
> +{
> +	return encoder->type == INTEL_OUTPUT_DP_MST;
> +}
> +
> +static inline struct intel_dp_mst_encoder *
> +enc_to_mst(struct intel_encoder *encoder)
> +{
> +	return container_of(&encoder->base, struct intel_dp_mst_encoder,
> +			    base.base);
> +}
> +
>  static inline struct intel_digital_port *
>  enc_to_dig_port(struct intel_encoder *encoder)
>  {
> @@ -1533,6 +1545,8 @@ enc_to_dig_port(struct intel_encoder *encoder)
>  	if (intel_encoder_is_dig_port(intel_encoder))
>  		return container_of(&encoder->base, struct intel_digital_port,
>  				    base.base);
> +	else if (intel_encoder_is_mst(intel_encoder))
> +		return enc_to_mst(encoder)->primary;
>  	else
>  		return NULL;
>  }
> @@ -1543,13 +1557,6 @@ intel_attached_dig_port(struct intel_connector *connector)
>  	return enc_to_dig_port(intel_attached_encoder(connector));
>  }
>  
> -static inline struct intel_dp_mst_encoder *
> -enc_to_mst(struct intel_encoder *encoder)
> -{
> -	return container_of(&encoder->base, struct intel_dp_mst_encoder,
> -			    base.base);
> -}
> -
>  static inline struct intel_dp *enc_to_intel_dp(struct intel_encoder *encoder)
>  {
>  	return &enc_to_dig_port(encoder)->dp;
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
  2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
@ 2020-07-09 10:37     ` Ramalingam C
  -1 siblings, 0 replies; 98+ messages in thread
From: Ramalingam C @ 2020-07-09 10:37 UTC (permalink / raw)
  To: Sean Paul
  Cc: dri-devel, daniel.vetter, intel-gfx, Sean Paul, juston.li, rodrigo.vivi

On 2020-06-23 at 11:59:07 -0400, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> Now that all the groundwork has been laid, we can turn on HDCP 1.4 over
> MST. Everything except for toggling the HDCP signalling and HDCP 2.2
> support is the same as the DP case, so we'll re-use those callbacks
> 
> Cc: Juston Li <juston.li@intel.com>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-12-sean@poorly.run #v1
> Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-13-sean@poorly.run #v2
> Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-13-sean@poorly.run #v3
> Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-15-sean@poorly.run #v4
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-17-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-17-sean@poorly.run #v6
> 
> Changes in v2:
> -Toggle HDCP from encoder disable/enable
> -Don't disable HDCP on MST connector destroy, leave that for encoder
>  disable, just ensure the check_work routine isn't running any longer
> Changes in v3:
> -Place the shim in the new intel_dp_hdcp.c file (Ville)
> Changes in v4:
> -Actually use the mst shim for mst connections (Juston)
> -Use QUERY_STREAM_ENC_STATUS MST message to verify channel is encrypted
> Changes in v5:
> -Add sleep on disable signalling to match hdmi delay
> Changes in v6:
> -Disable HDCP over MST on GEN12+ since I'm unsure how it should work and I
>  don't have hardware to test it
> Changes in v7:
> -Remove hdcp2 shims for MST in favor of skipping hdcp2 init (Ramalingam)
> ---
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 66 +++++++++++++++++++-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  | 18 ++++++
>  drivers/gpu/drm/i915/display/intel_hdcp.c    |  2 +-
>  3 files changed, 84 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> index 43446a6cae8d..3f67bd27fc3c 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -7,10 +7,12 @@
>   */
>  
>  #include <drm/drm_dp_helper.h>
> +#include <drm/drm_dp_mst_helper.h>
>  #include <drm/drm_hdcp.h>
>  #include <drm/drm_print.h>
>  
>  #include "intel_display_types.h"
> +#include "intel_ddi.h"
>  #include "intel_dp.h"
>  #include "intel_hdcp.h"
>  
> @@ -618,6 +620,65 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
>  	.protocol = HDCP_PROTOCOL_DP,
>  };
>  
> +static int
> +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> +				    enum transcoder cpu_transcoder,
> +				    bool enable)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> +	int ret;
> +
> +	if (!enable)
> +		usleep_range(6, 60); /* Bspec says >= 6us */
> +
> +	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> +					       cpu_transcoder, enable);
Sean,

This function toggles the TRANS_DDI_HDCP_SIGNALLING (9th)bit of TRANS_DDI_FUNC_CTL(tran)
But in the hw specification this bit is mentioned to be ignored for non
HDMI/DVI modes of the TRANS DDI.

Any reason why we need this? Did you try with out this function?

Apart from that Patch looks good to me.

-Ram

> +	if (ret)
> +		drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> +			      enable ? "Enable" : "Disable", ret);
> +	return ret;
> +}
> +
> +static
> +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> +				  struct intel_connector *connector)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> +	struct intel_dp *intel_dp = &intel_dig_port->dp;
> +	struct drm_dp_query_stream_enc_status_ack_reply reply;
> +	int ret;
> +
> +	if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> +		return false;
> +
> +	ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> +						  connector->port, &reply);
> +	if (ret) {
> +		drm_dbg_kms(&i915->drm,
> +			    "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> +			    connector->base.base.id, connector->base.name, ret);
> +		return false;
> +	}
> +
> +	return reply.auth_completed && reply.encryption_enabled;
> +}
> +
> +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> +	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
> +	.read_bksv = intel_dp_hdcp_read_bksv,
> +	.read_bstatus = intel_dp_hdcp_read_bstatus,
> +	.repeater_present = intel_dp_hdcp_repeater_present,
> +	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
> +	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> +	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> +	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> +	.toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> +	.check_link = intel_dp_mst_hdcp_check_link,
> +	.hdcp_capable = intel_dp_hdcp_capable,
> +
> +	.protocol = HDCP_PROTOCOL_DP,
> +};
> +
>  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
>  		       struct intel_connector *intel_connector)
>  {
> @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
>  	if (!is_hdcp_supported(dev_priv, port))
>  		return 0;
>  
> -	if (!intel_dp_is_edp(intel_dp))
> +	if (intel_connector->mst_port)
> +		return intel_hdcp_init(intel_connector, port,
> +				       &intel_dp_mst_hdcp_shim);
> +	else if (!intel_dp_is_edp(intel_dp))
>  		return intel_hdcp_init(intel_connector, port,
>  				       &intel_dp_hdcp_shim);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 0675825dcc20..abaaeeb963d2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -37,6 +37,7 @@
>  #include "intel_dp.h"
>  #include "intel_dp_mst.h"
>  #include "intel_dpio_phy.h"
> +#include "intel_hdcp.h"
>  
>  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>  					    struct intel_crtc_state *crtc_state,
> @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
>  	drm_dbg_kms(&i915->drm, "active links %d\n",
>  		    intel_dp->active_mst_links);
>  
> +	intel_hdcp_disable(intel_mst->connector);
> +
>  	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
>  
>  	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
>  
>  	if (pipe_config->has_audio)
>  		intel_audio_codec_enable(encoder, pipe_config, conn_state);
> +
> +	/* Enable hdcp if it's desired */
> +	if (conn_state->content_protection ==
> +	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
> +		intel_hdcp_enable(to_intel_connector(conn_state->connector),
> +				  pipe_config->cpu_transcoder,
> +				  (u8)conn_state->hdcp_content_type);
>  }
>  
>  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
>  	intel_attach_force_audio_property(connector);
>  	intel_attach_broadcast_rgb_property(connector);
>  
> +
> +	/* TODO: Figure out how to make HDCP work on GEN12+ */
> +	if (INTEL_GEN(dev_priv) < 12) {
> +		ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> +		if (ret)
> +			DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> +	}
> +
>  	/*
>  	 * Reuse the prop from the SST connector because we're
>  	 * not allowed to create new props after device registration.
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 6bd0e4616ee1..ddc9db8de2bc 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
>  	if (!shim)
>  		return -EINVAL;
>  
> -	if (is_hdcp2_supported(dev_priv))
> +	if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
>  		intel_hdcp2_init(connector, port, shim);
>  
>  	ret =
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
@ 2020-07-09 10:37     ` Ramalingam C
  0 siblings, 0 replies; 98+ messages in thread
From: Ramalingam C @ 2020-07-09 10:37 UTC (permalink / raw)
  To: Sean Paul; +Cc: dri-devel, daniel.vetter, intel-gfx, Sean Paul

On 2020-06-23 at 11:59:07 -0400, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> Now that all the groundwork has been laid, we can turn on HDCP 1.4 over
> MST. Everything except for toggling the HDCP signalling and HDCP 2.2
> support is the same as the DP case, so we'll re-use those callbacks
> 
> Cc: Juston Li <juston.li@intel.com>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-12-sean@poorly.run #v1
> Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-13-sean@poorly.run #v2
> Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-13-sean@poorly.run #v3
> Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-15-sean@poorly.run #v4
> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-17-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-17-sean@poorly.run #v6
> 
> Changes in v2:
> -Toggle HDCP from encoder disable/enable
> -Don't disable HDCP on MST connector destroy, leave that for encoder
>  disable, just ensure the check_work routine isn't running any longer
> Changes in v3:
> -Place the shim in the new intel_dp_hdcp.c file (Ville)
> Changes in v4:
> -Actually use the mst shim for mst connections (Juston)
> -Use QUERY_STREAM_ENC_STATUS MST message to verify channel is encrypted
> Changes in v5:
> -Add sleep on disable signalling to match hdmi delay
> Changes in v6:
> -Disable HDCP over MST on GEN12+ since I'm unsure how it should work and I
>  don't have hardware to test it
> Changes in v7:
> -Remove hdcp2 shims for MST in favor of skipping hdcp2 init (Ramalingam)
> ---
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 66 +++++++++++++++++++-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  | 18 ++++++
>  drivers/gpu/drm/i915/display/intel_hdcp.c    |  2 +-
>  3 files changed, 84 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> index 43446a6cae8d..3f67bd27fc3c 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -7,10 +7,12 @@
>   */
>  
>  #include <drm/drm_dp_helper.h>
> +#include <drm/drm_dp_mst_helper.h>
>  #include <drm/drm_hdcp.h>
>  #include <drm/drm_print.h>
>  
>  #include "intel_display_types.h"
> +#include "intel_ddi.h"
>  #include "intel_dp.h"
>  #include "intel_hdcp.h"
>  
> @@ -618,6 +620,65 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
>  	.protocol = HDCP_PROTOCOL_DP,
>  };
>  
> +static int
> +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> +				    enum transcoder cpu_transcoder,
> +				    bool enable)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> +	int ret;
> +
> +	if (!enable)
> +		usleep_range(6, 60); /* Bspec says >= 6us */
> +
> +	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> +					       cpu_transcoder, enable);
Sean,

This function toggles the TRANS_DDI_HDCP_SIGNALLING (9th)bit of TRANS_DDI_FUNC_CTL(tran)
But in the hw specification this bit is mentioned to be ignored for non
HDMI/DVI modes of the TRANS DDI.

Any reason why we need this? Did you try with out this function?

Apart from that Patch looks good to me.

-Ram

> +	if (ret)
> +		drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> +			      enable ? "Enable" : "Disable", ret);
> +	return ret;
> +}
> +
> +static
> +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> +				  struct intel_connector *connector)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> +	struct intel_dp *intel_dp = &intel_dig_port->dp;
> +	struct drm_dp_query_stream_enc_status_ack_reply reply;
> +	int ret;
> +
> +	if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> +		return false;
> +
> +	ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> +						  connector->port, &reply);
> +	if (ret) {
> +		drm_dbg_kms(&i915->drm,
> +			    "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> +			    connector->base.base.id, connector->base.name, ret);
> +		return false;
> +	}
> +
> +	return reply.auth_completed && reply.encryption_enabled;
> +}
> +
> +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> +	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
> +	.read_bksv = intel_dp_hdcp_read_bksv,
> +	.read_bstatus = intel_dp_hdcp_read_bstatus,
> +	.repeater_present = intel_dp_hdcp_repeater_present,
> +	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
> +	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> +	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> +	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> +	.toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> +	.check_link = intel_dp_mst_hdcp_check_link,
> +	.hdcp_capable = intel_dp_hdcp_capable,
> +
> +	.protocol = HDCP_PROTOCOL_DP,
> +};
> +
>  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
>  		       struct intel_connector *intel_connector)
>  {
> @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
>  	if (!is_hdcp_supported(dev_priv, port))
>  		return 0;
>  
> -	if (!intel_dp_is_edp(intel_dp))
> +	if (intel_connector->mst_port)
> +		return intel_hdcp_init(intel_connector, port,
> +				       &intel_dp_mst_hdcp_shim);
> +	else if (!intel_dp_is_edp(intel_dp))
>  		return intel_hdcp_init(intel_connector, port,
>  				       &intel_dp_hdcp_shim);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 0675825dcc20..abaaeeb963d2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -37,6 +37,7 @@
>  #include "intel_dp.h"
>  #include "intel_dp_mst.h"
>  #include "intel_dpio_phy.h"
> +#include "intel_hdcp.h"
>  
>  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>  					    struct intel_crtc_state *crtc_state,
> @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
>  	drm_dbg_kms(&i915->drm, "active links %d\n",
>  		    intel_dp->active_mst_links);
>  
> +	intel_hdcp_disable(intel_mst->connector);
> +
>  	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
>  
>  	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
>  
>  	if (pipe_config->has_audio)
>  		intel_audio_codec_enable(encoder, pipe_config, conn_state);
> +
> +	/* Enable hdcp if it's desired */
> +	if (conn_state->content_protection ==
> +	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
> +		intel_hdcp_enable(to_intel_connector(conn_state->connector),
> +				  pipe_config->cpu_transcoder,
> +				  (u8)conn_state->hdcp_content_type);
>  }
>  
>  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
>  	intel_attach_force_audio_property(connector);
>  	intel_attach_broadcast_rgb_property(connector);
>  
> +
> +	/* TODO: Figure out how to make HDCP work on GEN12+ */
> +	if (INTEL_GEN(dev_priv) < 12) {
> +		ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> +		if (ret)
> +			DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> +	}
> +
>  	/*
>  	 * Reuse the prop from the SST connector because we're
>  	 * not allowed to create new props after device registration.
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 6bd0e4616ee1..ddc9db8de2bc 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
>  	if (!shim)
>  		return -EINVAL;
>  
> -	if (is_hdcp2_supported(dev_priv))
> +	if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
>  		intel_hdcp2_init(connector, port, shim);
>  
>  	ret =
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH v7 11/17] drm/i915: Use ddi_update_pipe in intel_dp_mst
  2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
@ 2020-07-09 10:49     ` C, Ramalingam
  -1 siblings, 0 replies; 98+ messages in thread
From: C, Ramalingam @ 2020-07-09 10:49 UTC (permalink / raw)
  To: Sean Paul, dri-devel, intel-gfx
  Cc: daniel.vetter, Sean Paul, Li, Juston, Vivi, Rodrigo

> -----Original Message-----
> From: Sean Paul <sean@poorly.run>
> Sent: Tuesday, June 23, 2020 9:29 PM
> To: dri-devel@lists.freedesktop.org; intel-gfx@lists.freedesktop.org
> Cc: Li, Juston <juston.li@intel.com>; C, Ramalingam
> <ramalingam.c@intel.com>; ville.syrjala@linux.intel.com;
> jani.nikula@linux.intel.com; joonas.lahtinen@linux.intel.com; Vivi, Rodrigo
> <rodrigo.vivi@intel.com>; daniel.vetter@ffwll.ch; Sean Paul
> <seanpaul@chromium.org>
> Subject: [PATCH v7 11/17] drm/i915: Use ddi_update_pipe in intel_dp_mst
> 
> From: Sean Paul <seanpaul@chromium.org>
> 
> In order to act upon content_protection property changes, we'll need to
> implement the .update_pipe() hook. We can re-use intel_ddi_update_pipe for
> this
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-
> 10-sean@poorly.run #v1
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-11-
> sean@poorly.run #v2
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-11-
> sean@poorly.run #v3
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-11-
> sean@poorly.run #v4
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-11-
> sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-
> 11-sean@poorly.run #v6
> 
> Changes in v2:
> -None
> Changes in v3:
> -None
> Changes in v4:
> -None
> Changes in v5:
> -None
> Changes in v6:
> -None
> Changes in v7:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c    | 11 ++++++-----
>  drivers/gpu/drm/i915/display/intel_dp.h     |  6 ++++++
>  drivers/gpu/drm/i915/display/intel_dp_mst.c |  1 +
>  3 files changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 536299f902b9..29f1f552e8d8 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -3907,13 +3907,14 @@ static void intel_ddi_update_pipe_dp(struct
> intel_atomic_state *state,
>  	intel_panel_update_backlight(state, encoder, crtc_state, conn_state);  }
> 
> -static void intel_ddi_update_pipe(struct intel_atomic_state *state,
> -				  struct intel_encoder *encoder,
> -				  const struct intel_crtc_state *crtc_state,
> -				  const struct drm_connector_state
> *conn_state)
> +void intel_ddi_update_pipe(struct intel_atomic_state *state,
> +			   struct intel_encoder *encoder,
> +			   const struct intel_crtc_state *crtc_state,
> +			   const struct drm_connector_state *conn_state)
>  {
> 
> -	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
> +	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
> +	    !intel_encoder_is_mst(encoder))
>  		intel_ddi_update_pipe_dp(state, encoder, crtc_state,
>  					 conn_state);
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h
> b/drivers/gpu/drm/i915/display/intel_dp.h
> index 0a8950f744f6..6352c7e97e3b 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -17,6 +17,7 @@ struct drm_encoder;
>  struct drm_i915_private;
>  struct drm_modeset_acquire_ctx;
>  struct drm_dp_vsc_sdp;
> +struct intel_atomic_state;
>  struct intel_connector;
>  struct intel_crtc_state;
>  struct intel_digital_port;
> @@ -128,4 +129,9 @@ static inline unsigned int intel_dp_unused_lane_mask(int
> lane_count)
> 
>  u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
> 
> +void intel_ddi_update_pipe(struct intel_atomic_state *state,
> +			   struct intel_encoder *encoder,
> +			   const struct intel_crtc_state *crtc_state,
> +			   const struct drm_connector_state *conn_state);
> +
>  #endif /* __INTEL_DP_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 9308b5920780..0675825dcc20 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -836,6 +836,7 @@ intel_dp_create_fake_mst_encoder(struct
> intel_digital_port *intel_dig_port, enum
>  	intel_encoder->compute_config_late =
> intel_dp_mst_compute_config_late;
>  	intel_encoder->disable = intel_mst_disable_dp;
>  	intel_encoder->post_disable = intel_mst_post_disable_dp;
> +	intel_encoder->update_pipe = intel_ddi_update_pipe;
>  	intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp;
>  	intel_encoder->pre_enable = intel_mst_pre_enable_dp;
>  	intel_encoder->enable = intel_mst_enable_dp;
> --
> Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 11/17] drm/i915: Use ddi_update_pipe in intel_dp_mst
@ 2020-07-09 10:49     ` C, Ramalingam
  0 siblings, 0 replies; 98+ messages in thread
From: C, Ramalingam @ 2020-07-09 10:49 UTC (permalink / raw)
  To: Sean Paul, dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

> -----Original Message-----
> From: Sean Paul <sean@poorly.run>
> Sent: Tuesday, June 23, 2020 9:29 PM
> To: dri-devel@lists.freedesktop.org; intel-gfx@lists.freedesktop.org
> Cc: Li, Juston <juston.li@intel.com>; C, Ramalingam
> <ramalingam.c@intel.com>; ville.syrjala@linux.intel.com;
> jani.nikula@linux.intel.com; joonas.lahtinen@linux.intel.com; Vivi, Rodrigo
> <rodrigo.vivi@intel.com>; daniel.vetter@ffwll.ch; Sean Paul
> <seanpaul@chromium.org>
> Subject: [PATCH v7 11/17] drm/i915: Use ddi_update_pipe in intel_dp_mst
> 
> From: Sean Paul <seanpaul@chromium.org>
> 
> In order to act upon content_protection property changes, we'll need to
> implement the .update_pipe() hook. We can re-use intel_ddi_update_pipe for
> this
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-
> 10-sean@poorly.run #v1
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-11-
> sean@poorly.run #v2
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-11-
> sean@poorly.run #v3
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-11-
> sean@poorly.run #v4
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-11-
> sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-
> 11-sean@poorly.run #v6
> 
> Changes in v2:
> -None
> Changes in v3:
> -None
> Changes in v4:
> -None
> Changes in v5:
> -None
> Changes in v6:
> -None
> Changes in v7:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c    | 11 ++++++-----
>  drivers/gpu/drm/i915/display/intel_dp.h     |  6 ++++++
>  drivers/gpu/drm/i915/display/intel_dp_mst.c |  1 +
>  3 files changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 536299f902b9..29f1f552e8d8 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -3907,13 +3907,14 @@ static void intel_ddi_update_pipe_dp(struct
> intel_atomic_state *state,
>  	intel_panel_update_backlight(state, encoder, crtc_state, conn_state);  }
> 
> -static void intel_ddi_update_pipe(struct intel_atomic_state *state,
> -				  struct intel_encoder *encoder,
> -				  const struct intel_crtc_state *crtc_state,
> -				  const struct drm_connector_state
> *conn_state)
> +void intel_ddi_update_pipe(struct intel_atomic_state *state,
> +			   struct intel_encoder *encoder,
> +			   const struct intel_crtc_state *crtc_state,
> +			   const struct drm_connector_state *conn_state)
>  {
> 
> -	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
> +	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
> +	    !intel_encoder_is_mst(encoder))
>  		intel_ddi_update_pipe_dp(state, encoder, crtc_state,
>  					 conn_state);
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h
> b/drivers/gpu/drm/i915/display/intel_dp.h
> index 0a8950f744f6..6352c7e97e3b 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -17,6 +17,7 @@ struct drm_encoder;
>  struct drm_i915_private;
>  struct drm_modeset_acquire_ctx;
>  struct drm_dp_vsc_sdp;
> +struct intel_atomic_state;
>  struct intel_connector;
>  struct intel_crtc_state;
>  struct intel_digital_port;
> @@ -128,4 +129,9 @@ static inline unsigned int intel_dp_unused_lane_mask(int
> lane_count)
> 
>  u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
> 
> +void intel_ddi_update_pipe(struct intel_atomic_state *state,
> +			   struct intel_encoder *encoder,
> +			   const struct intel_crtc_state *crtc_state,
> +			   const struct drm_connector_state *conn_state);
> +
>  #endif /* __INTEL_DP_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 9308b5920780..0675825dcc20 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -836,6 +836,7 @@ intel_dp_create_fake_mst_encoder(struct
> intel_digital_port *intel_dig_port, enum
>  	intel_encoder->compute_config_late =
> intel_dp_mst_compute_config_late;
>  	intel_encoder->disable = intel_mst_disable_dp;
>  	intel_encoder->post_disable = intel_mst_post_disable_dp;
> +	intel_encoder->update_pipe = intel_ddi_update_pipe;
>  	intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp;
>  	intel_encoder->pre_enable = intel_mst_pre_enable_dp;
>  	intel_encoder->enable = intel_mst_enable_dp;
> --
> Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH v7 12/17] drm/i915: Factor out HDCP shim functions from dp for use by dp_mst
  2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
@ 2020-07-09 10:51     ` C, Ramalingam
  -1 siblings, 0 replies; 98+ messages in thread
From: C, Ramalingam @ 2020-07-09 10:51 UTC (permalink / raw)
  To: Sean Paul, dri-devel, intel-gfx
  Cc: daniel.vetter, Sean Paul, Li, Juston, Vivi, Rodrigo

> -----Original Message-----
> From: Sean Paul <sean@poorly.run>
> Sent: Tuesday, June 23, 2020 9:29 PM
> To: dri-devel@lists.freedesktop.org; intel-gfx@lists.freedesktop.org
> Cc: Li, Juston <juston.li@intel.com>; C, Ramalingam
> <ramalingam.c@intel.com>; ville.syrjala@linux.intel.com;
> jani.nikula@linux.intel.com; joonas.lahtinen@linux.intel.com; Vivi, Rodrigo
> <rodrigo.vivi@intel.com>; daniel.vetter@ffwll.ch; Sean Paul
> <seanpaul@chromium.org>
> Subject: [PATCH v7 12/17] drm/i915: Factor out HDCP shim functions from dp
> for use by dp_mst
> 
> From: Sean Paul <seanpaul@chromium.org>
> 
> These functions are all the same for dp and dp_mst, so move them into a
> dedicated file for both sst and mst to use.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-
> 11-sean@poorly.run #v1
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-12-
> sean@poorly.run #v2
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-12-
> sean@poorly.run #v3
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-12-
> sean@poorly.run #v4
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-12-
> sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-
> 12-sean@poorly.run #v6
> 
> Changes in v2:
> -None
> Changes in v3:
> -Created intel_dp_hdcp.c for the shared functions to live (Ville) Changes in v4:
> -Rebased on new drm logging change
> Changes in v5:
> -None
> Changes in v6:
> -None
> Changes in v7:
> -Rebased patch
> ---
>  drivers/gpu/drm/i915/Makefile                |   1 +
>  drivers/gpu/drm/i915/display/intel_dp.c      | 606 +-----------------
>  drivers/gpu/drm/i915/display/intel_dp.h      |   3 +
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 636 +++++++++++++++++++
>  4 files changed, 641 insertions(+), 605 deletions(-)  create mode 100644
> drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 41a27fd5dbc7..cba4ddb95ab1 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -233,6 +233,7 @@ i915-y += \
>  	display/intel_ddi.o \
>  	display/intel_dp.o \
>  	display/intel_dp_aux_backlight.o \
> +	display/intel_dp_hdcp.o \
>  	display/intel_dp_link_training.o \
>  	display/intel_dp_mst.o \
>  	display/intel_dsi.o \
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index d98e45a09c28..78ce5e41d559 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -38,7 +38,6 @@
>  #include <drm/drm_crtc.h>
>  #include <drm/drm_dp_helper.h>
>  #include <drm/drm_edid.h>
> -#include <drm/drm_hdcp.h>
>  #include <drm/drm_probe_helper.h>
> 
>  #include "i915_debugfs.h"
> @@ -6396,609 +6395,6 @@ void intel_dp_encoder_suspend(struct
> intel_encoder *intel_encoder)
>  		edp_panel_vdd_off_sync(intel_dp);
>  }
> 
> -static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
> -{
> -	long ret;
> -
> -#define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
> -	ret = wait_event_interruptible_timeout(hdcp->cp_irq_queue, C,
> -					       msecs_to_jiffies(timeout));
> -
> -	if (!ret)
> -		DRM_DEBUG_KMS("Timedout at waiting for CP_IRQ\n");
> -}
> -
> -static
> -int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
> -				u8 *an)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	u8 aksv[DRM_HDCP_KSV_LEN] = {};
> -	ssize_t dpcd_ret;
> -
> -	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_AN,
> -				     an, DRM_HDCP_AN_LEN);
> -	if (dpcd_ret != DRM_HDCP_AN_LEN) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Failed to write An over DP/AUX (%zd)\n",
> -			    dpcd_ret);
> -		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
> -	}
> -
> -	/*
> -	 * Since Aksv is Oh-So-Secret, we can't access it in software. So we
> -	 * send an empty buffer of the correct length through the DP helpers. On
> -	 * the other side, in the transfer hook, we'll generate a flag based on
> -	 * the destination address which will tickle the hardware to output the
> -	 * Aksv on our behalf after the header is sent.
> -	 */
> -	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_AKSV,
> -				     aksv, DRM_HDCP_KSV_LEN);
> -	if (dpcd_ret != DRM_HDCP_KSV_LEN) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Failed to write Aksv over DP/AUX (%zd)\n",
> -			    dpcd_ret);
> -		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
> -	}
> -	return 0;
> -}
> -
> -static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
> -				   u8 *bksv)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BKSV, bksv,
> -			       DRM_HDCP_KSV_LEN);
> -	if (ret != DRM_HDCP_KSV_LEN) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read Bksv from DP/AUX failed (%zd)\n", ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -	return 0;
> -}
> -
> -static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
> -				      u8 *bstatus)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -
> -	/*
> -	 * For some reason the HDMI and DP HDCP specs call this register
> -	 * definition by different names. In the HDMI spec, it's called BSTATUS,
> -	 * but in DP it's called BINFO.
> -	 */
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BINFO,
> -			       bstatus, DRM_HDCP_BSTATUS_LEN);
> -	if (ret != DRM_HDCP_BSTATUS_LEN) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
> -			     u8 *bcaps)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BCAPS,
> -			       bcaps, 1);
> -	if (ret != 1) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read bcaps from DP/AUX failed (%zd)\n", ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
> -				   bool *repeater_present)
> -{
> -	ssize_t ret;
> -	u8 bcaps;
> -
> -	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
> -	if (ret)
> -		return ret;
> -
> -	*repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT;
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
> -				u8 *ri_prime)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_RI_PRIME,
> -			       ri_prime, DRM_HDCP_RI_LEN);
> -	if (ret != DRM_HDCP_RI_LEN) {
> -		drm_dbg_kms(&i915->drm, "Read Ri' from DP/AUX failed
> (%zd)\n",
> -			    ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
> -				 bool *ksv_ready)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -	u8 bstatus;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BSTATUS,
> -			       &bstatus, 1);
> -	if (ret != 1) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -	*ksv_ready = bstatus & DP_BSTATUS_READY;
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
> -				int num_downstream, u8 *ksv_fifo)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -	int i;
> -
> -	/* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */
> -	for (i = 0; i < num_downstream; i += 3) {
> -		size_t len = min(num_downstream - i, 3) *
> DRM_HDCP_KSV_LEN;
> -		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> -				       DP_AUX_HDCP_KSV_FIFO,
> -				       ksv_fifo + i * DRM_HDCP_KSV_LEN,
> -				       len);
> -		if (ret != len) {
> -			drm_dbg_kms(&i915->drm,
> -				    "Read ksv[%d] from DP/AUX failed (%zd)\n",
> -				    i, ret);
> -			return ret >= 0 ? -EIO : ret;
> -		}
> -	}
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
> -				    int i, u32 *part)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -
> -	if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
> -		return -EINVAL;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> -			       DP_AUX_HDCP_V_PRIME(i), part,
> -			       DRM_HDCP_V_PRIME_PART_LEN);
> -	if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> -				    enum transcoder cpu_transcoder,
> -				    bool enable)
> -{
> -	/* Not used for single stream DisplayPort setups */
> -	return 0;
> -}
> -
> -static
> -bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port) -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -	u8 bstatus;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BSTATUS,
> -			       &bstatus, 1);
> -	if (ret != 1) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> -		return false;
> -	}
> -
> -	return !(bstatus & (DP_BSTATUS_LINK_FAILURE |
> DP_BSTATUS_REAUTH_REQ));
> -}
> -
> -static
> -int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
> -			  bool *hdcp_capable)
> -{
> -	ssize_t ret;
> -	u8 bcaps;
> -
> -	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
> -	if (ret)
> -		return ret;
> -
> -	*hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE;
> -	return 0;
> -}
> -
> -struct hdcp2_dp_errata_stream_type {
> -	u8	msg_id;
> -	u8	stream_type;
> -} __packed;
> -
> -struct hdcp2_dp_msg_data {
> -	u8 msg_id;
> -	u32 offset;
> -	bool msg_detectable;
> -	u32 timeout;
> -	u32 timeout2; /* Added for non_paired situation */
> -};
> -
> -static const struct hdcp2_dp_msg_data hdcp2_dp_msg_data[] = {
> -	{ HDCP_2_2_AKE_INIT, DP_HDCP_2_2_AKE_INIT_OFFSET, false, 0, 0 },
> -	{ HDCP_2_2_AKE_SEND_CERT,
> DP_HDCP_2_2_AKE_SEND_CERT_OFFSET,
> -	  false, HDCP_2_2_CERT_TIMEOUT_MS, 0 },
> -	{ HDCP_2_2_AKE_NO_STORED_KM,
> DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET,
> -	  false, 0, 0 },
> -	{ HDCP_2_2_AKE_STORED_KM,
> DP_HDCP_2_2_AKE_STORED_KM_OFFSET,
> -	  false, 0, 0 },
> -	{ HDCP_2_2_AKE_SEND_HPRIME,
> DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET,
> -	  true, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
> -	  HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS },
> -	{ HDCP_2_2_AKE_SEND_PAIRING_INFO,
> -	  DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET, true,
> -	  HDCP_2_2_PAIRING_TIMEOUT_MS, 0 },
> -	{ HDCP_2_2_LC_INIT, DP_HDCP_2_2_LC_INIT_OFFSET, false, 0, 0 },
> -	{ HDCP_2_2_LC_SEND_LPRIME,
> DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET,
> -	  false, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, 0 },
> -	{ HDCP_2_2_SKE_SEND_EKS, DP_HDCP_2_2_SKE_SEND_EKS_OFFSET,
> false,
> -	  0, 0 },
> -	{ HDCP_2_2_REP_SEND_RECVID_LIST,
> -	  DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET, true,
> -	  HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0 },
> -	{ HDCP_2_2_REP_SEND_ACK, DP_HDCP_2_2_REP_SEND_ACK_OFFSET,
> false,
> -	  0, 0 },
> -	{ HDCP_2_2_REP_STREAM_MANAGE,
> -	  DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET, false,
> -	  0, 0 },
> -	{ HDCP_2_2_REP_STREAM_READY,
> DP_HDCP_2_2_REP_STREAM_READY_OFFSET,
> -	  false, HDCP_2_2_STREAM_READY_TIMEOUT_MS, 0 },
> -/* local define to shovel this through the write_2_2 interface */
> -#define HDCP_2_2_ERRATA_DP_STREAM_TYPE	50
> -	{ HDCP_2_2_ERRATA_DP_STREAM_TYPE,
> -	  DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, false,
> -	  0, 0 },
> -};
> -
> -static int
> -intel_dp_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
> -			      u8 *rx_status)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> -			       DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
> -			       HDCP_2_2_DP_RXSTATUS_LEN);
> -	if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -
> -	return 0;
> -}
> -
> -static
> -int hdcp2_detect_msg_availability(struct intel_digital_port *intel_dig_port,
> -				  u8 msg_id, bool *msg_ready)
> -{
> -	u8 rx_status;
> -	int ret;
> -
> -	*msg_ready = false;
> -	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
> -	if (ret < 0)
> -		return ret;
> -
> -	switch (msg_id) {
> -	case HDCP_2_2_AKE_SEND_HPRIME:
> -		if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rx_status))
> -			*msg_ready = true;
> -		break;
> -	case HDCP_2_2_AKE_SEND_PAIRING_INFO:
> -		if (HDCP_2_2_DP_RXSTATUS_PAIRING(rx_status))
> -			*msg_ready = true;
> -		break;
> -	case HDCP_2_2_REP_SEND_RECVID_LIST:
> -		if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
> -			*msg_ready = true;
> -		break;
> -	default:
> -		DRM_ERROR("Unidentified msg_id: %d\n", msg_id);
> -		return -EINVAL;
> -	}
> -
> -	return 0;
> -}
> -
> -static ssize_t
> -intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
> -			    const struct hdcp2_dp_msg_data *hdcp2_msg_data)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	struct intel_dp *dp = &intel_dig_port->dp;
> -	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
> -	u8 msg_id = hdcp2_msg_data->msg_id;
> -	int ret, timeout;
> -	bool msg_ready = false;
> -
> -	if (msg_id == HDCP_2_2_AKE_SEND_HPRIME && !hdcp->is_paired)
> -		timeout = hdcp2_msg_data->timeout2;
> -	else
> -		timeout = hdcp2_msg_data->timeout;
> -
> -	/*
> -	 * There is no way to detect the CERT, LPRIME and STREAM_READY
> -	 * availability. So Wait for timeout and read the msg.
> -	 */
> -	if (!hdcp2_msg_data->msg_detectable) {
> -		mdelay(timeout);
> -		ret = 0;
> -	} else {
> -		/*
> -		 * As we want to check the msg availability at timeout, Ignoring
> -		 * the timeout at wait for CP_IRQ.
> -		 */
> -		intel_dp_hdcp_wait_for_cp_irq(hdcp, timeout);
> -		ret = hdcp2_detect_msg_availability(intel_dig_port,
> -						    msg_id, &msg_ready);
> -		if (!msg_ready)
> -			ret = -ETIMEDOUT;
> -	}
> -
> -	if (ret)
> -		drm_dbg_kms(&i915->drm,
> -			    "msg_id %d, ret %d, timeout(mSec): %d\n",
> -			    hdcp2_msg_data->msg_id, ret, timeout);
> -
> -	return ret;
> -}
> -
> -static const struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id) -
> {
> -	int i;
> -
> -	for (i = 0; i < ARRAY_SIZE(hdcp2_dp_msg_data); i++)
> -		if (hdcp2_dp_msg_data[i].msg_id == msg_id)
> -			return &hdcp2_dp_msg_data[i];
> -
> -	return NULL;
> -}
> -
> -static
> -int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
> -			     void *buf, size_t size)
> -{
> -	struct intel_dp *dp = &intel_dig_port->dp;
> -	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
> -	unsigned int offset;
> -	u8 *byte = buf;
> -	ssize_t ret, bytes_to_write, len;
> -	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
> -
> -	hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
> -	if (!hdcp2_msg_data)
> -		return -EINVAL;
> -
> -	offset = hdcp2_msg_data->offset;
> -
> -	/* No msg_id in DP HDCP2.2 msgs */
> -	bytes_to_write = size - 1;
> -	byte++;
> -
> -	hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count);
> -
> -	while (bytes_to_write) {
> -		len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
> -				DP_AUX_MAX_PAYLOAD_BYTES :
> bytes_to_write;
> -
> -		ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> -					offset, (void *)byte, len);
> -		if (ret < 0)
> -			return ret;
> -
> -		bytes_to_write -= ret;
> -		byte += ret;
> -		offset += ret;
> -	}
> -
> -	return size;
> -}
> -
> -static
> -ssize_t get_receiver_id_list_size(struct intel_digital_port *intel_dig_port) -{
> -	u8 rx_info[HDCP_2_2_RXINFO_LEN];
> -	u32 dev_cnt;
> -	ssize_t ret;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> -			       DP_HDCP_2_2_REG_RXINFO_OFFSET,
> -			       (void *)rx_info, HDCP_2_2_RXINFO_LEN);
> -	if (ret != HDCP_2_2_RXINFO_LEN)
> -		return ret >= 0 ? -EIO : ret;
> -
> -	dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
> -		   HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
> -
> -	if (dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
> -		dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
> -
> -	ret = sizeof(struct hdcp2_rep_send_receiverid_list) -
> -		HDCP_2_2_RECEIVER_IDS_MAX_LEN +
> -		(dev_cnt * HDCP_2_2_RECEIVER_ID_LEN);
> -
> -	return ret;
> -}
> -
> -static
> -int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
> -			    u8 msg_id, void *buf, size_t size)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	unsigned int offset;
> -	u8 *byte = buf;
> -	ssize_t ret, bytes_to_recv, len;
> -	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
> -
> -	hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
> -	if (!hdcp2_msg_data)
> -		return -EINVAL;
> -	offset = hdcp2_msg_data->offset;
> -
> -	ret = intel_dp_hdcp2_wait_for_msg(intel_dig_port, hdcp2_msg_data);
> -	if (ret < 0)
> -		return ret;
> -
> -	if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
> -		ret = get_receiver_id_list_size(intel_dig_port);
> -		if (ret < 0)
> -			return ret;
> -
> -		size = ret;
> -	}
> -	bytes_to_recv = size - 1;
> -
> -	/* DP adaptation msgs has no msg_id */
> -	byte++;
> -
> -	while (bytes_to_recv) {
> -		len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ?
> -		      DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
> -
> -		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, offset,
> -				       (void *)byte, len);
> -		if (ret < 0) {
> -			drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
> -				    msg_id, ret);
> -			return ret;
> -		}
> -
> -		bytes_to_recv -= ret;
> -		byte += ret;
> -		offset += ret;
> -	}
> -	byte = buf;
> -	*byte = msg_id;
> -
> -	return size;
> -}
> -
> -static
> -int intel_dp_hdcp2_config_stream_type(struct intel_digital_port
> *intel_dig_port,
> -				      bool is_repeater, u8 content_type)
> -{
> -	int ret;
> -	struct hdcp2_dp_errata_stream_type stream_type_msg;
> -
> -	if (is_repeater)
> -		return 0;
> -
> -	/*
> -	 * Errata for DP: As Stream type is used for encryption, Receiver
> -	 * should be communicated with stream type for the decryption of the
> -	 * content.
> -	 * Repeater will be communicated with stream type as a part of it's
> -	 * auth later in time.
> -	 */
> -	stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
> -	stream_type_msg.stream_type = content_type;
> -
> -	ret =  intel_dp_hdcp2_write_msg(intel_dig_port, &stream_type_msg,
> -					sizeof(stream_type_msg));
> -
> -	return ret < 0 ? ret : 0;
> -
> -}
> -
> -static
> -int intel_dp_hdcp2_check_link(struct intel_digital_port *intel_dig_port) -{
> -	u8 rx_status;
> -	int ret;
> -
> -	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
> -	if (ret)
> -		return ret;
> -
> -	if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
> -		ret = HDCP_REAUTH_REQUEST;
> -	else if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
> -		ret = HDCP_LINK_INTEGRITY_FAILURE;
> -	else if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
> -		ret = HDCP_TOPOLOGY_CHANGE;
> -
> -	return ret;
> -}
> -
> -static
> -int intel_dp_hdcp2_capable(struct intel_digital_port *intel_dig_port,
> -			   bool *capable)
> -{
> -	u8 rx_caps[3];
> -	int ret;
> -
> -	*capable = false;
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> -			       DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
> -			       rx_caps, HDCP_2_2_RXCAPS_LEN);
> -	if (ret != HDCP_2_2_RXCAPS_LEN)
> -		return ret >= 0 ? -EIO : ret;
> -
> -	if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
> -	    HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2]))
> -		*capable = true;
> -
> -	return 0;
> -}
> -
> -static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
> -	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
> -	.read_bksv = intel_dp_hdcp_read_bksv,
> -	.read_bstatus = intel_dp_hdcp_read_bstatus,
> -	.repeater_present = intel_dp_hdcp_repeater_present,
> -	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
> -	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> -	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> -	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> -	.toggle_signalling = intel_dp_hdcp_toggle_signalling,
> -	.check_link = intel_dp_hdcp_check_link,
> -	.hdcp_capable = intel_dp_hdcp_capable,
> -	.write_2_2_msg = intel_dp_hdcp2_write_msg,
> -	.read_2_2_msg = intel_dp_hdcp2_read_msg,
> -	.config_stream_type = intel_dp_hdcp2_config_stream_type,
> -	.check_2_2_link = intel_dp_hdcp2_check_link,
> -	.hdcp_2_2_capable = intel_dp_hdcp2_capable,
> -	.protocol = HDCP_PROTOCOL_DP,
> -};
> -
>  static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -8232,7
> +7628,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>  	intel_dp_add_properties(intel_dp, connector);
> 
>  	if (is_hdcp_supported(dev_priv, port) && !intel_dp_is_edp(intel_dp)) {
> -		int ret = intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
> +		int ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
>  		if (ret)
>  			drm_dbg_kms(&dev_priv->drm,
>  				    "HDCP init failed, skipping.\n"); diff --git
> a/drivers/gpu/drm/i915/display/intel_dp.h
> b/drivers/gpu/drm/i915/display/intel_dp.h
> index 6352c7e97e3b..794f25573254 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -134,4 +134,7 @@ void intel_ddi_update_pipe(struct intel_atomic_state
> *state,
>  			   const struct intel_crtc_state *crtc_state,
>  			   const struct drm_connector_state *conn_state);
> 
> +int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> +		       struct intel_connector *intel_connector);
> +
>  #endif /* __INTEL_DP_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> new file mode 100644
> index 000000000000..0e06a1066d61
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -0,0 +1,636 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright (C) 2020 Google, Inc.
> + *
> + * Authors:
> + * Sean Paul <seanpaul@chromium.org>
> + */
> +
> +#include <drm/drm_dp_helper.h>
> +#include <drm/drm_hdcp.h>
> +#include <drm/drm_print.h>
> +
> +#include "intel_display_types.h"
> +#include "intel_dp.h"
> +#include "intel_hdcp.h"
> +
> +static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int
> +timeout) {
> +	long ret;
> +
> +#define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
> +	ret = wait_event_interruptible_timeout(hdcp->cp_irq_queue, C,
> +					       msecs_to_jiffies(timeout));
> +
> +	if (!ret)
> +		DRM_DEBUG_KMS("Timedout at waiting for CP_IRQ\n"); }
> +
> +static
> +int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
> +				u8 *an)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	u8 aksv[DRM_HDCP_KSV_LEN] = {};
> +	ssize_t dpcd_ret;
> +
> +	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_AN,
> +				     an, DRM_HDCP_AN_LEN);
> +	if (dpcd_ret != DRM_HDCP_AN_LEN) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Failed to write An over DP/AUX (%zd)\n",
> +			    dpcd_ret);
> +		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
> +	}
> +
> +	/*
> +	 * Since Aksv is Oh-So-Secret, we can't access it in software. So we
> +	 * send an empty buffer of the correct length through the DP helpers. On
> +	 * the other side, in the transfer hook, we'll generate a flag based on
> +	 * the destination address which will tickle the hardware to output the
> +	 * Aksv on our behalf after the header is sent.
> +	 */
> +	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_AKSV,
> +				     aksv, DRM_HDCP_KSV_LEN);
> +	if (dpcd_ret != DRM_HDCP_KSV_LEN) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Failed to write Aksv over DP/AUX (%zd)\n",
> +			    dpcd_ret);
> +		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
> +	}
> +	return 0;
> +}
> +
> +static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
> +				   u8 *bksv)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BKSV, bksv,
> +			       DRM_HDCP_KSV_LEN);
> +	if (ret != DRM_HDCP_KSV_LEN) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read Bksv from DP/AUX failed (%zd)\n", ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +	return 0;
> +}
> +
> +static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
> +				      u8 *bstatus)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +
> +	/*
> +	 * For some reason the HDMI and DP HDCP specs call this register
> +	 * definition by different names. In the HDMI spec, it's called BSTATUS,
> +	 * but in DP it's called BINFO.
> +	 */
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BINFO,
> +			       bstatus, DRM_HDCP_BSTATUS_LEN);
> +	if (ret != DRM_HDCP_BSTATUS_LEN) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
> +			     u8 *bcaps)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BCAPS,
> +			       bcaps, 1);
> +	if (ret != 1) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read bcaps from DP/AUX failed (%zd)\n", ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
> +				   bool *repeater_present)
> +{
> +	ssize_t ret;
> +	u8 bcaps;
> +
> +	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
> +	if (ret)
> +		return ret;
> +
> +	*repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT;
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
> +				u8 *ri_prime)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_RI_PRIME,
> +			       ri_prime, DRM_HDCP_RI_LEN);
> +	if (ret != DRM_HDCP_RI_LEN) {
> +		drm_dbg_kms(&i915->drm, "Read Ri' from DP/AUX failed
> (%zd)\n",
> +			    ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
> +				 bool *ksv_ready)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +	u8 bstatus;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BSTATUS,
> +			       &bstatus, 1);
> +	if (ret != 1) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +	*ksv_ready = bstatus & DP_BSTATUS_READY;
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
> +				int num_downstream, u8 *ksv_fifo)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +	int i;
> +
> +	/* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */
> +	for (i = 0; i < num_downstream; i += 3) {
> +		size_t len = min(num_downstream - i, 3) *
> DRM_HDCP_KSV_LEN;
> +		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> +				       DP_AUX_HDCP_KSV_FIFO,
> +				       ksv_fifo + i * DRM_HDCP_KSV_LEN,
> +				       len);
> +		if (ret != len) {
> +			drm_dbg_kms(&i915->drm,
> +				    "Read ksv[%d] from DP/AUX failed (%zd)\n",
> +				    i, ret);
> +			return ret >= 0 ? -EIO : ret;
> +		}
> +	}
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
> +				    int i, u32 *part)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +
> +	if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
> +		return -EINVAL;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> +			       DP_AUX_HDCP_V_PRIME(i), part,
> +			       DRM_HDCP_V_PRIME_PART_LEN);
> +	if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> +				    enum transcoder cpu_transcoder,
> +				    bool enable)
> +{
> +	/* Not used for single stream DisplayPort setups */
> +	return 0;
> +}
> +
> +static
> +bool intel_dp_hdcp_check_link(struct intel_digital_port
> +*intel_dig_port) {
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +	u8 bstatus;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BSTATUS,
> +			       &bstatus, 1);
> +	if (ret != 1) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> +		return false;
> +	}
> +
> +	return !(bstatus & (DP_BSTATUS_LINK_FAILURE |
> DP_BSTATUS_REAUTH_REQ));
> +}
> +
> +static
> +int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
> +			  bool *hdcp_capable)
> +{
> +	ssize_t ret;
> +	u8 bcaps;
> +
> +	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
> +	if (ret)
> +		return ret;
> +
> +	*hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE;
> +	return 0;
> +}
> +
> +struct hdcp2_dp_errata_stream_type {
> +	u8	msg_id;
> +	u8	stream_type;
> +} __packed;
> +
> +struct hdcp2_dp_msg_data {
> +	u8 msg_id;
> +	u32 offset;
> +	bool msg_detectable;
> +	u32 timeout;
> +	u32 timeout2; /* Added for non_paired situation */ };
> +
> +static const struct hdcp2_dp_msg_data hdcp2_dp_msg_data[] = {
> +	{ HDCP_2_2_AKE_INIT, DP_HDCP_2_2_AKE_INIT_OFFSET, false, 0, 0 },
> +	{ HDCP_2_2_AKE_SEND_CERT,
> DP_HDCP_2_2_AKE_SEND_CERT_OFFSET,
> +	  false, HDCP_2_2_CERT_TIMEOUT_MS, 0 },
> +	{ HDCP_2_2_AKE_NO_STORED_KM,
> DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET,
> +	  false, 0, 0 },
> +	{ HDCP_2_2_AKE_STORED_KM,
> DP_HDCP_2_2_AKE_STORED_KM_OFFSET,
> +	  false, 0, 0 },
> +	{ HDCP_2_2_AKE_SEND_HPRIME,
> DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET,
> +	  true, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
> +	  HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS },
> +	{ HDCP_2_2_AKE_SEND_PAIRING_INFO,
> +	  DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET, true,
> +	  HDCP_2_2_PAIRING_TIMEOUT_MS, 0 },
> +	{ HDCP_2_2_LC_INIT, DP_HDCP_2_2_LC_INIT_OFFSET, false, 0, 0 },
> +	{ HDCP_2_2_LC_SEND_LPRIME,
> DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET,
> +	  false, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, 0 },
> +	{ HDCP_2_2_SKE_SEND_EKS, DP_HDCP_2_2_SKE_SEND_EKS_OFFSET,
> false,
> +	  0, 0 },
> +	{ HDCP_2_2_REP_SEND_RECVID_LIST,
> +	  DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET, true,
> +	  HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0 },
> +	{ HDCP_2_2_REP_SEND_ACK, DP_HDCP_2_2_REP_SEND_ACK_OFFSET,
> false,
> +	  0, 0 },
> +	{ HDCP_2_2_REP_STREAM_MANAGE,
> +	  DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET, false,
> +	  0, 0 },
> +	{ HDCP_2_2_REP_STREAM_READY,
> DP_HDCP_2_2_REP_STREAM_READY_OFFSET,
> +	  false, HDCP_2_2_STREAM_READY_TIMEOUT_MS, 0 },
> +/* local define to shovel this through the write_2_2 interface */
> +#define HDCP_2_2_ERRATA_DP_STREAM_TYPE	50
> +	{ HDCP_2_2_ERRATA_DP_STREAM_TYPE,
> +	  DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, false,
> +	  0, 0 },
> +};
> +
> +static int
> +intel_dp_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
> +			      u8 *rx_status)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> +			       DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
> +			       HDCP_2_2_DP_RXSTATUS_LEN);
> +	if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static
> +int hdcp2_detect_msg_availability(struct intel_digital_port *intel_dig_port,
> +				  u8 msg_id, bool *msg_ready)
> +{
> +	u8 rx_status;
> +	int ret;
> +
> +	*msg_ready = false;
> +	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
> +	if (ret < 0)
> +		return ret;
> +
> +	switch (msg_id) {
> +	case HDCP_2_2_AKE_SEND_HPRIME:
> +		if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rx_status))
> +			*msg_ready = true;
> +		break;
> +	case HDCP_2_2_AKE_SEND_PAIRING_INFO:
> +		if (HDCP_2_2_DP_RXSTATUS_PAIRING(rx_status))
> +			*msg_ready = true;
> +		break;
> +	case HDCP_2_2_REP_SEND_RECVID_LIST:
> +		if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
> +			*msg_ready = true;
> +		break;
> +	default:
> +		DRM_ERROR("Unidentified msg_id: %d\n", msg_id);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static ssize_t
> +intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
> +			    const struct hdcp2_dp_msg_data *hdcp2_msg_data)
> {
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	struct intel_dp *dp = &intel_dig_port->dp;
> +	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
> +	u8 msg_id = hdcp2_msg_data->msg_id;
> +	int ret, timeout;
> +	bool msg_ready = false;
> +
> +	if (msg_id == HDCP_2_2_AKE_SEND_HPRIME && !hdcp->is_paired)
> +		timeout = hdcp2_msg_data->timeout2;
> +	else
> +		timeout = hdcp2_msg_data->timeout;
> +
> +	/*
> +	 * There is no way to detect the CERT, LPRIME and STREAM_READY
> +	 * availability. So Wait for timeout and read the msg.
> +	 */
> +	if (!hdcp2_msg_data->msg_detectable) {
> +		mdelay(timeout);
> +		ret = 0;
> +	} else {
> +		/*
> +		 * As we want to check the msg availability at timeout, Ignoring
> +		 * the timeout at wait for CP_IRQ.
> +		 */
> +		intel_dp_hdcp_wait_for_cp_irq(hdcp, timeout);
> +		ret = hdcp2_detect_msg_availability(intel_dig_port,
> +						    msg_id, &msg_ready);
> +		if (!msg_ready)
> +			ret = -ETIMEDOUT;
> +	}
> +
> +	if (ret)
> +		drm_dbg_kms(&i915->drm,
> +			    "msg_id %d, ret %d, timeout(mSec): %d\n",
> +			    hdcp2_msg_data->msg_id, ret, timeout);
> +
> +	return ret;
> +}
> +
> +static const struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hdcp2_dp_msg_data); i++)
> +		if (hdcp2_dp_msg_data[i].msg_id == msg_id)
> +			return &hdcp2_dp_msg_data[i];
> +
> +	return NULL;
> +}
> +
> +static
> +int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
> +			     void *buf, size_t size)
> +{
> +	struct intel_dp *dp = &intel_dig_port->dp;
> +	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
> +	unsigned int offset;
> +	u8 *byte = buf;
> +	ssize_t ret, bytes_to_write, len;
> +	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
> +
> +	hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
> +	if (!hdcp2_msg_data)
> +		return -EINVAL;
> +
> +	offset = hdcp2_msg_data->offset;
> +
> +	/* No msg_id in DP HDCP2.2 msgs */
> +	bytes_to_write = size - 1;
> +	byte++;
> +
> +	hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count);
> +
> +	while (bytes_to_write) {
> +		len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
> +				DP_AUX_MAX_PAYLOAD_BYTES :
> bytes_to_write;
> +
> +		ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> +					offset, (void *)byte, len);
> +		if (ret < 0)
> +			return ret;
> +
> +		bytes_to_write -= ret;
> +		byte += ret;
> +		offset += ret;
> +	}
> +
> +	return size;
> +}
> +
> +static
> +ssize_t get_receiver_id_list_size(struct intel_digital_port
> +*intel_dig_port) {
> +	u8 rx_info[HDCP_2_2_RXINFO_LEN];
> +	u32 dev_cnt;
> +	ssize_t ret;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> +			       DP_HDCP_2_2_REG_RXINFO_OFFSET,
> +			       (void *)rx_info, HDCP_2_2_RXINFO_LEN);
> +	if (ret != HDCP_2_2_RXINFO_LEN)
> +		return ret >= 0 ? -EIO : ret;
> +
> +	dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
> +		   HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
> +
> +	if (dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
> +		dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
> +
> +	ret = sizeof(struct hdcp2_rep_send_receiverid_list) -
> +		HDCP_2_2_RECEIVER_IDS_MAX_LEN +
> +		(dev_cnt * HDCP_2_2_RECEIVER_ID_LEN);
> +
> +	return ret;
> +}
> +
> +static
> +int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
> +			    u8 msg_id, void *buf, size_t size) {
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	unsigned int offset;
> +	u8 *byte = buf;
> +	ssize_t ret, bytes_to_recv, len;
> +	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
> +
> +	hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
> +	if (!hdcp2_msg_data)
> +		return -EINVAL;
> +	offset = hdcp2_msg_data->offset;
> +
> +	ret = intel_dp_hdcp2_wait_for_msg(intel_dig_port, hdcp2_msg_data);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
> +		ret = get_receiver_id_list_size(intel_dig_port);
> +		if (ret < 0)
> +			return ret;
> +
> +		size = ret;
> +	}
> +	bytes_to_recv = size - 1;
> +
> +	/* DP adaptation msgs has no msg_id */
> +	byte++;
> +
> +	while (bytes_to_recv) {
> +		len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ?
> +		      DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
> +
> +		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, offset,
> +				       (void *)byte, len);
> +		if (ret < 0) {
> +			drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
> +				    msg_id, ret);
> +			return ret;
> +		}
> +
> +		bytes_to_recv -= ret;
> +		byte += ret;
> +		offset += ret;
> +	}
> +	byte = buf;
> +	*byte = msg_id;
> +
> +	return size;
> +}
> +
> +static
> +int intel_dp_hdcp2_config_stream_type(struct intel_digital_port
> *intel_dig_port,
> +				      bool is_repeater, u8 content_type) {
> +	int ret;
> +	struct hdcp2_dp_errata_stream_type stream_type_msg;
> +
> +	if (is_repeater)
> +		return 0;
> +
> +	/*
> +	 * Errata for DP: As Stream type is used for encryption, Receiver
> +	 * should be communicated with stream type for the decryption of the
> +	 * content.
> +	 * Repeater will be communicated with stream type as a part of it's
> +	 * auth later in time.
> +	 */
> +	stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
> +	stream_type_msg.stream_type = content_type;
> +
> +	ret =  intel_dp_hdcp2_write_msg(intel_dig_port, &stream_type_msg,
> +					sizeof(stream_type_msg));
> +
> +	return ret < 0 ? ret : 0;
> +
> +}
> +
> +static
> +int intel_dp_hdcp2_check_link(struct intel_digital_port
> +*intel_dig_port) {
> +	u8 rx_status;
> +	int ret;
> +
> +	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
> +	if (ret)
> +		return ret;
> +
> +	if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
> +		ret = HDCP_REAUTH_REQUEST;
> +	else if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
> +		ret = HDCP_LINK_INTEGRITY_FAILURE;
> +	else if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
> +		ret = HDCP_TOPOLOGY_CHANGE;
> +
> +	return ret;
> +}
> +
> +static
> +int intel_dp_hdcp2_capable(struct intel_digital_port *intel_dig_port,
> +			   bool *capable)
> +{
> +	u8 rx_caps[3];
> +	int ret;
> +
> +	*capable = false;
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> +			       DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
> +			       rx_caps, HDCP_2_2_RXCAPS_LEN);
> +	if (ret != HDCP_2_2_RXCAPS_LEN)
> +		return ret >= 0 ? -EIO : ret;
> +
> +	if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
> +	    HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2]))
> +		*capable = true;
> +
> +	return 0;
> +}
> +
> +static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
> +	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
> +	.read_bksv = intel_dp_hdcp_read_bksv,
> +	.read_bstatus = intel_dp_hdcp_read_bstatus,
> +	.repeater_present = intel_dp_hdcp_repeater_present,
> +	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
> +	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> +	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> +	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> +	.toggle_signalling = intel_dp_hdcp_toggle_signalling,
> +	.check_link = intel_dp_hdcp_check_link,
> +	.hdcp_capable = intel_dp_hdcp_capable,
> +	.write_2_2_msg = intel_dp_hdcp2_write_msg,
> +	.read_2_2_msg = intel_dp_hdcp2_read_msg,
> +	.config_stream_type = intel_dp_hdcp2_config_stream_type,
> +	.check_2_2_link = intel_dp_hdcp2_check_link,
> +	.hdcp_2_2_capable = intel_dp_hdcp2_capable,
> +	.protocol = HDCP_PROTOCOL_DP,
> +};
> +
> +int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> +		       struct intel_connector *intel_connector) {
> +	struct drm_device *dev = intel_connector->base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct intel_encoder *intel_encoder = &intel_dig_port->base;
> +	enum port port = intel_encoder->port;
> +	struct intel_dp *intel_dp = &intel_dig_port->dp;
> +
> +	if (!is_hdcp_supported(dev_priv, port))
> +		return 0;
> +
> +	if (!intel_dp_is_edp(intel_dp))
> +		return intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
> +
> +	return 0;
> +}
> --
> Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 12/17] drm/i915: Factor out HDCP shim functions from dp for use by dp_mst
@ 2020-07-09 10:51     ` C, Ramalingam
  0 siblings, 0 replies; 98+ messages in thread
From: C, Ramalingam @ 2020-07-09 10:51 UTC (permalink / raw)
  To: Sean Paul, dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

> -----Original Message-----
> From: Sean Paul <sean@poorly.run>
> Sent: Tuesday, June 23, 2020 9:29 PM
> To: dri-devel@lists.freedesktop.org; intel-gfx@lists.freedesktop.org
> Cc: Li, Juston <juston.li@intel.com>; C, Ramalingam
> <ramalingam.c@intel.com>; ville.syrjala@linux.intel.com;
> jani.nikula@linux.intel.com; joonas.lahtinen@linux.intel.com; Vivi, Rodrigo
> <rodrigo.vivi@intel.com>; daniel.vetter@ffwll.ch; Sean Paul
> <seanpaul@chromium.org>
> Subject: [PATCH v7 12/17] drm/i915: Factor out HDCP shim functions from dp
> for use by dp_mst
> 
> From: Sean Paul <seanpaul@chromium.org>
> 
> These functions are all the same for dp and dp_mst, so move them into a
> dedicated file for both sst and mst to use.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-
> 11-sean@poorly.run #v1
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-12-
> sean@poorly.run #v2
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-12-
> sean@poorly.run #v3
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-12-
> sean@poorly.run #v4
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-12-
> sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-
> 12-sean@poorly.run #v6
> 
> Changes in v2:
> -None
> Changes in v3:
> -Created intel_dp_hdcp.c for the shared functions to live (Ville) Changes in v4:
> -Rebased on new drm logging change
> Changes in v5:
> -None
> Changes in v6:
> -None
> Changes in v7:
> -Rebased patch
> ---
>  drivers/gpu/drm/i915/Makefile                |   1 +
>  drivers/gpu/drm/i915/display/intel_dp.c      | 606 +-----------------
>  drivers/gpu/drm/i915/display/intel_dp.h      |   3 +
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 636 +++++++++++++++++++
>  4 files changed, 641 insertions(+), 605 deletions(-)  create mode 100644
> drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 41a27fd5dbc7..cba4ddb95ab1 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -233,6 +233,7 @@ i915-y += \
>  	display/intel_ddi.o \
>  	display/intel_dp.o \
>  	display/intel_dp_aux_backlight.o \
> +	display/intel_dp_hdcp.o \
>  	display/intel_dp_link_training.o \
>  	display/intel_dp_mst.o \
>  	display/intel_dsi.o \
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index d98e45a09c28..78ce5e41d559 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -38,7 +38,6 @@
>  #include <drm/drm_crtc.h>
>  #include <drm/drm_dp_helper.h>
>  #include <drm/drm_edid.h>
> -#include <drm/drm_hdcp.h>
>  #include <drm/drm_probe_helper.h>
> 
>  #include "i915_debugfs.h"
> @@ -6396,609 +6395,6 @@ void intel_dp_encoder_suspend(struct
> intel_encoder *intel_encoder)
>  		edp_panel_vdd_off_sync(intel_dp);
>  }
> 
> -static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
> -{
> -	long ret;
> -
> -#define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
> -	ret = wait_event_interruptible_timeout(hdcp->cp_irq_queue, C,
> -					       msecs_to_jiffies(timeout));
> -
> -	if (!ret)
> -		DRM_DEBUG_KMS("Timedout at waiting for CP_IRQ\n");
> -}
> -
> -static
> -int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
> -				u8 *an)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	u8 aksv[DRM_HDCP_KSV_LEN] = {};
> -	ssize_t dpcd_ret;
> -
> -	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_AN,
> -				     an, DRM_HDCP_AN_LEN);
> -	if (dpcd_ret != DRM_HDCP_AN_LEN) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Failed to write An over DP/AUX (%zd)\n",
> -			    dpcd_ret);
> -		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
> -	}
> -
> -	/*
> -	 * Since Aksv is Oh-So-Secret, we can't access it in software. So we
> -	 * send an empty buffer of the correct length through the DP helpers. On
> -	 * the other side, in the transfer hook, we'll generate a flag based on
> -	 * the destination address which will tickle the hardware to output the
> -	 * Aksv on our behalf after the header is sent.
> -	 */
> -	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_AKSV,
> -				     aksv, DRM_HDCP_KSV_LEN);
> -	if (dpcd_ret != DRM_HDCP_KSV_LEN) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Failed to write Aksv over DP/AUX (%zd)\n",
> -			    dpcd_ret);
> -		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
> -	}
> -	return 0;
> -}
> -
> -static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
> -				   u8 *bksv)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BKSV, bksv,
> -			       DRM_HDCP_KSV_LEN);
> -	if (ret != DRM_HDCP_KSV_LEN) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read Bksv from DP/AUX failed (%zd)\n", ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -	return 0;
> -}
> -
> -static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
> -				      u8 *bstatus)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -
> -	/*
> -	 * For some reason the HDMI and DP HDCP specs call this register
> -	 * definition by different names. In the HDMI spec, it's called BSTATUS,
> -	 * but in DP it's called BINFO.
> -	 */
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BINFO,
> -			       bstatus, DRM_HDCP_BSTATUS_LEN);
> -	if (ret != DRM_HDCP_BSTATUS_LEN) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
> -			     u8 *bcaps)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BCAPS,
> -			       bcaps, 1);
> -	if (ret != 1) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read bcaps from DP/AUX failed (%zd)\n", ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
> -				   bool *repeater_present)
> -{
> -	ssize_t ret;
> -	u8 bcaps;
> -
> -	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
> -	if (ret)
> -		return ret;
> -
> -	*repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT;
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
> -				u8 *ri_prime)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_RI_PRIME,
> -			       ri_prime, DRM_HDCP_RI_LEN);
> -	if (ret != DRM_HDCP_RI_LEN) {
> -		drm_dbg_kms(&i915->drm, "Read Ri' from DP/AUX failed
> (%zd)\n",
> -			    ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
> -				 bool *ksv_ready)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -	u8 bstatus;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BSTATUS,
> -			       &bstatus, 1);
> -	if (ret != 1) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -	*ksv_ready = bstatus & DP_BSTATUS_READY;
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
> -				int num_downstream, u8 *ksv_fifo)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -	int i;
> -
> -	/* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */
> -	for (i = 0; i < num_downstream; i += 3) {
> -		size_t len = min(num_downstream - i, 3) *
> DRM_HDCP_KSV_LEN;
> -		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> -				       DP_AUX_HDCP_KSV_FIFO,
> -				       ksv_fifo + i * DRM_HDCP_KSV_LEN,
> -				       len);
> -		if (ret != len) {
> -			drm_dbg_kms(&i915->drm,
> -				    "Read ksv[%d] from DP/AUX failed (%zd)\n",
> -				    i, ret);
> -			return ret >= 0 ? -EIO : ret;
> -		}
> -	}
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
> -				    int i, u32 *part)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -
> -	if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
> -		return -EINVAL;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> -			       DP_AUX_HDCP_V_PRIME(i), part,
> -			       DRM_HDCP_V_PRIME_PART_LEN);
> -	if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -	return 0;
> -}
> -
> -static
> -int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> -				    enum transcoder cpu_transcoder,
> -				    bool enable)
> -{
> -	/* Not used for single stream DisplayPort setups */
> -	return 0;
> -}
> -
> -static
> -bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port) -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -	u8 bstatus;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BSTATUS,
> -			       &bstatus, 1);
> -	if (ret != 1) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> -		return false;
> -	}
> -
> -	return !(bstatus & (DP_BSTATUS_LINK_FAILURE |
> DP_BSTATUS_REAUTH_REQ));
> -}
> -
> -static
> -int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
> -			  bool *hdcp_capable)
> -{
> -	ssize_t ret;
> -	u8 bcaps;
> -
> -	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
> -	if (ret)
> -		return ret;
> -
> -	*hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE;
> -	return 0;
> -}
> -
> -struct hdcp2_dp_errata_stream_type {
> -	u8	msg_id;
> -	u8	stream_type;
> -} __packed;
> -
> -struct hdcp2_dp_msg_data {
> -	u8 msg_id;
> -	u32 offset;
> -	bool msg_detectable;
> -	u32 timeout;
> -	u32 timeout2; /* Added for non_paired situation */
> -};
> -
> -static const struct hdcp2_dp_msg_data hdcp2_dp_msg_data[] = {
> -	{ HDCP_2_2_AKE_INIT, DP_HDCP_2_2_AKE_INIT_OFFSET, false, 0, 0 },
> -	{ HDCP_2_2_AKE_SEND_CERT,
> DP_HDCP_2_2_AKE_SEND_CERT_OFFSET,
> -	  false, HDCP_2_2_CERT_TIMEOUT_MS, 0 },
> -	{ HDCP_2_2_AKE_NO_STORED_KM,
> DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET,
> -	  false, 0, 0 },
> -	{ HDCP_2_2_AKE_STORED_KM,
> DP_HDCP_2_2_AKE_STORED_KM_OFFSET,
> -	  false, 0, 0 },
> -	{ HDCP_2_2_AKE_SEND_HPRIME,
> DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET,
> -	  true, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
> -	  HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS },
> -	{ HDCP_2_2_AKE_SEND_PAIRING_INFO,
> -	  DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET, true,
> -	  HDCP_2_2_PAIRING_TIMEOUT_MS, 0 },
> -	{ HDCP_2_2_LC_INIT, DP_HDCP_2_2_LC_INIT_OFFSET, false, 0, 0 },
> -	{ HDCP_2_2_LC_SEND_LPRIME,
> DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET,
> -	  false, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, 0 },
> -	{ HDCP_2_2_SKE_SEND_EKS, DP_HDCP_2_2_SKE_SEND_EKS_OFFSET,
> false,
> -	  0, 0 },
> -	{ HDCP_2_2_REP_SEND_RECVID_LIST,
> -	  DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET, true,
> -	  HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0 },
> -	{ HDCP_2_2_REP_SEND_ACK, DP_HDCP_2_2_REP_SEND_ACK_OFFSET,
> false,
> -	  0, 0 },
> -	{ HDCP_2_2_REP_STREAM_MANAGE,
> -	  DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET, false,
> -	  0, 0 },
> -	{ HDCP_2_2_REP_STREAM_READY,
> DP_HDCP_2_2_REP_STREAM_READY_OFFSET,
> -	  false, HDCP_2_2_STREAM_READY_TIMEOUT_MS, 0 },
> -/* local define to shovel this through the write_2_2 interface */
> -#define HDCP_2_2_ERRATA_DP_STREAM_TYPE	50
> -	{ HDCP_2_2_ERRATA_DP_STREAM_TYPE,
> -	  DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, false,
> -	  0, 0 },
> -};
> -
> -static int
> -intel_dp_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
> -			      u8 *rx_status)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	ssize_t ret;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> -			       DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
> -			       HDCP_2_2_DP_RXSTATUS_LEN);
> -	if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
> -		drm_dbg_kms(&i915->drm,
> -			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> -		return ret >= 0 ? -EIO : ret;
> -	}
> -
> -	return 0;
> -}
> -
> -static
> -int hdcp2_detect_msg_availability(struct intel_digital_port *intel_dig_port,
> -				  u8 msg_id, bool *msg_ready)
> -{
> -	u8 rx_status;
> -	int ret;
> -
> -	*msg_ready = false;
> -	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
> -	if (ret < 0)
> -		return ret;
> -
> -	switch (msg_id) {
> -	case HDCP_2_2_AKE_SEND_HPRIME:
> -		if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rx_status))
> -			*msg_ready = true;
> -		break;
> -	case HDCP_2_2_AKE_SEND_PAIRING_INFO:
> -		if (HDCP_2_2_DP_RXSTATUS_PAIRING(rx_status))
> -			*msg_ready = true;
> -		break;
> -	case HDCP_2_2_REP_SEND_RECVID_LIST:
> -		if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
> -			*msg_ready = true;
> -		break;
> -	default:
> -		DRM_ERROR("Unidentified msg_id: %d\n", msg_id);
> -		return -EINVAL;
> -	}
> -
> -	return 0;
> -}
> -
> -static ssize_t
> -intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
> -			    const struct hdcp2_dp_msg_data *hdcp2_msg_data)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	struct intel_dp *dp = &intel_dig_port->dp;
> -	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
> -	u8 msg_id = hdcp2_msg_data->msg_id;
> -	int ret, timeout;
> -	bool msg_ready = false;
> -
> -	if (msg_id == HDCP_2_2_AKE_SEND_HPRIME && !hdcp->is_paired)
> -		timeout = hdcp2_msg_data->timeout2;
> -	else
> -		timeout = hdcp2_msg_data->timeout;
> -
> -	/*
> -	 * There is no way to detect the CERT, LPRIME and STREAM_READY
> -	 * availability. So Wait for timeout and read the msg.
> -	 */
> -	if (!hdcp2_msg_data->msg_detectable) {
> -		mdelay(timeout);
> -		ret = 0;
> -	} else {
> -		/*
> -		 * As we want to check the msg availability at timeout, Ignoring
> -		 * the timeout at wait for CP_IRQ.
> -		 */
> -		intel_dp_hdcp_wait_for_cp_irq(hdcp, timeout);
> -		ret = hdcp2_detect_msg_availability(intel_dig_port,
> -						    msg_id, &msg_ready);
> -		if (!msg_ready)
> -			ret = -ETIMEDOUT;
> -	}
> -
> -	if (ret)
> -		drm_dbg_kms(&i915->drm,
> -			    "msg_id %d, ret %d, timeout(mSec): %d\n",
> -			    hdcp2_msg_data->msg_id, ret, timeout);
> -
> -	return ret;
> -}
> -
> -static const struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id) -
> {
> -	int i;
> -
> -	for (i = 0; i < ARRAY_SIZE(hdcp2_dp_msg_data); i++)
> -		if (hdcp2_dp_msg_data[i].msg_id == msg_id)
> -			return &hdcp2_dp_msg_data[i];
> -
> -	return NULL;
> -}
> -
> -static
> -int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
> -			     void *buf, size_t size)
> -{
> -	struct intel_dp *dp = &intel_dig_port->dp;
> -	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
> -	unsigned int offset;
> -	u8 *byte = buf;
> -	ssize_t ret, bytes_to_write, len;
> -	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
> -
> -	hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
> -	if (!hdcp2_msg_data)
> -		return -EINVAL;
> -
> -	offset = hdcp2_msg_data->offset;
> -
> -	/* No msg_id in DP HDCP2.2 msgs */
> -	bytes_to_write = size - 1;
> -	byte++;
> -
> -	hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count);
> -
> -	while (bytes_to_write) {
> -		len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
> -				DP_AUX_MAX_PAYLOAD_BYTES :
> bytes_to_write;
> -
> -		ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> -					offset, (void *)byte, len);
> -		if (ret < 0)
> -			return ret;
> -
> -		bytes_to_write -= ret;
> -		byte += ret;
> -		offset += ret;
> -	}
> -
> -	return size;
> -}
> -
> -static
> -ssize_t get_receiver_id_list_size(struct intel_digital_port *intel_dig_port) -{
> -	u8 rx_info[HDCP_2_2_RXINFO_LEN];
> -	u32 dev_cnt;
> -	ssize_t ret;
> -
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> -			       DP_HDCP_2_2_REG_RXINFO_OFFSET,
> -			       (void *)rx_info, HDCP_2_2_RXINFO_LEN);
> -	if (ret != HDCP_2_2_RXINFO_LEN)
> -		return ret >= 0 ? -EIO : ret;
> -
> -	dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
> -		   HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
> -
> -	if (dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
> -		dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
> -
> -	ret = sizeof(struct hdcp2_rep_send_receiverid_list) -
> -		HDCP_2_2_RECEIVER_IDS_MAX_LEN +
> -		(dev_cnt * HDCP_2_2_RECEIVER_ID_LEN);
> -
> -	return ret;
> -}
> -
> -static
> -int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
> -			    u8 msg_id, void *buf, size_t size)
> -{
> -	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	unsigned int offset;
> -	u8 *byte = buf;
> -	ssize_t ret, bytes_to_recv, len;
> -	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
> -
> -	hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
> -	if (!hdcp2_msg_data)
> -		return -EINVAL;
> -	offset = hdcp2_msg_data->offset;
> -
> -	ret = intel_dp_hdcp2_wait_for_msg(intel_dig_port, hdcp2_msg_data);
> -	if (ret < 0)
> -		return ret;
> -
> -	if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
> -		ret = get_receiver_id_list_size(intel_dig_port);
> -		if (ret < 0)
> -			return ret;
> -
> -		size = ret;
> -	}
> -	bytes_to_recv = size - 1;
> -
> -	/* DP adaptation msgs has no msg_id */
> -	byte++;
> -
> -	while (bytes_to_recv) {
> -		len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ?
> -		      DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
> -
> -		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, offset,
> -				       (void *)byte, len);
> -		if (ret < 0) {
> -			drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
> -				    msg_id, ret);
> -			return ret;
> -		}
> -
> -		bytes_to_recv -= ret;
> -		byte += ret;
> -		offset += ret;
> -	}
> -	byte = buf;
> -	*byte = msg_id;
> -
> -	return size;
> -}
> -
> -static
> -int intel_dp_hdcp2_config_stream_type(struct intel_digital_port
> *intel_dig_port,
> -				      bool is_repeater, u8 content_type)
> -{
> -	int ret;
> -	struct hdcp2_dp_errata_stream_type stream_type_msg;
> -
> -	if (is_repeater)
> -		return 0;
> -
> -	/*
> -	 * Errata for DP: As Stream type is used for encryption, Receiver
> -	 * should be communicated with stream type for the decryption of the
> -	 * content.
> -	 * Repeater will be communicated with stream type as a part of it's
> -	 * auth later in time.
> -	 */
> -	stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
> -	stream_type_msg.stream_type = content_type;
> -
> -	ret =  intel_dp_hdcp2_write_msg(intel_dig_port, &stream_type_msg,
> -					sizeof(stream_type_msg));
> -
> -	return ret < 0 ? ret : 0;
> -
> -}
> -
> -static
> -int intel_dp_hdcp2_check_link(struct intel_digital_port *intel_dig_port) -{
> -	u8 rx_status;
> -	int ret;
> -
> -	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
> -	if (ret)
> -		return ret;
> -
> -	if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
> -		ret = HDCP_REAUTH_REQUEST;
> -	else if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
> -		ret = HDCP_LINK_INTEGRITY_FAILURE;
> -	else if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
> -		ret = HDCP_TOPOLOGY_CHANGE;
> -
> -	return ret;
> -}
> -
> -static
> -int intel_dp_hdcp2_capable(struct intel_digital_port *intel_dig_port,
> -			   bool *capable)
> -{
> -	u8 rx_caps[3];
> -	int ret;
> -
> -	*capable = false;
> -	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> -			       DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
> -			       rx_caps, HDCP_2_2_RXCAPS_LEN);
> -	if (ret != HDCP_2_2_RXCAPS_LEN)
> -		return ret >= 0 ? -EIO : ret;
> -
> -	if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
> -	    HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2]))
> -		*capable = true;
> -
> -	return 0;
> -}
> -
> -static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
> -	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
> -	.read_bksv = intel_dp_hdcp_read_bksv,
> -	.read_bstatus = intel_dp_hdcp_read_bstatus,
> -	.repeater_present = intel_dp_hdcp_repeater_present,
> -	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
> -	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> -	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> -	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> -	.toggle_signalling = intel_dp_hdcp_toggle_signalling,
> -	.check_link = intel_dp_hdcp_check_link,
> -	.hdcp_capable = intel_dp_hdcp_capable,
> -	.write_2_2_msg = intel_dp_hdcp2_write_msg,
> -	.read_2_2_msg = intel_dp_hdcp2_read_msg,
> -	.config_stream_type = intel_dp_hdcp2_config_stream_type,
> -	.check_2_2_link = intel_dp_hdcp2_check_link,
> -	.hdcp_2_2_capable = intel_dp_hdcp2_capable,
> -	.protocol = HDCP_PROTOCOL_DP,
> -};
> -
>  static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -8232,7
> +7628,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>  	intel_dp_add_properties(intel_dp, connector);
> 
>  	if (is_hdcp_supported(dev_priv, port) && !intel_dp_is_edp(intel_dp)) {
> -		int ret = intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
> +		int ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
>  		if (ret)
>  			drm_dbg_kms(&dev_priv->drm,
>  				    "HDCP init failed, skipping.\n"); diff --git
> a/drivers/gpu/drm/i915/display/intel_dp.h
> b/drivers/gpu/drm/i915/display/intel_dp.h
> index 6352c7e97e3b..794f25573254 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -134,4 +134,7 @@ void intel_ddi_update_pipe(struct intel_atomic_state
> *state,
>  			   const struct intel_crtc_state *crtc_state,
>  			   const struct drm_connector_state *conn_state);
> 
> +int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> +		       struct intel_connector *intel_connector);
> +
>  #endif /* __INTEL_DP_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> new file mode 100644
> index 000000000000..0e06a1066d61
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -0,0 +1,636 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright (C) 2020 Google, Inc.
> + *
> + * Authors:
> + * Sean Paul <seanpaul@chromium.org>
> + */
> +
> +#include <drm/drm_dp_helper.h>
> +#include <drm/drm_hdcp.h>
> +#include <drm/drm_print.h>
> +
> +#include "intel_display_types.h"
> +#include "intel_dp.h"
> +#include "intel_hdcp.h"
> +
> +static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int
> +timeout) {
> +	long ret;
> +
> +#define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
> +	ret = wait_event_interruptible_timeout(hdcp->cp_irq_queue, C,
> +					       msecs_to_jiffies(timeout));
> +
> +	if (!ret)
> +		DRM_DEBUG_KMS("Timedout at waiting for CP_IRQ\n"); }
> +
> +static
> +int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
> +				u8 *an)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	u8 aksv[DRM_HDCP_KSV_LEN] = {};
> +	ssize_t dpcd_ret;
> +
> +	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_AN,
> +				     an, DRM_HDCP_AN_LEN);
> +	if (dpcd_ret != DRM_HDCP_AN_LEN) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Failed to write An over DP/AUX (%zd)\n",
> +			    dpcd_ret);
> +		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
> +	}
> +
> +	/*
> +	 * Since Aksv is Oh-So-Secret, we can't access it in software. So we
> +	 * send an empty buffer of the correct length through the DP helpers. On
> +	 * the other side, in the transfer hook, we'll generate a flag based on
> +	 * the destination address which will tickle the hardware to output the
> +	 * Aksv on our behalf after the header is sent.
> +	 */
> +	dpcd_ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_AKSV,
> +				     aksv, DRM_HDCP_KSV_LEN);
> +	if (dpcd_ret != DRM_HDCP_KSV_LEN) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Failed to write Aksv over DP/AUX (%zd)\n",
> +			    dpcd_ret);
> +		return dpcd_ret >= 0 ? -EIO : dpcd_ret;
> +	}
> +	return 0;
> +}
> +
> +static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
> +				   u8 *bksv)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BKSV, bksv,
> +			       DRM_HDCP_KSV_LEN);
> +	if (ret != DRM_HDCP_KSV_LEN) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read Bksv from DP/AUX failed (%zd)\n", ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +	return 0;
> +}
> +
> +static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
> +				      u8 *bstatus)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +
> +	/*
> +	 * For some reason the HDMI and DP HDCP specs call this register
> +	 * definition by different names. In the HDMI spec, it's called BSTATUS,
> +	 * but in DP it's called BINFO.
> +	 */
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BINFO,
> +			       bstatus, DRM_HDCP_BSTATUS_LEN);
> +	if (ret != DRM_HDCP_BSTATUS_LEN) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
> +			     u8 *bcaps)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BCAPS,
> +			       bcaps, 1);
> +	if (ret != 1) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read bcaps from DP/AUX failed (%zd)\n", ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
> +				   bool *repeater_present)
> +{
> +	ssize_t ret;
> +	u8 bcaps;
> +
> +	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
> +	if (ret)
> +		return ret;
> +
> +	*repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT;
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
> +				u8 *ri_prime)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_RI_PRIME,
> +			       ri_prime, DRM_HDCP_RI_LEN);
> +	if (ret != DRM_HDCP_RI_LEN) {
> +		drm_dbg_kms(&i915->drm, "Read Ri' from DP/AUX failed
> (%zd)\n",
> +			    ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
> +				 bool *ksv_ready)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +	u8 bstatus;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BSTATUS,
> +			       &bstatus, 1);
> +	if (ret != 1) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +	*ksv_ready = bstatus & DP_BSTATUS_READY;
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
> +				int num_downstream, u8 *ksv_fifo)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +	int i;
> +
> +	/* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */
> +	for (i = 0; i < num_downstream; i += 3) {
> +		size_t len = min(num_downstream - i, 3) *
> DRM_HDCP_KSV_LEN;
> +		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> +				       DP_AUX_HDCP_KSV_FIFO,
> +				       ksv_fifo + i * DRM_HDCP_KSV_LEN,
> +				       len);
> +		if (ret != len) {
> +			drm_dbg_kms(&i915->drm,
> +				    "Read ksv[%d] from DP/AUX failed (%zd)\n",
> +				    i, ret);
> +			return ret >= 0 ? -EIO : ret;
> +		}
> +	}
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
> +				    int i, u32 *part)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +
> +	if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
> +		return -EINVAL;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> +			       DP_AUX_HDCP_V_PRIME(i), part,
> +			       DRM_HDCP_V_PRIME_PART_LEN);
> +	if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +	return 0;
> +}
> +
> +static
> +int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> +				    enum transcoder cpu_transcoder,
> +				    bool enable)
> +{
> +	/* Not used for single stream DisplayPort setups */
> +	return 0;
> +}
> +
> +static
> +bool intel_dp_hdcp_check_link(struct intel_digital_port
> +*intel_dig_port) {
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +	u8 bstatus;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> DP_AUX_HDCP_BSTATUS,
> +			       &bstatus, 1);
> +	if (ret != 1) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> +		return false;
> +	}
> +
> +	return !(bstatus & (DP_BSTATUS_LINK_FAILURE |
> DP_BSTATUS_REAUTH_REQ));
> +}
> +
> +static
> +int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
> +			  bool *hdcp_capable)
> +{
> +	ssize_t ret;
> +	u8 bcaps;
> +
> +	ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
> +	if (ret)
> +		return ret;
> +
> +	*hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE;
> +	return 0;
> +}
> +
> +struct hdcp2_dp_errata_stream_type {
> +	u8	msg_id;
> +	u8	stream_type;
> +} __packed;
> +
> +struct hdcp2_dp_msg_data {
> +	u8 msg_id;
> +	u32 offset;
> +	bool msg_detectable;
> +	u32 timeout;
> +	u32 timeout2; /* Added for non_paired situation */ };
> +
> +static const struct hdcp2_dp_msg_data hdcp2_dp_msg_data[] = {
> +	{ HDCP_2_2_AKE_INIT, DP_HDCP_2_2_AKE_INIT_OFFSET, false, 0, 0 },
> +	{ HDCP_2_2_AKE_SEND_CERT,
> DP_HDCP_2_2_AKE_SEND_CERT_OFFSET,
> +	  false, HDCP_2_2_CERT_TIMEOUT_MS, 0 },
> +	{ HDCP_2_2_AKE_NO_STORED_KM,
> DP_HDCP_2_2_AKE_NO_STORED_KM_OFFSET,
> +	  false, 0, 0 },
> +	{ HDCP_2_2_AKE_STORED_KM,
> DP_HDCP_2_2_AKE_STORED_KM_OFFSET,
> +	  false, 0, 0 },
> +	{ HDCP_2_2_AKE_SEND_HPRIME,
> DP_HDCP_2_2_AKE_SEND_HPRIME_OFFSET,
> +	  true, HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS,
> +	  HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS },
> +	{ HDCP_2_2_AKE_SEND_PAIRING_INFO,
> +	  DP_HDCP_2_2_AKE_SEND_PAIRING_INFO_OFFSET, true,
> +	  HDCP_2_2_PAIRING_TIMEOUT_MS, 0 },
> +	{ HDCP_2_2_LC_INIT, DP_HDCP_2_2_LC_INIT_OFFSET, false, 0, 0 },
> +	{ HDCP_2_2_LC_SEND_LPRIME,
> DP_HDCP_2_2_LC_SEND_LPRIME_OFFSET,
> +	  false, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, 0 },
> +	{ HDCP_2_2_SKE_SEND_EKS, DP_HDCP_2_2_SKE_SEND_EKS_OFFSET,
> false,
> +	  0, 0 },
> +	{ HDCP_2_2_REP_SEND_RECVID_LIST,
> +	  DP_HDCP_2_2_REP_SEND_RECVID_LIST_OFFSET, true,
> +	  HDCP_2_2_RECVID_LIST_TIMEOUT_MS, 0 },
> +	{ HDCP_2_2_REP_SEND_ACK, DP_HDCP_2_2_REP_SEND_ACK_OFFSET,
> false,
> +	  0, 0 },
> +	{ HDCP_2_2_REP_STREAM_MANAGE,
> +	  DP_HDCP_2_2_REP_STREAM_MANAGE_OFFSET, false,
> +	  0, 0 },
> +	{ HDCP_2_2_REP_STREAM_READY,
> DP_HDCP_2_2_REP_STREAM_READY_OFFSET,
> +	  false, HDCP_2_2_STREAM_READY_TIMEOUT_MS, 0 },
> +/* local define to shovel this through the write_2_2 interface */
> +#define HDCP_2_2_ERRATA_DP_STREAM_TYPE	50
> +	{ HDCP_2_2_ERRATA_DP_STREAM_TYPE,
> +	  DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, false,
> +	  0, 0 },
> +};
> +
> +static int
> +intel_dp_hdcp2_read_rx_status(struct intel_digital_port *intel_dig_port,
> +			      u8 *rx_status)
> +{
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	ssize_t ret;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> +			       DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
> +			       HDCP_2_2_DP_RXSTATUS_LEN);
> +	if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
> +		drm_dbg_kms(&i915->drm,
> +			    "Read bstatus from DP/AUX failed (%zd)\n", ret);
> +		return ret >= 0 ? -EIO : ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static
> +int hdcp2_detect_msg_availability(struct intel_digital_port *intel_dig_port,
> +				  u8 msg_id, bool *msg_ready)
> +{
> +	u8 rx_status;
> +	int ret;
> +
> +	*msg_ready = false;
> +	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
> +	if (ret < 0)
> +		return ret;
> +
> +	switch (msg_id) {
> +	case HDCP_2_2_AKE_SEND_HPRIME:
> +		if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rx_status))
> +			*msg_ready = true;
> +		break;
> +	case HDCP_2_2_AKE_SEND_PAIRING_INFO:
> +		if (HDCP_2_2_DP_RXSTATUS_PAIRING(rx_status))
> +			*msg_ready = true;
> +		break;
> +	case HDCP_2_2_REP_SEND_RECVID_LIST:
> +		if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
> +			*msg_ready = true;
> +		break;
> +	default:
> +		DRM_ERROR("Unidentified msg_id: %d\n", msg_id);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static ssize_t
> +intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *intel_dig_port,
> +			    const struct hdcp2_dp_msg_data *hdcp2_msg_data)
> {
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	struct intel_dp *dp = &intel_dig_port->dp;
> +	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
> +	u8 msg_id = hdcp2_msg_data->msg_id;
> +	int ret, timeout;
> +	bool msg_ready = false;
> +
> +	if (msg_id == HDCP_2_2_AKE_SEND_HPRIME && !hdcp->is_paired)
> +		timeout = hdcp2_msg_data->timeout2;
> +	else
> +		timeout = hdcp2_msg_data->timeout;
> +
> +	/*
> +	 * There is no way to detect the CERT, LPRIME and STREAM_READY
> +	 * availability. So Wait for timeout and read the msg.
> +	 */
> +	if (!hdcp2_msg_data->msg_detectable) {
> +		mdelay(timeout);
> +		ret = 0;
> +	} else {
> +		/*
> +		 * As we want to check the msg availability at timeout, Ignoring
> +		 * the timeout at wait for CP_IRQ.
> +		 */
> +		intel_dp_hdcp_wait_for_cp_irq(hdcp, timeout);
> +		ret = hdcp2_detect_msg_availability(intel_dig_port,
> +						    msg_id, &msg_ready);
> +		if (!msg_ready)
> +			ret = -ETIMEDOUT;
> +	}
> +
> +	if (ret)
> +		drm_dbg_kms(&i915->drm,
> +			    "msg_id %d, ret %d, timeout(mSec): %d\n",
> +			    hdcp2_msg_data->msg_id, ret, timeout);
> +
> +	return ret;
> +}
> +
> +static const struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hdcp2_dp_msg_data); i++)
> +		if (hdcp2_dp_msg_data[i].msg_id == msg_id)
> +			return &hdcp2_dp_msg_data[i];
> +
> +	return NULL;
> +}
> +
> +static
> +int intel_dp_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
> +			     void *buf, size_t size)
> +{
> +	struct intel_dp *dp = &intel_dig_port->dp;
> +	struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
> +	unsigned int offset;
> +	u8 *byte = buf;
> +	ssize_t ret, bytes_to_write, len;
> +	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
> +
> +	hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
> +	if (!hdcp2_msg_data)
> +		return -EINVAL;
> +
> +	offset = hdcp2_msg_data->offset;
> +
> +	/* No msg_id in DP HDCP2.2 msgs */
> +	bytes_to_write = size - 1;
> +	byte++;
> +
> +	hdcp->cp_irq_count_cached = atomic_read(&hdcp->cp_irq_count);
> +
> +	while (bytes_to_write) {
> +		len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
> +				DP_AUX_MAX_PAYLOAD_BYTES :
> bytes_to_write;
> +
> +		ret = drm_dp_dpcd_write(&intel_dig_port->dp.aux,
> +					offset, (void *)byte, len);
> +		if (ret < 0)
> +			return ret;
> +
> +		bytes_to_write -= ret;
> +		byte += ret;
> +		offset += ret;
> +	}
> +
> +	return size;
> +}
> +
> +static
> +ssize_t get_receiver_id_list_size(struct intel_digital_port
> +*intel_dig_port) {
> +	u8 rx_info[HDCP_2_2_RXINFO_LEN];
> +	u32 dev_cnt;
> +	ssize_t ret;
> +
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> +			       DP_HDCP_2_2_REG_RXINFO_OFFSET,
> +			       (void *)rx_info, HDCP_2_2_RXINFO_LEN);
> +	if (ret != HDCP_2_2_RXINFO_LEN)
> +		return ret >= 0 ? -EIO : ret;
> +
> +	dev_cnt = (HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 |
> +		   HDCP_2_2_DEV_COUNT_LO(rx_info[1]));
> +
> +	if (dev_cnt > HDCP_2_2_MAX_DEVICE_COUNT)
> +		dev_cnt = HDCP_2_2_MAX_DEVICE_COUNT;
> +
> +	ret = sizeof(struct hdcp2_rep_send_receiverid_list) -
> +		HDCP_2_2_RECEIVER_IDS_MAX_LEN +
> +		(dev_cnt * HDCP_2_2_RECEIVER_ID_LEN);
> +
> +	return ret;
> +}
> +
> +static
> +int intel_dp_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
> +			    u8 msg_id, void *buf, size_t size) {
> +	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> +	unsigned int offset;
> +	u8 *byte = buf;
> +	ssize_t ret, bytes_to_recv, len;
> +	const struct hdcp2_dp_msg_data *hdcp2_msg_data;
> +
> +	hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
> +	if (!hdcp2_msg_data)
> +		return -EINVAL;
> +	offset = hdcp2_msg_data->offset;
> +
> +	ret = intel_dp_hdcp2_wait_for_msg(intel_dig_port, hdcp2_msg_data);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
> +		ret = get_receiver_id_list_size(intel_dig_port);
> +		if (ret < 0)
> +			return ret;
> +
> +		size = ret;
> +	}
> +	bytes_to_recv = size - 1;
> +
> +	/* DP adaptation msgs has no msg_id */
> +	byte++;
> +
> +	while (bytes_to_recv) {
> +		len = bytes_to_recv > DP_AUX_MAX_PAYLOAD_BYTES ?
> +		      DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
> +
> +		ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, offset,
> +				       (void *)byte, len);
> +		if (ret < 0) {
> +			drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
> +				    msg_id, ret);
> +			return ret;
> +		}
> +
> +		bytes_to_recv -= ret;
> +		byte += ret;
> +		offset += ret;
> +	}
> +	byte = buf;
> +	*byte = msg_id;
> +
> +	return size;
> +}
> +
> +static
> +int intel_dp_hdcp2_config_stream_type(struct intel_digital_port
> *intel_dig_port,
> +				      bool is_repeater, u8 content_type) {
> +	int ret;
> +	struct hdcp2_dp_errata_stream_type stream_type_msg;
> +
> +	if (is_repeater)
> +		return 0;
> +
> +	/*
> +	 * Errata for DP: As Stream type is used for encryption, Receiver
> +	 * should be communicated with stream type for the decryption of the
> +	 * content.
> +	 * Repeater will be communicated with stream type as a part of it's
> +	 * auth later in time.
> +	 */
> +	stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
> +	stream_type_msg.stream_type = content_type;
> +
> +	ret =  intel_dp_hdcp2_write_msg(intel_dig_port, &stream_type_msg,
> +					sizeof(stream_type_msg));
> +
> +	return ret < 0 ? ret : 0;
> +
> +}
> +
> +static
> +int intel_dp_hdcp2_check_link(struct intel_digital_port
> +*intel_dig_port) {
> +	u8 rx_status;
> +	int ret;
> +
> +	ret = intel_dp_hdcp2_read_rx_status(intel_dig_port, &rx_status);
> +	if (ret)
> +		return ret;
> +
> +	if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
> +		ret = HDCP_REAUTH_REQUEST;
> +	else if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
> +		ret = HDCP_LINK_INTEGRITY_FAILURE;
> +	else if (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
> +		ret = HDCP_TOPOLOGY_CHANGE;
> +
> +	return ret;
> +}
> +
> +static
> +int intel_dp_hdcp2_capable(struct intel_digital_port *intel_dig_port,
> +			   bool *capable)
> +{
> +	u8 rx_caps[3];
> +	int ret;
> +
> +	*capable = false;
> +	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux,
> +			       DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
> +			       rx_caps, HDCP_2_2_RXCAPS_LEN);
> +	if (ret != HDCP_2_2_RXCAPS_LEN)
> +		return ret >= 0 ? -EIO : ret;
> +
> +	if (rx_caps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL &&
> +	    HDCP_2_2_DP_HDCP_CAPABLE(rx_caps[2]))
> +		*capable = true;
> +
> +	return 0;
> +}
> +
> +static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
> +	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
> +	.read_bksv = intel_dp_hdcp_read_bksv,
> +	.read_bstatus = intel_dp_hdcp_read_bstatus,
> +	.repeater_present = intel_dp_hdcp_repeater_present,
> +	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
> +	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> +	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> +	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> +	.toggle_signalling = intel_dp_hdcp_toggle_signalling,
> +	.check_link = intel_dp_hdcp_check_link,
> +	.hdcp_capable = intel_dp_hdcp_capable,
> +	.write_2_2_msg = intel_dp_hdcp2_write_msg,
> +	.read_2_2_msg = intel_dp_hdcp2_read_msg,
> +	.config_stream_type = intel_dp_hdcp2_config_stream_type,
> +	.check_2_2_link = intel_dp_hdcp2_check_link,
> +	.hdcp_2_2_capable = intel_dp_hdcp2_capable,
> +	.protocol = HDCP_PROTOCOL_DP,
> +};
> +
> +int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> +		       struct intel_connector *intel_connector) {
> +	struct drm_device *dev = intel_connector->base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct intel_encoder *intel_encoder = &intel_dig_port->base;
> +	enum port port = intel_encoder->port;
> +	struct intel_dp *intel_dp = &intel_dig_port->dp;
> +
> +	if (!is_hdcp_supported(dev_priv, port))
> +		return 0;
> +
> +	if (!intel_dp_is_edp(intel_dp))
> +		return intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
> +
> +	return 0;
> +}
> --
> Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v7 13/17] drm/i915: Plumb port through hdcp init
  2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
@ 2020-07-09 10:55     ` Ramalingam C
  -1 siblings, 0 replies; 98+ messages in thread
From: Ramalingam C @ 2020-07-09 10:55 UTC (permalink / raw)
  To: Sean Paul
  Cc: dri-devel, daniel.vetter, intel-gfx, Sean Paul, juston.li, rodrigo.vivi

On 2020-06-23 at 11:59:03 -0400, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> This patch plumbs port through hdcp init instead of relying on
> intel_attached_encoder() to return a non-NULL encoder which won't work
> for MST connectors.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-13-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-13-sean@poorly.run #v6
> 
> Changes in v5:
> -Added to the set
> Changes in v6:
> -None
> Changes in v7:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c |  3 ++-
>  drivers/gpu/drm/i915/display/intel_hdcp.c    | 11 ++++++-----
>  drivers/gpu/drm/i915/display/intel_hdcp.h    |  2 +-
>  drivers/gpu/drm/i915/display/intel_hdmi.c    |  2 +-
>  4 files changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> index 0e06a1066d61..e26a45f880cb 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -630,7 +630,8 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
>  		return 0;
>  
>  	if (!intel_dp_is_edp(intel_dp))
> -		return intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
> +		return intel_hdcp_init(intel_connector, port,
> +				       &intel_dp_hdcp_shim);
>  
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 5679877c6b4c..d79d4142aea7 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -1955,6 +1955,7 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum transcoder cpu_transcoder)
>  }
>  
>  static int initialize_hdcp_port_data(struct intel_connector *connector,
> +				     enum port port,
>  				     const struct intel_hdcp_shim *shim)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> @@ -1962,8 +1963,7 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
>  	struct hdcp_port_data *data = &hdcp->port_data;
>  
>  	if (INTEL_GEN(dev_priv) < 12)
> -		data->fw_ddi =
> -			intel_get_mei_fw_ddi_index(intel_attached_encoder(connector)->port);
> +		data->fw_ddi = intel_get_mei_fw_ddi_index(port);
>  	else
>  		/*
>  		 * As per ME FW API expectation, for GEN 12+, fw_ddi is filled
> @@ -2033,14 +2033,14 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
>  	}
>  }
>  
> -static void intel_hdcp2_init(struct intel_connector *connector,
> +static void intel_hdcp2_init(struct intel_connector *connector, enum port port,
>  			     const struct intel_hdcp_shim *shim)
>  {
>  	struct drm_i915_private *i915 = to_i915(connector->base.dev);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	int ret;
>  
> -	ret = initialize_hdcp_port_data(connector, shim);
> +	ret = initialize_hdcp_port_data(connector, port, shim);
>  	if (ret) {
>  		drm_dbg_kms(&i915->drm, "Mei hdcp data init failed\n");
>  		return;
> @@ -2050,6 +2050,7 @@ static void intel_hdcp2_init(struct intel_connector *connector,
>  }
>  
>  int intel_hdcp_init(struct intel_connector *connector,
> +		    enum port port,
>  		    const struct intel_hdcp_shim *shim)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> @@ -2060,7 +2061,7 @@ int intel_hdcp_init(struct intel_connector *connector,
>  		return -EINVAL;
>  
>  	if (is_hdcp2_supported(dev_priv))
> -		intel_hdcp2_init(connector, shim);
> +		intel_hdcp2_init(connector, port, shim);
>  
>  	ret =
>  	drm_connector_attach_content_protection_property(&connector->base,
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h
> index 86bbaec120cc..1bbf5b67ed0a 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.h
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.h
> @@ -22,7 +22,7 @@ enum transcoder;
>  void intel_hdcp_atomic_check(struct drm_connector *connector,
>  			     struct drm_connector_state *old_state,
>  			     struct drm_connector_state *new_state);
> -int intel_hdcp_init(struct intel_connector *connector,
> +int intel_hdcp_init(struct intel_connector *connector, enum port port,
>  		    const struct intel_hdcp_shim *hdcp_shim);
>  int intel_hdcp_enable(struct intel_connector *connector,
>  		      enum transcoder cpu_transcoder, u8 content_type);
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index a59acfff456e..ca71ee3dd1c7 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -3260,7 +3260,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
>  	intel_hdmi->attached_connector = intel_connector;
>  
>  	if (is_hdcp_supported(dev_priv, port)) {
> -		int ret = intel_hdcp_init(intel_connector,
> +		int ret = intel_hdcp_init(intel_connector, port,
>  					  &intel_hdmi_hdcp_shim);
>  		if (ret)
>  			drm_dbg_kms(&dev_priv->drm,
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 13/17] drm/i915: Plumb port through hdcp init
@ 2020-07-09 10:55     ` Ramalingam C
  0 siblings, 0 replies; 98+ messages in thread
From: Ramalingam C @ 2020-07-09 10:55 UTC (permalink / raw)
  To: Sean Paul; +Cc: dri-devel, daniel.vetter, intel-gfx, Sean Paul

On 2020-06-23 at 11:59:03 -0400, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> This patch plumbs port through hdcp init instead of relying on
> intel_attached_encoder() to return a non-NULL encoder which won't work
> for MST connectors.
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

> Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-13-sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-13-sean@poorly.run #v6
> 
> Changes in v5:
> -Added to the set
> Changes in v6:
> -None
> Changes in v7:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c |  3 ++-
>  drivers/gpu/drm/i915/display/intel_hdcp.c    | 11 ++++++-----
>  drivers/gpu/drm/i915/display/intel_hdcp.h    |  2 +-
>  drivers/gpu/drm/i915/display/intel_hdmi.c    |  2 +-
>  4 files changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> index 0e06a1066d61..e26a45f880cb 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -630,7 +630,8 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
>  		return 0;
>  
>  	if (!intel_dp_is_edp(intel_dp))
> -		return intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
> +		return intel_hdcp_init(intel_connector, port,
> +				       &intel_dp_hdcp_shim);
>  
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 5679877c6b4c..d79d4142aea7 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -1955,6 +1955,7 @@ static enum mei_fw_tc intel_get_mei_fw_tc(enum transcoder cpu_transcoder)
>  }
>  
>  static int initialize_hdcp_port_data(struct intel_connector *connector,
> +				     enum port port,
>  				     const struct intel_hdcp_shim *shim)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> @@ -1962,8 +1963,7 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
>  	struct hdcp_port_data *data = &hdcp->port_data;
>  
>  	if (INTEL_GEN(dev_priv) < 12)
> -		data->fw_ddi =
> -			intel_get_mei_fw_ddi_index(intel_attached_encoder(connector)->port);
> +		data->fw_ddi = intel_get_mei_fw_ddi_index(port);
>  	else
>  		/*
>  		 * As per ME FW API expectation, for GEN 12+, fw_ddi is filled
> @@ -2033,14 +2033,14 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
>  	}
>  }
>  
> -static void intel_hdcp2_init(struct intel_connector *connector,
> +static void intel_hdcp2_init(struct intel_connector *connector, enum port port,
>  			     const struct intel_hdcp_shim *shim)
>  {
>  	struct drm_i915_private *i915 = to_i915(connector->base.dev);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	int ret;
>  
> -	ret = initialize_hdcp_port_data(connector, shim);
> +	ret = initialize_hdcp_port_data(connector, port, shim);
>  	if (ret) {
>  		drm_dbg_kms(&i915->drm, "Mei hdcp data init failed\n");
>  		return;
> @@ -2050,6 +2050,7 @@ static void intel_hdcp2_init(struct intel_connector *connector,
>  }
>  
>  int intel_hdcp_init(struct intel_connector *connector,
> +		    enum port port,
>  		    const struct intel_hdcp_shim *shim)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
> @@ -2060,7 +2061,7 @@ int intel_hdcp_init(struct intel_connector *connector,
>  		return -EINVAL;
>  
>  	if (is_hdcp2_supported(dev_priv))
> -		intel_hdcp2_init(connector, shim);
> +		intel_hdcp2_init(connector, port, shim);
>  
>  	ret =
>  	drm_connector_attach_content_protection_property(&connector->base,
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.h b/drivers/gpu/drm/i915/display/intel_hdcp.h
> index 86bbaec120cc..1bbf5b67ed0a 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.h
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.h
> @@ -22,7 +22,7 @@ enum transcoder;
>  void intel_hdcp_atomic_check(struct drm_connector *connector,
>  			     struct drm_connector_state *old_state,
>  			     struct drm_connector_state *new_state);
> -int intel_hdcp_init(struct intel_connector *connector,
> +int intel_hdcp_init(struct intel_connector *connector, enum port port,
>  		    const struct intel_hdcp_shim *hdcp_shim);
>  int intel_hdcp_enable(struct intel_connector *connector,
>  		      enum transcoder cpu_transcoder, u8 content_type);
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index a59acfff456e..ca71ee3dd1c7 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -3260,7 +3260,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
>  	intel_hdmi->attached_connector = intel_connector;
>  
>  	if (is_hdcp_supported(dev_priv, port)) {
> -		int ret = intel_hdcp_init(intel_connector,
> +		int ret = intel_hdcp_init(intel_connector, port,
>  					  &intel_hdmi_hdcp_shim);
>  		if (ret)
>  			drm_dbg_kms(&dev_priv->drm,
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH v7 14/17] drm/i915: Add connector to hdcp_shim->check_link()
  2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
@ 2020-07-09 10:56     ` C, Ramalingam
  -1 siblings, 0 replies; 98+ messages in thread
From: C, Ramalingam @ 2020-07-09 10:56 UTC (permalink / raw)
  To: Sean Paul, dri-devel, intel-gfx
  Cc: daniel.vetter, Sean Paul, Li, Juston, Vivi, Rodrigo

> -----Original Message-----
> From: Sean Paul <sean@poorly.run>
> Sent: Tuesday, June 23, 2020 9:29 PM
> To: dri-devel@lists.freedesktop.org; intel-gfx@lists.freedesktop.org
> Cc: Li, Juston <juston.li@intel.com>; C, Ramalingam
> <ramalingam.c@intel.com>; ville.syrjala@linux.intel.com;
> jani.nikula@linux.intel.com; joonas.lahtinen@linux.intel.com; Vivi, Rodrigo
> <rodrigo.vivi@intel.com>; daniel.vetter@ffwll.ch; Sean Paul
> <seanpaul@chromium.org>
> Subject: [PATCH v7 14/17] drm/i915: Add connector to hdcp_shim->check_link()
> 
> From: Sean Paul <seanpaul@chromium.org>
> 
> Currently we derive the connector from digital port in check_link(). For MST, this
> isn't sufficient since the digital port passed into the function can have multiple
> connectors downstream. This patch adds connector to the check_link()
> arguments so we have it when we need it.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-13-
> sean@poorly.run #v4
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-14-
> sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-
> 14-sean@poorly.run #v6
> 
> Changes in v4:
> -Added to the set
> Changes in v5:
> -None
> Changes in v6:
> -None
> Changes in v7:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_display_types.h | 3 ++-
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c       | 3 ++-
>  drivers/gpu/drm/i915/display/intel_hdcp.c          | 2 +-
>  drivers/gpu/drm/i915/display/intel_hdmi.c          | 5 ++---
>  4 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 811085ef3fba..94211b8fc159 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -318,7 +318,8 @@ struct intel_hdcp_shim {
>  				 bool enable);
> 
>  	/* Ensures the link is still protected */
> -	bool (*check_link)(struct intel_digital_port *intel_dig_port);
> +	bool (*check_link)(struct intel_digital_port *intel_dig_port,
> +			   struct intel_connector *connector);
> 
>  	/* Detects panel's hdcp capability. This is optional for HDMI. */
>  	int (*hdcp_capable)(struct intel_digital_port *intel_dig_port, diff --git
> a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> index e26a45f880cb..43446a6cae8d 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -223,7 +223,8 @@ int intel_dp_hdcp_toggle_signalling(struct
> intel_digital_port *intel_dig_port,  }
> 
>  static
> -bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
> +bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> +			      struct intel_connector *connector)
>  {
>  	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
>  	ssize_t ret;
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c
> b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index d79d4142aea7..6bd0e4616ee1 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -953,7 +953,7 @@ static int intel_hdcp_check_link(struct intel_connector
> *connector)
>  		goto out;
>  	}
> 
> -	if (hdcp->shim->check_link(intel_dig_port)) {
> +	if (hdcp->shim->check_link(intel_dig_port, connector)) {
>  		if (hdcp->value !=
> DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
>  			intel_hdcp_update_value(connector,
> 
> 	DRM_MODE_CONTENT_PROTECTION_ENABLED, true); diff --git
> a/drivers/gpu/drm/i915/display/intel_hdmi.c
> b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index ca71ee3dd1c7..b12f1af0611d 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -1546,11 +1546,10 @@ int intel_hdmi_hdcp_toggle_signalling(struct
> intel_digital_port *intel_dig_port,  }
> 
>  static
> -bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port)
> +bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> +				struct intel_connector *connector)
>  {
>  	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	struct intel_connector *connector =
> -		intel_dig_port->hdmi.attached_connector;
>  	enum port port = intel_dig_port->base.port;
>  	enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder;
>  	int ret;
> --
> Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 14/17] drm/i915: Add connector to hdcp_shim->check_link()
@ 2020-07-09 10:56     ` C, Ramalingam
  0 siblings, 0 replies; 98+ messages in thread
From: C, Ramalingam @ 2020-07-09 10:56 UTC (permalink / raw)
  To: Sean Paul, dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

> -----Original Message-----
> From: Sean Paul <sean@poorly.run>
> Sent: Tuesday, June 23, 2020 9:29 PM
> To: dri-devel@lists.freedesktop.org; intel-gfx@lists.freedesktop.org
> Cc: Li, Juston <juston.li@intel.com>; C, Ramalingam
> <ramalingam.c@intel.com>; ville.syrjala@linux.intel.com;
> jani.nikula@linux.intel.com; joonas.lahtinen@linux.intel.com; Vivi, Rodrigo
> <rodrigo.vivi@intel.com>; daniel.vetter@ffwll.ch; Sean Paul
> <seanpaul@chromium.org>
> Subject: [PATCH v7 14/17] drm/i915: Add connector to hdcp_shim->check_link()
> 
> From: Sean Paul <seanpaul@chromium.org>
> 
> Currently we derive the connector from digital port in check_link(). For MST, this
> isn't sufficient since the digital port passed into the function can have multiple
> connectors downstream. This patch adds connector to the check_link()
> arguments so we have it when we need it.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-13-
> sean@poorly.run #v4
> Link:
> https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-14-
> sean@poorly.run #v5
> Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-
> 14-sean@poorly.run #v6
> 
> Changes in v4:
> -Added to the set
> Changes in v5:
> -None
> Changes in v6:
> -None
> Changes in v7:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_display_types.h | 3 ++-
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c       | 3 ++-
>  drivers/gpu/drm/i915/display/intel_hdcp.c          | 2 +-
>  drivers/gpu/drm/i915/display/intel_hdmi.c          | 5 ++---
>  4 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 811085ef3fba..94211b8fc159 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -318,7 +318,8 @@ struct intel_hdcp_shim {
>  				 bool enable);
> 
>  	/* Ensures the link is still protected */
> -	bool (*check_link)(struct intel_digital_port *intel_dig_port);
> +	bool (*check_link)(struct intel_digital_port *intel_dig_port,
> +			   struct intel_connector *connector);
> 
>  	/* Detects panel's hdcp capability. This is optional for HDMI. */
>  	int (*hdcp_capable)(struct intel_digital_port *intel_dig_port, diff --git
> a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> index e26a45f880cb..43446a6cae8d 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> @@ -223,7 +223,8 @@ int intel_dp_hdcp_toggle_signalling(struct
> intel_digital_port *intel_dig_port,  }
> 
>  static
> -bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
> +bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> +			      struct intel_connector *connector)
>  {
>  	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
>  	ssize_t ret;
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c
> b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index d79d4142aea7..6bd0e4616ee1 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -953,7 +953,7 @@ static int intel_hdcp_check_link(struct intel_connector
> *connector)
>  		goto out;
>  	}
> 
> -	if (hdcp->shim->check_link(intel_dig_port)) {
> +	if (hdcp->shim->check_link(intel_dig_port, connector)) {
>  		if (hdcp->value !=
> DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
>  			intel_hdcp_update_value(connector,
> 
> 	DRM_MODE_CONTENT_PROTECTION_ENABLED, true); diff --git
> a/drivers/gpu/drm/i915/display/intel_hdmi.c
> b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index ca71ee3dd1c7..b12f1af0611d 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -1546,11 +1546,10 @@ int intel_hdmi_hdcp_toggle_signalling(struct
> intel_digital_port *intel_dig_port,  }
> 
>  static
> -bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port)
> +bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> +				struct intel_connector *connector)
>  {
>  	struct drm_i915_private *i915 = to_i915(intel_dig_port-
> >base.base.dev);
> -	struct intel_connector *connector =
> -		intel_dig_port->hdmi.attached_connector;
>  	enum port port = intel_dig_port->base.port;
>  	enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder;
>  	int ret;
> --
> Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
  2020-07-09 10:37     ` [Intel-gfx] " Ramalingam C
@ 2020-07-09 12:28       ` Anshuman Gupta
  -1 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-09 12:28 UTC (permalink / raw)
  To: Ramalingam C; +Cc: Sean Paul, daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-07-09 at 16:07:12 +0530, Ramalingam C wrote:
> On 2020-06-23 at 11:59:07 -0400, Sean Paul wrote:
> > From: Sean Paul <seanpaul@chromium.org>
> > 
> > Now that all the groundwork has been laid, we can turn on HDCP 1.4 over
> > MST. Everything except for toggling the HDCP signalling and HDCP 2.2
> > support is the same as the DP case, so we'll re-use those callbacks
> > 
> > Cc: Juston Li <juston.li@intel.com>
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-12-sean@poorly.run #v1
> > Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-13-sean@poorly.run #v2
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-13-sean@poorly.run #v3
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-15-sean@poorly.run #v4
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-17-sean@poorly.run #v5
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-17-sean@poorly.run #v6
> > 
> > Changes in v2:
> > -Toggle HDCP from encoder disable/enable
> > -Don't disable HDCP on MST connector destroy, leave that for encoder
> >  disable, just ensure the check_work routine isn't running any longer
> > Changes in v3:
> > -Place the shim in the new intel_dp_hdcp.c file (Ville)
> > Changes in v4:
> > -Actually use the mst shim for mst connections (Juston)
> > -Use QUERY_STREAM_ENC_STATUS MST message to verify channel is encrypted
> > Changes in v5:
> > -Add sleep on disable signalling to match hdmi delay
> > Changes in v6:
> > -Disable HDCP over MST on GEN12+ since I'm unsure how it should work and I
> >  don't have hardware to test it
> > Changes in v7:
> > -Remove hdcp2 shims for MST in favor of skipping hdcp2 init (Ramalingam)
> > ---
> >  drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 66 +++++++++++++++++++-
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c  | 18 ++++++
> >  drivers/gpu/drm/i915/display/intel_hdcp.c    |  2 +-
> >  3 files changed, 84 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> > index 43446a6cae8d..3f67bd27fc3c 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> > @@ -7,10 +7,12 @@
> >   */
> >  
> >  #include <drm/drm_dp_helper.h>
> > +#include <drm/drm_dp_mst_helper.h>
> >  #include <drm/drm_hdcp.h>
> >  #include <drm/drm_print.h>
> >  
> >  #include "intel_display_types.h"
> > +#include "intel_ddi.h"
> >  #include "intel_dp.h"
> >  #include "intel_hdcp.h"
> >  
> > @@ -618,6 +620,65 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
> >  	.protocol = HDCP_PROTOCOL_DP,
> >  };
> >  
> > +static int
> > +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> > +				    enum transcoder cpu_transcoder,
> > +				    bool enable)
> > +{
> > +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > +	int ret;
> > +
> > +	if (!enable)
> > +		usleep_range(6, 60); /* Bspec says >= 6us */
> > +
> > +	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> > +					       cpu_transcoder, enable);
> Sean,
> 
> This function toggles the TRANS_DDI_HDCP_SIGNALLING (9th)bit of TRANS_DDI_FUNC_CTL(tran)
> But in the hw specification this bit is mentioned to be ignored for non
> HDMI/DVI modes of the TRANS DDI.
> 
> Any reason why we need this? Did you try with out this function?
> 
> Apart from that Patch looks good to me.
IMHO it seems we are still missing to enable the Multistream HDCP Select
bit (5) in TRANS_DDI_FUNC_CTL register which is required to enable the
stream encryption.

Thanks,
Anshuman Gupta.
> 
> -Ram
> 
> > +	if (ret)
> > +		drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> > +			      enable ? "Enable" : "Disable", ret);
> > +	return ret;
> > +}
> > +
> > +static
> > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> > +				  struct intel_connector *connector)
> > +{
> > +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > +	struct intel_dp *intel_dp = &intel_dig_port->dp;
> > +	struct drm_dp_query_stream_enc_status_ack_reply reply;
> > +	int ret;
> > +
> > +	if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> > +		return false;
> > +
> > +	ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> > +						  connector->port, &reply);
> > +	if (ret) {
> > +		drm_dbg_kms(&i915->drm,
> > +			    "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> > +			    connector->base.base.id, connector->base.name, ret);
> > +		return false;
> > +	}
> > +
> > +	return reply.auth_completed && reply.encryption_enabled;
> > +}
> > +
> > +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> > +	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > +	.read_bksv = intel_dp_hdcp_read_bksv,
> > +	.read_bstatus = intel_dp_hdcp_read_bstatus,
> > +	.repeater_present = intel_dp_hdcp_repeater_present,
> > +	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
> > +	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> > +	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> > +	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> > +	.toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> > +	.check_link = intel_dp_mst_hdcp_check_link,
> > +	.hdcp_capable = intel_dp_hdcp_capable,
> > +
> > +	.protocol = HDCP_PROTOCOL_DP,
> > +};
> > +
> >  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> >  		       struct intel_connector *intel_connector)
> >  {
> > @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> >  	if (!is_hdcp_supported(dev_priv, port))
> >  		return 0;
> >  
> > -	if (!intel_dp_is_edp(intel_dp))
> > +	if (intel_connector->mst_port)
> > +		return intel_hdcp_init(intel_connector, port,
> > +				       &intel_dp_mst_hdcp_shim);
> > +	else if (!intel_dp_is_edp(intel_dp))
> >  		return intel_hdcp_init(intel_connector, port,
> >  				       &intel_dp_hdcp_shim);
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index 0675825dcc20..abaaeeb963d2 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -37,6 +37,7 @@
> >  #include "intel_dp.h"
> >  #include "intel_dp_mst.h"
> >  #include "intel_dpio_phy.h"
> > +#include "intel_hdcp.h"
> >  
> >  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> >  					    struct intel_crtc_state *crtc_state,
> > @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
> >  	drm_dbg_kms(&i915->drm, "active links %d\n",
> >  		    intel_dp->active_mst_links);
> >  
> > +	intel_hdcp_disable(intel_mst->connector);
> > +
> >  	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
> >  
> >  	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> > @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
> >  
> >  	if (pipe_config->has_audio)
> >  		intel_audio_codec_enable(encoder, pipe_config, conn_state);
> > +
> > +	/* Enable hdcp if it's desired */
> > +	if (conn_state->content_protection ==
> > +	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > +		intel_hdcp_enable(to_intel_connector(conn_state->connector),
> > +				  pipe_config->cpu_transcoder,
> > +				  (u8)conn_state->hdcp_content_type);
> >  }
> >  
> >  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> > @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
> >  	intel_attach_force_audio_property(connector);
> >  	intel_attach_broadcast_rgb_property(connector);
> >  
> > +
> > +	/* TODO: Figure out how to make HDCP work on GEN12+ */
> > +	if (INTEL_GEN(dev_priv) < 12) {
> > +		ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> > +		if (ret)
> > +			DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> > +	}
> > +
> >  	/*
> >  	 * Reuse the prop from the SST connector because we're
> >  	 * not allowed to create new props after device registration.
> > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > index 6bd0e4616ee1..ddc9db8de2bc 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
> >  	if (!shim)
> >  		return -EINVAL;
> >  
> > -	if (is_hdcp2_supported(dev_priv))
> > +	if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
> >  		intel_hdcp2_init(connector, port, shim);
> >  
> >  	ret =
> > -- 
> > Sean Paul, Software Engineer, Google / Chromium OS
> > 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
@ 2020-07-09 12:28       ` Anshuman Gupta
  0 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-09 12:28 UTC (permalink / raw)
  To: Ramalingam C; +Cc: Sean Paul, daniel.vetter, intel-gfx, dri-devel

On 2020-07-09 at 16:07:12 +0530, Ramalingam C wrote:
> On 2020-06-23 at 11:59:07 -0400, Sean Paul wrote:
> > From: Sean Paul <seanpaul@chromium.org>
> > 
> > Now that all the groundwork has been laid, we can turn on HDCP 1.4 over
> > MST. Everything except for toggling the HDCP signalling and HDCP 2.2
> > support is the same as the DP case, so we'll re-use those callbacks
> > 
> > Cc: Juston Li <juston.li@intel.com>
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-12-sean@poorly.run #v1
> > Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-13-sean@poorly.run #v2
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-13-sean@poorly.run #v3
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-15-sean@poorly.run #v4
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-17-sean@poorly.run #v5
> > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-17-sean@poorly.run #v6
> > 
> > Changes in v2:
> > -Toggle HDCP from encoder disable/enable
> > -Don't disable HDCP on MST connector destroy, leave that for encoder
> >  disable, just ensure the check_work routine isn't running any longer
> > Changes in v3:
> > -Place the shim in the new intel_dp_hdcp.c file (Ville)
> > Changes in v4:
> > -Actually use the mst shim for mst connections (Juston)
> > -Use QUERY_STREAM_ENC_STATUS MST message to verify channel is encrypted
> > Changes in v5:
> > -Add sleep on disable signalling to match hdmi delay
> > Changes in v6:
> > -Disable HDCP over MST on GEN12+ since I'm unsure how it should work and I
> >  don't have hardware to test it
> > Changes in v7:
> > -Remove hdcp2 shims for MST in favor of skipping hdcp2 init (Ramalingam)
> > ---
> >  drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 66 +++++++++++++++++++-
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c  | 18 ++++++
> >  drivers/gpu/drm/i915/display/intel_hdcp.c    |  2 +-
> >  3 files changed, 84 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> > index 43446a6cae8d..3f67bd27fc3c 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
> > @@ -7,10 +7,12 @@
> >   */
> >  
> >  #include <drm/drm_dp_helper.h>
> > +#include <drm/drm_dp_mst_helper.h>
> >  #include <drm/drm_hdcp.h>
> >  #include <drm/drm_print.h>
> >  
> >  #include "intel_display_types.h"
> > +#include "intel_ddi.h"
> >  #include "intel_dp.h"
> >  #include "intel_hdcp.h"
> >  
> > @@ -618,6 +620,65 @@ static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
> >  	.protocol = HDCP_PROTOCOL_DP,
> >  };
> >  
> > +static int
> > +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> > +				    enum transcoder cpu_transcoder,
> > +				    bool enable)
> > +{
> > +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > +	int ret;
> > +
> > +	if (!enable)
> > +		usleep_range(6, 60); /* Bspec says >= 6us */
> > +
> > +	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> > +					       cpu_transcoder, enable);
> Sean,
> 
> This function toggles the TRANS_DDI_HDCP_SIGNALLING (9th)bit of TRANS_DDI_FUNC_CTL(tran)
> But in the hw specification this bit is mentioned to be ignored for non
> HDMI/DVI modes of the TRANS DDI.
> 
> Any reason why we need this? Did you try with out this function?
> 
> Apart from that Patch looks good to me.
IMHO it seems we are still missing to enable the Multistream HDCP Select
bit (5) in TRANS_DDI_FUNC_CTL register which is required to enable the
stream encryption.

Thanks,
Anshuman Gupta.
> 
> -Ram
> 
> > +	if (ret)
> > +		drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> > +			      enable ? "Enable" : "Disable", ret);
> > +	return ret;
> > +}
> > +
> > +static
> > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> > +				  struct intel_connector *connector)
> > +{
> > +	struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > +	struct intel_dp *intel_dp = &intel_dig_port->dp;
> > +	struct drm_dp_query_stream_enc_status_ack_reply reply;
> > +	int ret;
> > +
> > +	if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> > +		return false;
> > +
> > +	ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> > +						  connector->port, &reply);
> > +	if (ret) {
> > +		drm_dbg_kms(&i915->drm,
> > +			    "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> > +			    connector->base.base.id, connector->base.name, ret);
> > +		return false;
> > +	}
> > +
> > +	return reply.auth_completed && reply.encryption_enabled;
> > +}
> > +
> > +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> > +	.write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > +	.read_bksv = intel_dp_hdcp_read_bksv,
> > +	.read_bstatus = intel_dp_hdcp_read_bstatus,
> > +	.repeater_present = intel_dp_hdcp_repeater_present,
> > +	.read_ri_prime = intel_dp_hdcp_read_ri_prime,
> > +	.read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> > +	.read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> > +	.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> > +	.toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> > +	.check_link = intel_dp_mst_hdcp_check_link,
> > +	.hdcp_capable = intel_dp_hdcp_capable,
> > +
> > +	.protocol = HDCP_PROTOCOL_DP,
> > +};
> > +
> >  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> >  		       struct intel_connector *intel_connector)
> >  {
> > @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> >  	if (!is_hdcp_supported(dev_priv, port))
> >  		return 0;
> >  
> > -	if (!intel_dp_is_edp(intel_dp))
> > +	if (intel_connector->mst_port)
> > +		return intel_hdcp_init(intel_connector, port,
> > +				       &intel_dp_mst_hdcp_shim);
> > +	else if (!intel_dp_is_edp(intel_dp))
> >  		return intel_hdcp_init(intel_connector, port,
> >  				       &intel_dp_hdcp_shim);
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index 0675825dcc20..abaaeeb963d2 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -37,6 +37,7 @@
> >  #include "intel_dp.h"
> >  #include "intel_dp_mst.h"
> >  #include "intel_dpio_phy.h"
> > +#include "intel_hdcp.h"
> >  
> >  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> >  					    struct intel_crtc_state *crtc_state,
> > @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
> >  	drm_dbg_kms(&i915->drm, "active links %d\n",
> >  		    intel_dp->active_mst_links);
> >  
> > +	intel_hdcp_disable(intel_mst->connector);
> > +
> >  	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
> >  
> >  	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> > @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
> >  
> >  	if (pipe_config->has_audio)
> >  		intel_audio_codec_enable(encoder, pipe_config, conn_state);
> > +
> > +	/* Enable hdcp if it's desired */
> > +	if (conn_state->content_protection ==
> > +	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > +		intel_hdcp_enable(to_intel_connector(conn_state->connector),
> > +				  pipe_config->cpu_transcoder,
> > +				  (u8)conn_state->hdcp_content_type);
> >  }
> >  
> >  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> > @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
> >  	intel_attach_force_audio_property(connector);
> >  	intel_attach_broadcast_rgb_property(connector);
> >  
> > +
> > +	/* TODO: Figure out how to make HDCP work on GEN12+ */
> > +	if (INTEL_GEN(dev_priv) < 12) {
> > +		ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> > +		if (ret)
> > +			DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> > +	}
> > +
> >  	/*
> >  	 * Reuse the prop from the SST connector because we're
> >  	 * not allowed to create new props after device registration.
> > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > index 6bd0e4616ee1..ddc9db8de2bc 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
> >  	if (!shim)
> >  		return -EINVAL;
> >  
> > -	if (is_hdcp2_supported(dev_priv))
> > +	if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
> >  		intel_hdcp2_init(connector, port, shim);
> >  
> >  	ret =
> > -- 
> > Sean Paul, Software Engineer, Google / Chromium OS
> > 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
  2020-07-02 14:37         ` Anshuman Gupta
@ 2020-07-09 12:58           ` Anshuman Gupta
  -1 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-09 12:58 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-07-02 at 20:07:36 +0530, Anshuman Gupta wrote:
> On 2020-06-30 at 12:48:34 -0400, Sean Paul wrote:
> > On Tue, Jun 30, 2020 at 10:21 AM Anshuman Gupta
> > <anshuman.gupta@intel.com> wrote:
> > >
> > > On 2020-06-23 at 21:29:05 +0530, Sean Paul wrote:
> > > Hi Sean,
> > > I am new to DP MST stuff, I am looking to DP MST spec DP v1.2a.
> > > I have looked the entire series, i will take up this opportunity to review
> > > the series from HDCP over DP MST POV.
> > > I think theoretically this series should work or Gen12 as well, as DP MST streams
> > > are getting encrypted by QUERY_STREAM_ENCRYPTION_STATUS reply tranaction msg
> > > (generating Stream State Signature L’).
> > > I will test this on Gen12 H/W with DP MST support and will provide my inputs.
> > >
> > > Meanwhile while going through DP MST v1.2a specs(Page 262) came to know about
> > > a DP irq vector LINK_SERVICE_IRQ_VECTOR_ESI0 (02005h),
> > > Bit 2 : STREAM_STATUS_CHANGED.
> > > When this bit set to ‘1’ indicates the source must re-check the Stream Status
> > > with the QUERY_STREAM_ENCRYPTION_STATUS message.
> > > Currently i feel this irq support is missing, do we require to support
> > > above IRQ vector for DP MST stream encryption.
> > >
> > 
> > Hi Anshuman,
> > Thank you for your comments.
> > 
> > QUERY_STREAM_ENCRYPTION_STATUS is not necessary for HDCP 1.x, I added
> > this as a safety check to ensure that the streams were being
> > encrypted. As such, the existing integrity checks in place for DP are
> > sufficient to satisfy spec. When HDCP 2.2 support is added for MST,
> > handling QSES will need to be addressed to meet spec. Note also that
> > we're not validating the QSES signature for the same reason.
> Thanks sean for the explanation,
> overall patch looks good to me but i have couple of doubt see below.
> > 
> > Sean
> > 
> > 
> > > Thanks,
> > > Anshuman Gupta.
> > >
> > > > From: Sean Paul <seanpaul@chromium.org>
> > > >
> > > > Used to query whether an MST stream is encrypted or not.
> > > >
> > > > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > > >
> > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
> > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
> > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6
> > > >
> > > > Changes in v4:
> > > > -Added to the set
> > > > Changes in v5:
> > > > -None
> > > > Changes in v6:
> > > > -Use FIELD_PREP to generate request buffer bitfields (Lyude)
> > > > -Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
> > > > Changes in v7:
> > > > -None
> > > > ---
> > > >  drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
> > > >  .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
> > > >  include/drm/drm_dp_helper.h                   |   3 +
> > > >  include/drm/drm_dp_mst_helper.h               |  44 ++++++
> > > >  4 files changed, 206 insertions(+)
> > > >
> > > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > index b2f5a84b4cfb..fc68478eaeb4 100644
> > > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > @@ -20,11 +20,13 @@
> > > >   * OF THIS SOFTWARE.
> > > >   */
> > > >
> > > > +#include <linux/bitfield.h>
> > > >  #include <linux/delay.h>
> > > >  #include <linux/errno.h>
> > > >  #include <linux/i2c.h>
> > > >  #include <linux/init.h>
> > > >  #include <linux/kernel.h>
> > > > +#include <linux/random.h>
> > > >  #include <linux/sched.h>
> > > >  #include <linux/seq_file.h>
> > > >  #include <linux/iopoll.h>
> > > > @@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
> > > >               memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
> > > >               idx += req->u.i2c_write.num_bytes;
> > > >               break;
> > > > +     case DP_QUERY_STREAM_ENC_STATUS: {
> > > > +             const struct drm_dp_query_stream_enc_status *msg;
> > > > +
> > > > +             msg = &req->u.enc_status;
> > > > +             buf[idx] = msg->stream_id;
> > > > +             idx++;
> > > > +             memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
> > > > +             idx += sizeof(msg->client_id);
> > > > +             buf[idx] = 0;
> > > > +             buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
> > > > +             buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
> > > > +             buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
> > > > +             buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
> > > > +             idx++;
> > > > +             }
> > > > +             break;
> > > >       }
> > > >       raw->cur_len = idx;
> > > >  }
> > > > @@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
> > > >                               return -ENOMEM;
> > > >               }
> > > >               break;
> > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > +             req->u.enc_status.stream_id = buf[idx++];
> > > > +             for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
> > > > +                     req->u.enc_status.client_id[i] = buf[idx++];
> > > > +
> > > > +             req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
> > > > +                                                        buf[idx]);
> > > > +             req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
> > > > +                                                              buf[idx]);
> > > > +             req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
> > > > +                                                           buf[idx]);
> > > > +             req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
> > > > +                                                                 buf[idx]);
> > > > +             break;
> > > >       }
> > > >
> > > >       return 0;
> > > > @@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
> > > >                 req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
> > > >                 req->u.i2c_write.bytes);
> > > >               break;
> > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > +             P("stream_id=%u client_id=%*ph stream_event=%x "
> > > > +               "valid_event=%d stream_behavior=%x valid_behavior=%d",
> > > > +               req->u.enc_status.stream_id,
> > > > +               (int)ARRAY_SIZE(req->u.enc_status.client_id),
> > > > +               req->u.enc_status.client_id, req->u.enc_status.stream_event,
> > > > +               req->u.enc_status.valid_stream_event,
> > > > +               req->u.enc_status.stream_behavior,
> > > > +               req->u.enc_status.valid_stream_behavior);
> > > > +             break;
> > > >       default:
> > > >               P("???\n");
> > > >               break;
> > > > @@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
> > > >       return true;
> > > >  }
> > > >
> > > > +static bool
> > > > +drm_dp_sideband_parse_query_stream_enc_status(
> > > > +                             struct drm_dp_sideband_msg_rx *raw,
> > > > +                             struct drm_dp_sideband_msg_reply_body *repmsg)
> > > > +{
> > > > +     struct drm_dp_query_stream_enc_status_ack_reply *reply;
> > > > +
> > > > +     reply = &repmsg->u.enc_status;
> > > > +
> > > > +     reply->stream_id = raw->msg[3];
> It seems msg[0] is not part of reply data,
> could you help me with pointers, where msg is formatted.
> > > > +
> > > > +     reply->reply_signed = raw->msg[2] & BIT(0);
This whole patch looks good to me i could have given RB but i am having
some concerns regarding parsing of bits here.
reply_signed is 15th bit of reply message i.e MSB of msg[2] here.
it seems bit parsing is in reverse order in all places.
> > > > +
> > > > +     reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> > > > +     reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
But these two bits are not parse as reverse order, these are parse
as similar in DP specs, hdcp_1x 11th bit (bit 3 of msg[2]),
hdcp_2x 12th bit (bit 4 of msg[2]).
Please correct me if i am wrong here.
Thanks,
Anshuman Gupta.
> > > > +
> > > > +     reply->query_capable_device_present = raw->msg[2] & BIT(5);
> > > > +     reply->legacy_device_present = raw->msg[2] & BIT(6);
> > > > +     reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> > > > +
> > > > +     reply->auth_completed = !!(raw->msg[1] & BIT(3));

> > > > +     reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> > > > +     reply->repeater_present = !!(raw->msg[1] & BIT(5));
> > > > +     reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> > > > +
> > > > +     return true;
> > > > +}
> > > > +
> > > >  static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > > >                                       struct drm_dp_sideband_msg_reply_body *msg)
> > > >  {
> > > > @@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > > >               return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
> > > >       case DP_CLEAR_PAYLOAD_ID_TABLE:
> > > >               return true; /* since there's nothing to parse */
> > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > +             return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
> > > >       default:
> > > >               DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
> > > >                         drm_dp_mst_req_type_str(msg->req_type));
> > > > @@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
> > > >       msg->path_msg = true;
> > > >  }
> > > >
> > > > +static int
> > > > +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
> > > > +                           u8 *q_id)
> > > > +{
> > > > +     struct drm_dp_sideband_msg_req_body req;
> > > > +
> > > > +     req.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > > +     req.u.enc_status.stream_id = stream_id;
> > > > +     memcpy(req.u.enc_status.client_id, q_id,
> > > > +            sizeof(req.u.enc_status.client_id));
> > > > +     req.u.enc_status.stream_event = 0;
> > > > +     req.u.enc_status.valid_stream_event = false;
> > > > +     req.u.enc_status.stream_behavior = 0;
> > > > +     req.u.enc_status.valid_stream_behavior = false;
> > > > +
> > > > +     drm_dp_encode_sideband_req(&req, msg);
> > > > +     return 0;
> > > > +}
> > > > +
> > > >  static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
> > > >                                       struct drm_dp_vcpi *vcpi)
> > > >  {
> > > > @@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > >  }
> > > >  EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
> > > >
> > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > +             struct drm_dp_mst_port *port,
> > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status)
> > > > +{
> > > > +     struct drm_dp_sideband_msg_tx *txmsg;
> > > > +     u8 nonce[7];
> > > > +     int len, ret;
> > > > +
> > > > +     txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> > > > +     if (!txmsg)
> > > > +             return -ENOMEM;
> > > > +
> > > > +     port = drm_dp_mst_topology_get_port_validated(mgr, port);
> > > > +     if (!port) {
> > > > +             ret = -EINVAL;
> > > > +             goto out_get_port;
> > > > +     }
> > > > +
> > > > +     get_random_bytes(nonce, sizeof(nonce));
> > > > +
> > > > +     /*
> > > > +      * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
> > > > +      *  transaction at the MST Branch device directly connected to the
> > > > +      *  Source"
> > > > +      */
> > > > +     txmsg->dst = mgr->mst_primary;
> > > > +
> > > > +     len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
> > > > +
> > > > +     drm_dp_queue_down_tx(mgr, txmsg);
> > > > +
> > > > +     ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
> > > > +     if (ret < 0) {
> > > > +             goto out;
> > > > +     } else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
> > > > +             DRM_DEBUG_KMS("query encryption status nak received\n");
> > > > +             ret = -ENXIO;
> > > > +             goto out;
> > > > +     }
> > > > +
> > > > +     ret = 0;
> > > > +     memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
> > > > +
> > > > +out:
> > > > +     drm_dp_mst_topology_put_port(port);
> > > > +out_get_port:
> > > > +     kfree(txmsg);
> > > > +     return ret;
> > > > +}
> > > > +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
> > > > +
> > > >  static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
> > > >                                      int id,
> > > >                                      struct drm_dp_payload *payload)
> > > > diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > index bd990d178765..1d696ec001cf 100644
> > > > --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > @@ -5,6 +5,8 @@
> > > >
> > > >  #define PREFIX_STR "[drm_dp_mst_helper]"
> > > >
> > > > +#include <linux/random.h>
> > > > +
> > > >  #include <drm/drm_dp_mst_helper.h>
> > > >  #include <drm/drm_print.h>
> > > >
> > > > @@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
> > > >       in.u.i2c_write.bytes = data;
> > > >       DO_TEST();
> > > >
> > > > +     in.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > > +     in.u.enc_status.stream_id = 1;
> > > > +     DO_TEST();
> > > > +     get_random_bytes(in.u.enc_status.client_id,
> > > > +                      sizeof(in.u.enc_status.client_id));
> > > > +     DO_TEST();
> > > > +     in.u.enc_status.stream_event = 3;
> > > > +     DO_TEST();
> > > > +     in.u.enc_status.valid_stream_event = 0;
> > > > +     DO_TEST();
> > > > +     in.u.enc_status.stream_behavior = 3;
> > > > +     DO_TEST();
> > > > +     in.u.enc_status.valid_stream_behavior = 1;
> > > > +     DO_TEST();
> > > > +
> > > >  #undef DO_TEST
> > > >       return 0;
> > > >  }
> > > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > > > index e47dc22ebf50..e2d2df5e869e 100644
> > > > --- a/include/drm/drm_dp_helper.h
> > > > +++ b/include/drm/drm_dp_helper.h
> > > > @@ -1108,6 +1108,9 @@
> > > >  #define DP_POWER_DOWN_PHY            0x25
> > > >  #define DP_SINK_EVENT_NOTIFY         0x30
> > > >  #define DP_QUERY_STREAM_ENC_STATUS   0x38
> > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST   0
> > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE   1
> > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE     2
> > > >
> > > >  /* DP 1.2 MST sideband reply types */
> > > >  #define DP_SIDEBAND_REPLY_ACK                0x00
> > > > diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> > > > index 8b9eb4db3381..371eef8798ad 100644
> > > > --- a/include/drm/drm_dp_mst_helper.h
> > > > +++ b/include/drm/drm_dp_mst_helper.h
> > > > @@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
> > > >       u8 port_number;
> > > >  };
> > > >
> > > > +struct drm_dp_query_stream_enc_status_ack_reply {
> > > > +     /* Bit[23:16]- Stream Id */
> > > > +     u8 stream_id;
> > > > +
> > > > +     /* Bit[15]- Signed */
> > > > +     bool reply_signed;
> > > > +
> > > > +     /* Bit[10:8]- Stream Output Sink Type */
> > > > +     bool unauthorizable_device_present;
> > > > +     bool legacy_device_present;
> > > > +     bool query_capable_device_present;
> > > > +
> > > > +     /* Bit[12:11]- Stream Output CP Type */
> > > > +     bool hdcp_1x_device_present;
> > > > +     bool hdcp_2x_device_present;
> > > > +
> > > > +     /* Bit[4]- Stream Authentication */
> > > > +     bool auth_completed;
> > > > +
> > > > +     /* Bit[3]- Stream Encryption */
> > > > +     bool encryption_enabled;
> > > > +
> > > > +     /* Bit[2]- Stream Repeater Function Present */
> > > > +     bool repeater_present;
> > > > +
> > > > +     /* Bit[1:0]- Stream State */
> > > > +     u8 state;
> reply msg also has 20 byte of signature L' (HDCP 1.4),
> AFAIU it has lefted out for HDCP 2.2 implementation, which is of 32 bytes for HDCP 2.2.
> Please correct me if i am wrong here.
> Thanks,
> Anshuman Gupta.
> > > > +};
> > > >
> > > >  #define DRM_DP_MAX_SDP_STREAMS 16
> > > >  struct drm_dp_allocate_payload {
> > > > @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
> > > >       u8 *bytes;
> > > >  };
> > > >
> > > > +struct drm_dp_query_stream_enc_status {
> > > > +     u8 stream_id;
> > > > +     u8 client_id[7];        /* 56-bit nonce */
> > > > +     u8 stream_event;
> > > > +     bool valid_stream_event;
> > > > +     u8 stream_behavior;
> > > > +     u8 valid_stream_behavior;
> > > > +};
> > > > +
> > > >  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
> > > >  struct drm_dp_port_number_req {
> > > >       u8 port_number;
> > > > @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
> > > >
> > > >               struct drm_dp_remote_i2c_read i2c_read;
> > > >               struct drm_dp_remote_i2c_write i2c_write;
> > > > +
> > > > +             struct drm_dp_query_stream_enc_status enc_status;
> > > >       } u;
> > > >  };
> > > >
> > > > @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
> > > >               struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
> > > >               struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
> > > >               struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> > > > +
> > > > +             struct drm_dp_query_stream_enc_status_ack_reply enc_status;
> > > >       } u;
> > > >  };
> > > >
> > > > @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
> > > >                                struct drm_dp_mst_port *port);
> > > >  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > >                                struct drm_dp_mst_port *port, bool power_up);
> > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > +             struct drm_dp_mst_port *port,
> > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status);
> > > >  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
> > > >
> > > >  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> > > > --
> > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > >
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
@ 2020-07-09 12:58           ` Anshuman Gupta
  0 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-07-09 12:58 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-07-02 at 20:07:36 +0530, Anshuman Gupta wrote:
> On 2020-06-30 at 12:48:34 -0400, Sean Paul wrote:
> > On Tue, Jun 30, 2020 at 10:21 AM Anshuman Gupta
> > <anshuman.gupta@intel.com> wrote:
> > >
> > > On 2020-06-23 at 21:29:05 +0530, Sean Paul wrote:
> > > Hi Sean,
> > > I am new to DP MST stuff, I am looking to DP MST spec DP v1.2a.
> > > I have looked the entire series, i will take up this opportunity to review
> > > the series from HDCP over DP MST POV.
> > > I think theoretically this series should work or Gen12 as well, as DP MST streams
> > > are getting encrypted by QUERY_STREAM_ENCRYPTION_STATUS reply tranaction msg
> > > (generating Stream State Signature L’).
> > > I will test this on Gen12 H/W with DP MST support and will provide my inputs.
> > >
> > > Meanwhile while going through DP MST v1.2a specs(Page 262) came to know about
> > > a DP irq vector LINK_SERVICE_IRQ_VECTOR_ESI0 (02005h),
> > > Bit 2 : STREAM_STATUS_CHANGED.
> > > When this bit set to ‘1’ indicates the source must re-check the Stream Status
> > > with the QUERY_STREAM_ENCRYPTION_STATUS message.
> > > Currently i feel this irq support is missing, do we require to support
> > > above IRQ vector for DP MST stream encryption.
> > >
> > 
> > Hi Anshuman,
> > Thank you for your comments.
> > 
> > QUERY_STREAM_ENCRYPTION_STATUS is not necessary for HDCP 1.x, I added
> > this as a safety check to ensure that the streams were being
> > encrypted. As such, the existing integrity checks in place for DP are
> > sufficient to satisfy spec. When HDCP 2.2 support is added for MST,
> > handling QSES will need to be addressed to meet spec. Note also that
> > we're not validating the QSES signature for the same reason.
> Thanks sean for the explanation,
> overall patch looks good to me but i have couple of doubt see below.
> > 
> > Sean
> > 
> > 
> > > Thanks,
> > > Anshuman Gupta.
> > >
> > > > From: Sean Paul <seanpaul@chromium.org>
> > > >
> > > > Used to query whether an MST stream is encrypted or not.
> > > >
> > > > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > > >
> > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
> > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
> > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6
> > > >
> > > > Changes in v4:
> > > > -Added to the set
> > > > Changes in v5:
> > > > -None
> > > > Changes in v6:
> > > > -Use FIELD_PREP to generate request buffer bitfields (Lyude)
> > > > -Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
> > > > Changes in v7:
> > > > -None
> > > > ---
> > > >  drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
> > > >  .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
> > > >  include/drm/drm_dp_helper.h                   |   3 +
> > > >  include/drm/drm_dp_mst_helper.h               |  44 ++++++
> > > >  4 files changed, 206 insertions(+)
> > > >
> > > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > index b2f5a84b4cfb..fc68478eaeb4 100644
> > > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > @@ -20,11 +20,13 @@
> > > >   * OF THIS SOFTWARE.
> > > >   */
> > > >
> > > > +#include <linux/bitfield.h>
> > > >  #include <linux/delay.h>
> > > >  #include <linux/errno.h>
> > > >  #include <linux/i2c.h>
> > > >  #include <linux/init.h>
> > > >  #include <linux/kernel.h>
> > > > +#include <linux/random.h>
> > > >  #include <linux/sched.h>
> > > >  #include <linux/seq_file.h>
> > > >  #include <linux/iopoll.h>
> > > > @@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
> > > >               memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
> > > >               idx += req->u.i2c_write.num_bytes;
> > > >               break;
> > > > +     case DP_QUERY_STREAM_ENC_STATUS: {
> > > > +             const struct drm_dp_query_stream_enc_status *msg;
> > > > +
> > > > +             msg = &req->u.enc_status;
> > > > +             buf[idx] = msg->stream_id;
> > > > +             idx++;
> > > > +             memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
> > > > +             idx += sizeof(msg->client_id);
> > > > +             buf[idx] = 0;
> > > > +             buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
> > > > +             buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
> > > > +             buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
> > > > +             buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
> > > > +             idx++;
> > > > +             }
> > > > +             break;
> > > >       }
> > > >       raw->cur_len = idx;
> > > >  }
> > > > @@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
> > > >                               return -ENOMEM;
> > > >               }
> > > >               break;
> > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > +             req->u.enc_status.stream_id = buf[idx++];
> > > > +             for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
> > > > +                     req->u.enc_status.client_id[i] = buf[idx++];
> > > > +
> > > > +             req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
> > > > +                                                        buf[idx]);
> > > > +             req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
> > > > +                                                              buf[idx]);
> > > > +             req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
> > > > +                                                           buf[idx]);
> > > > +             req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
> > > > +                                                                 buf[idx]);
> > > > +             break;
> > > >       }
> > > >
> > > >       return 0;
> > > > @@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
> > > >                 req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
> > > >                 req->u.i2c_write.bytes);
> > > >               break;
> > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > +             P("stream_id=%u client_id=%*ph stream_event=%x "
> > > > +               "valid_event=%d stream_behavior=%x valid_behavior=%d",
> > > > +               req->u.enc_status.stream_id,
> > > > +               (int)ARRAY_SIZE(req->u.enc_status.client_id),
> > > > +               req->u.enc_status.client_id, req->u.enc_status.stream_event,
> > > > +               req->u.enc_status.valid_stream_event,
> > > > +               req->u.enc_status.stream_behavior,
> > > > +               req->u.enc_status.valid_stream_behavior);
> > > > +             break;
> > > >       default:
> > > >               P("???\n");
> > > >               break;
> > > > @@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
> > > >       return true;
> > > >  }
> > > >
> > > > +static bool
> > > > +drm_dp_sideband_parse_query_stream_enc_status(
> > > > +                             struct drm_dp_sideband_msg_rx *raw,
> > > > +                             struct drm_dp_sideband_msg_reply_body *repmsg)
> > > > +{
> > > > +     struct drm_dp_query_stream_enc_status_ack_reply *reply;
> > > > +
> > > > +     reply = &repmsg->u.enc_status;
> > > > +
> > > > +     reply->stream_id = raw->msg[3];
> It seems msg[0] is not part of reply data,
> could you help me with pointers, where msg is formatted.
> > > > +
> > > > +     reply->reply_signed = raw->msg[2] & BIT(0);
This whole patch looks good to me i could have given RB but i am having
some concerns regarding parsing of bits here.
reply_signed is 15th bit of reply message i.e MSB of msg[2] here.
it seems bit parsing is in reverse order in all places.
> > > > +
> > > > +     reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> > > > +     reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
But these two bits are not parse as reverse order, these are parse
as similar in DP specs, hdcp_1x 11th bit (bit 3 of msg[2]),
hdcp_2x 12th bit (bit 4 of msg[2]).
Please correct me if i am wrong here.
Thanks,
Anshuman Gupta.
> > > > +
> > > > +     reply->query_capable_device_present = raw->msg[2] & BIT(5);
> > > > +     reply->legacy_device_present = raw->msg[2] & BIT(6);
> > > > +     reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> > > > +
> > > > +     reply->auth_completed = !!(raw->msg[1] & BIT(3));

> > > > +     reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> > > > +     reply->repeater_present = !!(raw->msg[1] & BIT(5));
> > > > +     reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> > > > +
> > > > +     return true;
> > > > +}
> > > > +
> > > >  static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > > >                                       struct drm_dp_sideband_msg_reply_body *msg)
> > > >  {
> > > > @@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > > >               return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
> > > >       case DP_CLEAR_PAYLOAD_ID_TABLE:
> > > >               return true; /* since there's nothing to parse */
> > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > +             return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
> > > >       default:
> > > >               DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
> > > >                         drm_dp_mst_req_type_str(msg->req_type));
> > > > @@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
> > > >       msg->path_msg = true;
> > > >  }
> > > >
> > > > +static int
> > > > +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
> > > > +                           u8 *q_id)
> > > > +{
> > > > +     struct drm_dp_sideband_msg_req_body req;
> > > > +
> > > > +     req.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > > +     req.u.enc_status.stream_id = stream_id;
> > > > +     memcpy(req.u.enc_status.client_id, q_id,
> > > > +            sizeof(req.u.enc_status.client_id));
> > > > +     req.u.enc_status.stream_event = 0;
> > > > +     req.u.enc_status.valid_stream_event = false;
> > > > +     req.u.enc_status.stream_behavior = 0;
> > > > +     req.u.enc_status.valid_stream_behavior = false;
> > > > +
> > > > +     drm_dp_encode_sideband_req(&req, msg);
> > > > +     return 0;
> > > > +}
> > > > +
> > > >  static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
> > > >                                       struct drm_dp_vcpi *vcpi)
> > > >  {
> > > > @@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > >  }
> > > >  EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
> > > >
> > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > +             struct drm_dp_mst_port *port,
> > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status)
> > > > +{
> > > > +     struct drm_dp_sideband_msg_tx *txmsg;
> > > > +     u8 nonce[7];
> > > > +     int len, ret;
> > > > +
> > > > +     txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> > > > +     if (!txmsg)
> > > > +             return -ENOMEM;
> > > > +
> > > > +     port = drm_dp_mst_topology_get_port_validated(mgr, port);
> > > > +     if (!port) {
> > > > +             ret = -EINVAL;
> > > > +             goto out_get_port;
> > > > +     }
> > > > +
> > > > +     get_random_bytes(nonce, sizeof(nonce));
> > > > +
> > > > +     /*
> > > > +      * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
> > > > +      *  transaction at the MST Branch device directly connected to the
> > > > +      *  Source"
> > > > +      */
> > > > +     txmsg->dst = mgr->mst_primary;
> > > > +
> > > > +     len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
> > > > +
> > > > +     drm_dp_queue_down_tx(mgr, txmsg);
> > > > +
> > > > +     ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
> > > > +     if (ret < 0) {
> > > > +             goto out;
> > > > +     } else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
> > > > +             DRM_DEBUG_KMS("query encryption status nak received\n");
> > > > +             ret = -ENXIO;
> > > > +             goto out;
> > > > +     }
> > > > +
> > > > +     ret = 0;
> > > > +     memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
> > > > +
> > > > +out:
> > > > +     drm_dp_mst_topology_put_port(port);
> > > > +out_get_port:
> > > > +     kfree(txmsg);
> > > > +     return ret;
> > > > +}
> > > > +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
> > > > +
> > > >  static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
> > > >                                      int id,
> > > >                                      struct drm_dp_payload *payload)
> > > > diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > index bd990d178765..1d696ec001cf 100644
> > > > --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > @@ -5,6 +5,8 @@
> > > >
> > > >  #define PREFIX_STR "[drm_dp_mst_helper]"
> > > >
> > > > +#include <linux/random.h>
> > > > +
> > > >  #include <drm/drm_dp_mst_helper.h>
> > > >  #include <drm/drm_print.h>
> > > >
> > > > @@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
> > > >       in.u.i2c_write.bytes = data;
> > > >       DO_TEST();
> > > >
> > > > +     in.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > > +     in.u.enc_status.stream_id = 1;
> > > > +     DO_TEST();
> > > > +     get_random_bytes(in.u.enc_status.client_id,
> > > > +                      sizeof(in.u.enc_status.client_id));
> > > > +     DO_TEST();
> > > > +     in.u.enc_status.stream_event = 3;
> > > > +     DO_TEST();
> > > > +     in.u.enc_status.valid_stream_event = 0;
> > > > +     DO_TEST();
> > > > +     in.u.enc_status.stream_behavior = 3;
> > > > +     DO_TEST();
> > > > +     in.u.enc_status.valid_stream_behavior = 1;
> > > > +     DO_TEST();
> > > > +
> > > >  #undef DO_TEST
> > > >       return 0;
> > > >  }
> > > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > > > index e47dc22ebf50..e2d2df5e869e 100644
> > > > --- a/include/drm/drm_dp_helper.h
> > > > +++ b/include/drm/drm_dp_helper.h
> > > > @@ -1108,6 +1108,9 @@
> > > >  #define DP_POWER_DOWN_PHY            0x25
> > > >  #define DP_SINK_EVENT_NOTIFY         0x30
> > > >  #define DP_QUERY_STREAM_ENC_STATUS   0x38
> > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST   0
> > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE   1
> > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE     2
> > > >
> > > >  /* DP 1.2 MST sideband reply types */
> > > >  #define DP_SIDEBAND_REPLY_ACK                0x00
> > > > diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> > > > index 8b9eb4db3381..371eef8798ad 100644
> > > > --- a/include/drm/drm_dp_mst_helper.h
> > > > +++ b/include/drm/drm_dp_mst_helper.h
> > > > @@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
> > > >       u8 port_number;
> > > >  };
> > > >
> > > > +struct drm_dp_query_stream_enc_status_ack_reply {
> > > > +     /* Bit[23:16]- Stream Id */
> > > > +     u8 stream_id;
> > > > +
> > > > +     /* Bit[15]- Signed */
> > > > +     bool reply_signed;
> > > > +
> > > > +     /* Bit[10:8]- Stream Output Sink Type */
> > > > +     bool unauthorizable_device_present;
> > > > +     bool legacy_device_present;
> > > > +     bool query_capable_device_present;
> > > > +
> > > > +     /* Bit[12:11]- Stream Output CP Type */
> > > > +     bool hdcp_1x_device_present;
> > > > +     bool hdcp_2x_device_present;
> > > > +
> > > > +     /* Bit[4]- Stream Authentication */
> > > > +     bool auth_completed;
> > > > +
> > > > +     /* Bit[3]- Stream Encryption */
> > > > +     bool encryption_enabled;
> > > > +
> > > > +     /* Bit[2]- Stream Repeater Function Present */
> > > > +     bool repeater_present;
> > > > +
> > > > +     /* Bit[1:0]- Stream State */
> > > > +     u8 state;
> reply msg also has 20 byte of signature L' (HDCP 1.4),
> AFAIU it has lefted out for HDCP 2.2 implementation, which is of 32 bytes for HDCP 2.2.
> Please correct me if i am wrong here.
> Thanks,
> Anshuman Gupta.
> > > > +};
> > > >
> > > >  #define DRM_DP_MAX_SDP_STREAMS 16
> > > >  struct drm_dp_allocate_payload {
> > > > @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
> > > >       u8 *bytes;
> > > >  };
> > > >
> > > > +struct drm_dp_query_stream_enc_status {
> > > > +     u8 stream_id;
> > > > +     u8 client_id[7];        /* 56-bit nonce */
> > > > +     u8 stream_event;
> > > > +     bool valid_stream_event;
> > > > +     u8 stream_behavior;
> > > > +     u8 valid_stream_behavior;
> > > > +};
> > > > +
> > > >  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
> > > >  struct drm_dp_port_number_req {
> > > >       u8 port_number;
> > > > @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
> > > >
> > > >               struct drm_dp_remote_i2c_read i2c_read;
> > > >               struct drm_dp_remote_i2c_write i2c_write;
> > > > +
> > > > +             struct drm_dp_query_stream_enc_status enc_status;
> > > >       } u;
> > > >  };
> > > >
> > > > @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
> > > >               struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
> > > >               struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
> > > >               struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> > > > +
> > > > +             struct drm_dp_query_stream_enc_status_ack_reply enc_status;
> > > >       } u;
> > > >  };
> > > >
> > > > @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
> > > >                                struct drm_dp_mst_port *port);
> > > >  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > >                                struct drm_dp_mst_port *port, bool power_up);
> > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > +             struct drm_dp_mst_port *port,
> > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status);
> > > >  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
> > > >
> > > >  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> > > > --
> > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > >
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
  2020-07-02 14:37         ` Anshuman Gupta
@ 2020-08-11 14:43           ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-08-11 14:43 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On Thu, Jul 2, 2020 at 10:49 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
>
> On 2020-06-30 at 12:48:34 -0400, Sean Paul wrote:
> > On Tue, Jun 30, 2020 at 10:21 AM Anshuman Gupta
> > <anshuman.gupta@intel.com> wrote:
> > >

\snip

> > > > +static bool
> > > > +drm_dp_sideband_parse_query_stream_enc_status(
> > > > +                             struct drm_dp_sideband_msg_rx *raw,
> > > > +                             struct drm_dp_sideband_msg_reply_body *repmsg)
> > > > +{
> > > > +     struct drm_dp_query_stream_enc_status_ack_reply *reply;
> > > > +
> > > > +     reply = &repmsg->u.enc_status;
> > > > +
> > > > +     reply->stream_id = raw->msg[3];
> It seems msg[0] is not part of reply data,
> could you help me with pointers, where msg is formatted.

msg[0] is the reply type, see drm_dp_sideband_parse_reply()

> > > > +
> > > > +     reply->reply_signed = raw->msg[2] & BIT(0);
> > > > +
> > > > +     reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> > > > +     reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
> > > > +
> > > > +     reply->query_capable_device_present = raw->msg[2] & BIT(5);
> > > > +     reply->legacy_device_present = raw->msg[2] & BIT(6);
> > > > +     reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> > > > +
> > > > +     reply->auth_completed = !!(raw->msg[1] & BIT(3));
> > > > +     reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> > > > +     reply->repeater_present = !!(raw->msg[1] & BIT(5));
> > > > +     reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> > > > +
> > > > +     return true;
> > > > +}
> > > > +

/snip

> > > >
> > > > +struct drm_dp_query_stream_enc_status_ack_reply {
> > > > +     /* Bit[23:16]- Stream Id */
> > > > +     u8 stream_id;
> > > > +
> > > > +     /* Bit[15]- Signed */
> > > > +     bool reply_signed;
> > > > +
> > > > +     /* Bit[10:8]- Stream Output Sink Type */
> > > > +     bool unauthorizable_device_present;
> > > > +     bool legacy_device_present;
> > > > +     bool query_capable_device_present;
> > > > +
> > > > +     /* Bit[12:11]- Stream Output CP Type */
> > > > +     bool hdcp_1x_device_present;
> > > > +     bool hdcp_2x_device_present;
> > > > +
> > > > +     /* Bit[4]- Stream Authentication */
> > > > +     bool auth_completed;
> > > > +
> > > > +     /* Bit[3]- Stream Encryption */
> > > > +     bool encryption_enabled;
> > > > +
> > > > +     /* Bit[2]- Stream Repeater Function Present */
> > > > +     bool repeater_present;
> > > > +
> > > > +     /* Bit[1:0]- Stream State */
> > > > +     u8 state;
> reply msg also has 20 byte of signature L' (HDCP 1.4),

Yeah, I haven't done signature parsing because we simply can't. To
compute the signature we need Link_s, which maps to M0 in HDCP 1.4
terms. The Intel HDCP bspec states "M0 cannot be exposed to
software. It is kept internal to hardware". So it's impossible to
compute/verify on the host side.

Sean

> AFAIU it has lefted out for HDCP 2.2 implementation, which is of 32 bytes for HDCP 2.2.
> Please correct me if i am wrong here.
> Thanks,
> Anshuman Gupta.
> > > > +};
> > > >
> > > >  #define DRM_DP_MAX_SDP_STREAMS 16
> > > >  struct drm_dp_allocate_payload {
> > > > @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
> > > >       u8 *bytes;
> > > >  };
> > > >
> > > > +struct drm_dp_query_stream_enc_status {
> > > > +     u8 stream_id;
> > > > +     u8 client_id[7];        /* 56-bit nonce */
> > > > +     u8 stream_event;
> > > > +     bool valid_stream_event;
> > > > +     u8 stream_behavior;
> > > > +     u8 valid_stream_behavior;
> > > > +};
> > > > +
> > > >  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
> > > >  struct drm_dp_port_number_req {
> > > >       u8 port_number;
> > > > @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
> > > >
> > > >               struct drm_dp_remote_i2c_read i2c_read;
> > > >               struct drm_dp_remote_i2c_write i2c_write;
> > > > +
> > > > +             struct drm_dp_query_stream_enc_status enc_status;
> > > >       } u;
> > > >  };
> > > >
> > > > @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
> > > >               struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
> > > >               struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
> > > >               struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> > > > +
> > > > +             struct drm_dp_query_stream_enc_status_ack_reply enc_status;
> > > >       } u;
> > > >  };
> > > >
> > > > @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
> > > >                                struct drm_dp_mst_port *port);
> > > >  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > >                                struct drm_dp_mst_port *port, bool power_up);
> > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > +             struct drm_dp_mst_port *port,
> > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status);
> > > >  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
> > > >
> > > >  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> > > > --
> > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > >
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
@ 2020-08-11 14:43           ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-08-11 14:43 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On Thu, Jul 2, 2020 at 10:49 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
>
> On 2020-06-30 at 12:48:34 -0400, Sean Paul wrote:
> > On Tue, Jun 30, 2020 at 10:21 AM Anshuman Gupta
> > <anshuman.gupta@intel.com> wrote:
> > >

\snip

> > > > +static bool
> > > > +drm_dp_sideband_parse_query_stream_enc_status(
> > > > +                             struct drm_dp_sideband_msg_rx *raw,
> > > > +                             struct drm_dp_sideband_msg_reply_body *repmsg)
> > > > +{
> > > > +     struct drm_dp_query_stream_enc_status_ack_reply *reply;
> > > > +
> > > > +     reply = &repmsg->u.enc_status;
> > > > +
> > > > +     reply->stream_id = raw->msg[3];
> It seems msg[0] is not part of reply data,
> could you help me with pointers, where msg is formatted.

msg[0] is the reply type, see drm_dp_sideband_parse_reply()

> > > > +
> > > > +     reply->reply_signed = raw->msg[2] & BIT(0);
> > > > +
> > > > +     reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> > > > +     reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
> > > > +
> > > > +     reply->query_capable_device_present = raw->msg[2] & BIT(5);
> > > > +     reply->legacy_device_present = raw->msg[2] & BIT(6);
> > > > +     reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> > > > +
> > > > +     reply->auth_completed = !!(raw->msg[1] & BIT(3));
> > > > +     reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> > > > +     reply->repeater_present = !!(raw->msg[1] & BIT(5));
> > > > +     reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> > > > +
> > > > +     return true;
> > > > +}
> > > > +

/snip

> > > >
> > > > +struct drm_dp_query_stream_enc_status_ack_reply {
> > > > +     /* Bit[23:16]- Stream Id */
> > > > +     u8 stream_id;
> > > > +
> > > > +     /* Bit[15]- Signed */
> > > > +     bool reply_signed;
> > > > +
> > > > +     /* Bit[10:8]- Stream Output Sink Type */
> > > > +     bool unauthorizable_device_present;
> > > > +     bool legacy_device_present;
> > > > +     bool query_capable_device_present;
> > > > +
> > > > +     /* Bit[12:11]- Stream Output CP Type */
> > > > +     bool hdcp_1x_device_present;
> > > > +     bool hdcp_2x_device_present;
> > > > +
> > > > +     /* Bit[4]- Stream Authentication */
> > > > +     bool auth_completed;
> > > > +
> > > > +     /* Bit[3]- Stream Encryption */
> > > > +     bool encryption_enabled;
> > > > +
> > > > +     /* Bit[2]- Stream Repeater Function Present */
> > > > +     bool repeater_present;
> > > > +
> > > > +     /* Bit[1:0]- Stream State */
> > > > +     u8 state;
> reply msg also has 20 byte of signature L' (HDCP 1.4),

Yeah, I haven't done signature parsing because we simply can't. To
compute the signature we need Link_s, which maps to M0 in HDCP 1.4
terms. The Intel HDCP bspec states "M0 cannot be exposed to
software. It is kept internal to hardware". So it's impossible to
compute/verify on the host side.

Sean

> AFAIU it has lefted out for HDCP 2.2 implementation, which is of 32 bytes for HDCP 2.2.
> Please correct me if i am wrong here.
> Thanks,
> Anshuman Gupta.
> > > > +};
> > > >
> > > >  #define DRM_DP_MAX_SDP_STREAMS 16
> > > >  struct drm_dp_allocate_payload {
> > > > @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
> > > >       u8 *bytes;
> > > >  };
> > > >
> > > > +struct drm_dp_query_stream_enc_status {
> > > > +     u8 stream_id;
> > > > +     u8 client_id[7];        /* 56-bit nonce */
> > > > +     u8 stream_event;
> > > > +     bool valid_stream_event;
> > > > +     u8 stream_behavior;
> > > > +     u8 valid_stream_behavior;
> > > > +};
> > > > +
> > > >  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
> > > >  struct drm_dp_port_number_req {
> > > >       u8 port_number;
> > > > @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
> > > >
> > > >               struct drm_dp_remote_i2c_read i2c_read;
> > > >               struct drm_dp_remote_i2c_write i2c_write;
> > > > +
> > > > +             struct drm_dp_query_stream_enc_status enc_status;
> > > >       } u;
> > > >  };
> > > >
> > > > @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
> > > >               struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
> > > >               struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
> > > >               struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> > > > +
> > > > +             struct drm_dp_query_stream_enc_status_ack_reply enc_status;
> > > >       } u;
> > > >  };
> > > >
> > > > @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
> > > >                                struct drm_dp_mst_port *port);
> > > >  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > >                                struct drm_dp_mst_port *port, bool power_up);
> > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > +             struct drm_dp_mst_port *port,
> > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status);
> > > >  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
> > > >
> > > >  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> > > > --
> > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > >
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
  2020-07-09 12:58           ` Anshuman Gupta
@ 2020-08-11 17:21             ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-08-11 17:21 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On Thu, Jul 9, 2020 at 9:09 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
>
> On 2020-07-02 at 20:07:36 +0530, Anshuman Gupta wrote:
> > On 2020-06-30 at 12:48:34 -0400, Sean Paul wrote:
> > > On Tue, Jun 30, 2020 at 10:21 AM Anshuman Gupta
> > > <anshuman.gupta@intel.com> wrote:
> > > >
> > > > On 2020-06-23 at 21:29:05 +0530, Sean Paul wrote:
> > > > Hi Sean,
> > > > I am new to DP MST stuff, I am looking to DP MST spec DP v1.2a.
> > > > I have looked the entire series, i will take up this opportunity to review
> > > > the series from HDCP over DP MST POV.
> > > > I think theoretically this series should work or Gen12 as well, as DP MST streams
> > > > are getting encrypted by QUERY_STREAM_ENCRYPTION_STATUS reply tranaction msg
> > > > (generating Stream State Signature L’).
> > > > I will test this on Gen12 H/W with DP MST support and will provide my inputs.
> > > >
> > > > Meanwhile while going through DP MST v1.2a specs(Page 262) came to know about
> > > > a DP irq vector LINK_SERVICE_IRQ_VECTOR_ESI0 (02005h),
> > > > Bit 2 : STREAM_STATUS_CHANGED.
> > > > When this bit set to ‘1’ indicates the source must re-check the Stream Status
> > > > with the QUERY_STREAM_ENCRYPTION_STATUS message.
> > > > Currently i feel this irq support is missing, do we require to support
> > > > above IRQ vector for DP MST stream encryption.
> > > >
> > >
> > > Hi Anshuman,
> > > Thank you for your comments.
> > >
> > > QUERY_STREAM_ENCRYPTION_STATUS is not necessary for HDCP 1.x, I added
> > > this as a safety check to ensure that the streams were being
> > > encrypted. As such, the existing integrity checks in place for DP are
> > > sufficient to satisfy spec. When HDCP 2.2 support is added for MST,
> > > handling QSES will need to be addressed to meet spec. Note also that
> > > we're not validating the QSES signature for the same reason.
> > Thanks sean for the explanation,
> > overall patch looks good to me but i have couple of doubt see below.
> > >
> > > Sean
> > >
> > >
> > > > Thanks,
> > > > Anshuman Gupta.
> > > >
> > > > > From: Sean Paul <seanpaul@chromium.org>
> > > > >
> > > > > Used to query whether an MST stream is encrypted or not.
> > > > >
> > > > > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > > > >
> > > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
> > > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
> > > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6
> > > > >
> > > > > Changes in v4:
> > > > > -Added to the set
> > > > > Changes in v5:
> > > > > -None
> > > > > Changes in v6:
> > > > > -Use FIELD_PREP to generate request buffer bitfields (Lyude)
> > > > > -Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
> > > > > Changes in v7:
> > > > > -None
> > > > > ---
> > > > >  drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
> > > > >  .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
> > > > >  include/drm/drm_dp_helper.h                   |   3 +
> > > > >  include/drm/drm_dp_mst_helper.h               |  44 ++++++
> > > > >  4 files changed, 206 insertions(+)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > > index b2f5a84b4cfb..fc68478eaeb4 100644
> > > > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > > @@ -20,11 +20,13 @@
> > > > >   * OF THIS SOFTWARE.
> > > > >   */
> > > > >
> > > > > +#include <linux/bitfield.h>
> > > > >  #include <linux/delay.h>
> > > > >  #include <linux/errno.h>
> > > > >  #include <linux/i2c.h>
> > > > >  #include <linux/init.h>
> > > > >  #include <linux/kernel.h>
> > > > > +#include <linux/random.h>
> > > > >  #include <linux/sched.h>
> > > > >  #include <linux/seq_file.h>
> > > > >  #include <linux/iopoll.h>
> > > > > @@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
> > > > >               memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
> > > > >               idx += req->u.i2c_write.num_bytes;
> > > > >               break;
> > > > > +     case DP_QUERY_STREAM_ENC_STATUS: {
> > > > > +             const struct drm_dp_query_stream_enc_status *msg;
> > > > > +
> > > > > +             msg = &req->u.enc_status;
> > > > > +             buf[idx] = msg->stream_id;
> > > > > +             idx++;
> > > > > +             memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
> > > > > +             idx += sizeof(msg->client_id);
> > > > > +             buf[idx] = 0;
> > > > > +             buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
> > > > > +             buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
> > > > > +             buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
> > > > > +             buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
> > > > > +             idx++;
> > > > > +             }
> > > > > +             break;
> > > > >       }
> > > > >       raw->cur_len = idx;
> > > > >  }
> > > > > @@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
> > > > >                               return -ENOMEM;
> > > > >               }
> > > > >               break;
> > > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > > +             req->u.enc_status.stream_id = buf[idx++];
> > > > > +             for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
> > > > > +                     req->u.enc_status.client_id[i] = buf[idx++];
> > > > > +
> > > > > +             req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
> > > > > +                                                        buf[idx]);
> > > > > +             req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
> > > > > +                                                              buf[idx]);
> > > > > +             req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
> > > > > +                                                           buf[idx]);
> > > > > +             req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
> > > > > +                                                                 buf[idx]);
> > > > > +             break;
> > > > >       }
> > > > >
> > > > >       return 0;
> > > > > @@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
> > > > >                 req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
> > > > >                 req->u.i2c_write.bytes);
> > > > >               break;
> > > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > > +             P("stream_id=%u client_id=%*ph stream_event=%x "
> > > > > +               "valid_event=%d stream_behavior=%x valid_behavior=%d",
> > > > > +               req->u.enc_status.stream_id,
> > > > > +               (int)ARRAY_SIZE(req->u.enc_status.client_id),
> > > > > +               req->u.enc_status.client_id, req->u.enc_status.stream_event,
> > > > > +               req->u.enc_status.valid_stream_event,
> > > > > +               req->u.enc_status.stream_behavior,
> > > > > +               req->u.enc_status.valid_stream_behavior);
> > > > > +             break;
> > > > >       default:
> > > > >               P("???\n");
> > > > >               break;
> > > > > @@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
> > > > >       return true;
> > > > >  }
> > > > >
> > > > > +static bool
> > > > > +drm_dp_sideband_parse_query_stream_enc_status(
> > > > > +                             struct drm_dp_sideband_msg_rx *raw,
> > > > > +                             struct drm_dp_sideband_msg_reply_body *repmsg)
> > > > > +{
> > > > > +     struct drm_dp_query_stream_enc_status_ack_reply *reply;
> > > > > +
> > > > > +     reply = &repmsg->u.enc_status;
> > > > > +
> > > > > +     reply->stream_id = raw->msg[3];
> > It seems msg[0] is not part of reply data,
> > could you help me with pointers, where msg is formatted.
> > > > > +
> > > > > +     reply->reply_signed = raw->msg[2] & BIT(0);
> This whole patch looks good to me i could have given RB but i am having
> some concerns regarding parsing of bits here.
> reply_signed is 15th bit of reply message i.e MSB of msg[2] here.
> it seems bit parsing is in reverse order in all places.
> > > > > +
> > > > > +     reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> > > > > +     reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
> But these two bits are not parse as reverse order, these are parse
> as similar in DP specs, hdcp_1x 11th bit (bit 3 of msg[2]),
> hdcp_2x 12th bit (bit 4 of msg[2]).
> Please correct me if i am wrong here.

I'm not really sure what to make of this field since when I connect a
display which only supports HDCP 1.x (no HDCP 2.x), I get:

msg[2][4:3] = 01b

I've reproduced this with multiple hubs. I don't have an HDCP 2.x
display, so I can't reproduce to see if the other bit lights up under
those conditions.

We're not using these fields at the moment, so I suppose I can switch
them around and leave a comment in case someone notices weirdness.

Sean



> Thanks,
> Anshuman Gupta.
> > > > > +
> > > > > +     reply->query_capable_device_present = raw->msg[2] & BIT(5);
> > > > > +     reply->legacy_device_present = raw->msg[2] & BIT(6);
> > > > > +     reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> > > > > +
> > > > > +     reply->auth_completed = !!(raw->msg[1] & BIT(3));
>
> > > > > +     reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> > > > > +     reply->repeater_present = !!(raw->msg[1] & BIT(5));
> > > > > +     reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> > > > > +
> > > > > +     return true;
> > > > > +}
> > > > > +
> > > > >  static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > > > >                                       struct drm_dp_sideband_msg_reply_body *msg)
> > > > >  {
> > > > > @@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > > > >               return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
> > > > >       case DP_CLEAR_PAYLOAD_ID_TABLE:
> > > > >               return true; /* since there's nothing to parse */
> > > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > > +             return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
> > > > >       default:
> > > > >               DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
> > > > >                         drm_dp_mst_req_type_str(msg->req_type));
> > > > > @@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
> > > > >       msg->path_msg = true;
> > > > >  }
> > > > >
> > > > > +static int
> > > > > +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
> > > > > +                           u8 *q_id)
> > > > > +{
> > > > > +     struct drm_dp_sideband_msg_req_body req;
> > > > > +
> > > > > +     req.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > > > +     req.u.enc_status.stream_id = stream_id;
> > > > > +     memcpy(req.u.enc_status.client_id, q_id,
> > > > > +            sizeof(req.u.enc_status.client_id));
> > > > > +     req.u.enc_status.stream_event = 0;
> > > > > +     req.u.enc_status.valid_stream_event = false;
> > > > > +     req.u.enc_status.stream_behavior = 0;
> > > > > +     req.u.enc_status.valid_stream_behavior = false;
> > > > > +
> > > > > +     drm_dp_encode_sideband_req(&req, msg);
> > > > > +     return 0;
> > > > > +}
> > > > > +
> > > > >  static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
> > > > >                                       struct drm_dp_vcpi *vcpi)
> > > > >  {
> > > > > @@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > > >  }
> > > > >  EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
> > > > >
> > > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > > +             struct drm_dp_mst_port *port,
> > > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status)
> > > > > +{
> > > > > +     struct drm_dp_sideband_msg_tx *txmsg;
> > > > > +     u8 nonce[7];
> > > > > +     int len, ret;
> > > > > +
> > > > > +     txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> > > > > +     if (!txmsg)
> > > > > +             return -ENOMEM;
> > > > > +
> > > > > +     port = drm_dp_mst_topology_get_port_validated(mgr, port);
> > > > > +     if (!port) {
> > > > > +             ret = -EINVAL;
> > > > > +             goto out_get_port;
> > > > > +     }
> > > > > +
> > > > > +     get_random_bytes(nonce, sizeof(nonce));
> > > > > +
> > > > > +     /*
> > > > > +      * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
> > > > > +      *  transaction at the MST Branch device directly connected to the
> > > > > +      *  Source"
> > > > > +      */
> > > > > +     txmsg->dst = mgr->mst_primary;
> > > > > +
> > > > > +     len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
> > > > > +
> > > > > +     drm_dp_queue_down_tx(mgr, txmsg);
> > > > > +
> > > > > +     ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
> > > > > +     if (ret < 0) {
> > > > > +             goto out;
> > > > > +     } else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
> > > > > +             DRM_DEBUG_KMS("query encryption status nak received\n");
> > > > > +             ret = -ENXIO;
> > > > > +             goto out;
> > > > > +     }
> > > > > +
> > > > > +     ret = 0;
> > > > > +     memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
> > > > > +
> > > > > +out:
> > > > > +     drm_dp_mst_topology_put_port(port);
> > > > > +out_get_port:
> > > > > +     kfree(txmsg);
> > > > > +     return ret;
> > > > > +}
> > > > > +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
> > > > > +
> > > > >  static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
> > > > >                                      int id,
> > > > >                                      struct drm_dp_payload *payload)
> > > > > diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > > index bd990d178765..1d696ec001cf 100644
> > > > > --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > > +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > > @@ -5,6 +5,8 @@
> > > > >
> > > > >  #define PREFIX_STR "[drm_dp_mst_helper]"
> > > > >
> > > > > +#include <linux/random.h>
> > > > > +
> > > > >  #include <drm/drm_dp_mst_helper.h>
> > > > >  #include <drm/drm_print.h>
> > > > >
> > > > > @@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
> > > > >       in.u.i2c_write.bytes = data;
> > > > >       DO_TEST();
> > > > >
> > > > > +     in.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > > > +     in.u.enc_status.stream_id = 1;
> > > > > +     DO_TEST();
> > > > > +     get_random_bytes(in.u.enc_status.client_id,
> > > > > +                      sizeof(in.u.enc_status.client_id));
> > > > > +     DO_TEST();
> > > > > +     in.u.enc_status.stream_event = 3;
> > > > > +     DO_TEST();
> > > > > +     in.u.enc_status.valid_stream_event = 0;
> > > > > +     DO_TEST();
> > > > > +     in.u.enc_status.stream_behavior = 3;
> > > > > +     DO_TEST();
> > > > > +     in.u.enc_status.valid_stream_behavior = 1;
> > > > > +     DO_TEST();
> > > > > +
> > > > >  #undef DO_TEST
> > > > >       return 0;
> > > > >  }
> > > > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > > > > index e47dc22ebf50..e2d2df5e869e 100644
> > > > > --- a/include/drm/drm_dp_helper.h
> > > > > +++ b/include/drm/drm_dp_helper.h
> > > > > @@ -1108,6 +1108,9 @@
> > > > >  #define DP_POWER_DOWN_PHY            0x25
> > > > >  #define DP_SINK_EVENT_NOTIFY         0x30
> > > > >  #define DP_QUERY_STREAM_ENC_STATUS   0x38
> > > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST   0
> > > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE   1
> > > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE     2
> > > > >
> > > > >  /* DP 1.2 MST sideband reply types */
> > > > >  #define DP_SIDEBAND_REPLY_ACK                0x00
> > > > > diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> > > > > index 8b9eb4db3381..371eef8798ad 100644
> > > > > --- a/include/drm/drm_dp_mst_helper.h
> > > > > +++ b/include/drm/drm_dp_mst_helper.h
> > > > > @@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
> > > > >       u8 port_number;
> > > > >  };
> > > > >
> > > > > +struct drm_dp_query_stream_enc_status_ack_reply {
> > > > > +     /* Bit[23:16]- Stream Id */
> > > > > +     u8 stream_id;
> > > > > +
> > > > > +     /* Bit[15]- Signed */
> > > > > +     bool reply_signed;
> > > > > +
> > > > > +     /* Bit[10:8]- Stream Output Sink Type */
> > > > > +     bool unauthorizable_device_present;
> > > > > +     bool legacy_device_present;
> > > > > +     bool query_capable_device_present;
> > > > > +
> > > > > +     /* Bit[12:11]- Stream Output CP Type */
> > > > > +     bool hdcp_1x_device_present;
> > > > > +     bool hdcp_2x_device_present;
> > > > > +
> > > > > +     /* Bit[4]- Stream Authentication */
> > > > > +     bool auth_completed;
> > > > > +
> > > > > +     /* Bit[3]- Stream Encryption */
> > > > > +     bool encryption_enabled;
> > > > > +
> > > > > +     /* Bit[2]- Stream Repeater Function Present */
> > > > > +     bool repeater_present;
> > > > > +
> > > > > +     /* Bit[1:0]- Stream State */
> > > > > +     u8 state;
> > reply msg also has 20 byte of signature L' (HDCP 1.4),
> > AFAIU it has lefted out for HDCP 2.2 implementation, which is of 32 bytes for HDCP 2.2.
> > Please correct me if i am wrong here.
> > Thanks,
> > Anshuman Gupta.
> > > > > +};
> > > > >
> > > > >  #define DRM_DP_MAX_SDP_STREAMS 16
> > > > >  struct drm_dp_allocate_payload {
> > > > > @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
> > > > >       u8 *bytes;
> > > > >  };
> > > > >
> > > > > +struct drm_dp_query_stream_enc_status {
> > > > > +     u8 stream_id;
> > > > > +     u8 client_id[7];        /* 56-bit nonce */
> > > > > +     u8 stream_event;
> > > > > +     bool valid_stream_event;
> > > > > +     u8 stream_behavior;
> > > > > +     u8 valid_stream_behavior;
> > > > > +};
> > > > > +
> > > > >  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
> > > > >  struct drm_dp_port_number_req {
> > > > >       u8 port_number;
> > > > > @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
> > > > >
> > > > >               struct drm_dp_remote_i2c_read i2c_read;
> > > > >               struct drm_dp_remote_i2c_write i2c_write;
> > > > > +
> > > > > +             struct drm_dp_query_stream_enc_status enc_status;
> > > > >       } u;
> > > > >  };
> > > > >
> > > > > @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
> > > > >               struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
> > > > >               struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
> > > > >               struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> > > > > +
> > > > > +             struct drm_dp_query_stream_enc_status_ack_reply enc_status;
> > > > >       } u;
> > > > >  };
> > > > >
> > > > > @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
> > > > >                                struct drm_dp_mst_port *port);
> > > > >  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > > >                                struct drm_dp_mst_port *port, bool power_up);
> > > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > > +             struct drm_dp_mst_port *port,
> > > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status);
> > > > >  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
> > > > >
> > > > >  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> > > > > --
> > > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > > >
> > > > > _______________________________________________
> > > > > Intel-gfx mailing list
> > > > > Intel-gfx@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
@ 2020-08-11 17:21             ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-08-11 17:21 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On Thu, Jul 9, 2020 at 9:09 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
>
> On 2020-07-02 at 20:07:36 +0530, Anshuman Gupta wrote:
> > On 2020-06-30 at 12:48:34 -0400, Sean Paul wrote:
> > > On Tue, Jun 30, 2020 at 10:21 AM Anshuman Gupta
> > > <anshuman.gupta@intel.com> wrote:
> > > >
> > > > On 2020-06-23 at 21:29:05 +0530, Sean Paul wrote:
> > > > Hi Sean,
> > > > I am new to DP MST stuff, I am looking to DP MST spec DP v1.2a.
> > > > I have looked the entire series, i will take up this opportunity to review
> > > > the series from HDCP over DP MST POV.
> > > > I think theoretically this series should work or Gen12 as well, as DP MST streams
> > > > are getting encrypted by QUERY_STREAM_ENCRYPTION_STATUS reply tranaction msg
> > > > (generating Stream State Signature L’).
> > > > I will test this on Gen12 H/W with DP MST support and will provide my inputs.
> > > >
> > > > Meanwhile while going through DP MST v1.2a specs(Page 262) came to know about
> > > > a DP irq vector LINK_SERVICE_IRQ_VECTOR_ESI0 (02005h),
> > > > Bit 2 : STREAM_STATUS_CHANGED.
> > > > When this bit set to ‘1’ indicates the source must re-check the Stream Status
> > > > with the QUERY_STREAM_ENCRYPTION_STATUS message.
> > > > Currently i feel this irq support is missing, do we require to support
> > > > above IRQ vector for DP MST stream encryption.
> > > >
> > >
> > > Hi Anshuman,
> > > Thank you for your comments.
> > >
> > > QUERY_STREAM_ENCRYPTION_STATUS is not necessary for HDCP 1.x, I added
> > > this as a safety check to ensure that the streams were being
> > > encrypted. As such, the existing integrity checks in place for DP are
> > > sufficient to satisfy spec. When HDCP 2.2 support is added for MST,
> > > handling QSES will need to be addressed to meet spec. Note also that
> > > we're not validating the QSES signature for the same reason.
> > Thanks sean for the explanation,
> > overall patch looks good to me but i have couple of doubt see below.
> > >
> > > Sean
> > >
> > >
> > > > Thanks,
> > > > Anshuman Gupta.
> > > >
> > > > > From: Sean Paul <seanpaul@chromium.org>
> > > > >
> > > > > Used to query whether an MST stream is encrypted or not.
> > > > >
> > > > > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > > > >
> > > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
> > > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
> > > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6
> > > > >
> > > > > Changes in v4:
> > > > > -Added to the set
> > > > > Changes in v5:
> > > > > -None
> > > > > Changes in v6:
> > > > > -Use FIELD_PREP to generate request buffer bitfields (Lyude)
> > > > > -Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
> > > > > Changes in v7:
> > > > > -None
> > > > > ---
> > > > >  drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
> > > > >  .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
> > > > >  include/drm/drm_dp_helper.h                   |   3 +
> > > > >  include/drm/drm_dp_mst_helper.h               |  44 ++++++
> > > > >  4 files changed, 206 insertions(+)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > > index b2f5a84b4cfb..fc68478eaeb4 100644
> > > > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > > @@ -20,11 +20,13 @@
> > > > >   * OF THIS SOFTWARE.
> > > > >   */
> > > > >
> > > > > +#include <linux/bitfield.h>
> > > > >  #include <linux/delay.h>
> > > > >  #include <linux/errno.h>
> > > > >  #include <linux/i2c.h>
> > > > >  #include <linux/init.h>
> > > > >  #include <linux/kernel.h>
> > > > > +#include <linux/random.h>
> > > > >  #include <linux/sched.h>
> > > > >  #include <linux/seq_file.h>
> > > > >  #include <linux/iopoll.h>
> > > > > @@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
> > > > >               memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
> > > > >               idx += req->u.i2c_write.num_bytes;
> > > > >               break;
> > > > > +     case DP_QUERY_STREAM_ENC_STATUS: {
> > > > > +             const struct drm_dp_query_stream_enc_status *msg;
> > > > > +
> > > > > +             msg = &req->u.enc_status;
> > > > > +             buf[idx] = msg->stream_id;
> > > > > +             idx++;
> > > > > +             memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
> > > > > +             idx += sizeof(msg->client_id);
> > > > > +             buf[idx] = 0;
> > > > > +             buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
> > > > > +             buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
> > > > > +             buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
> > > > > +             buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
> > > > > +             idx++;
> > > > > +             }
> > > > > +             break;
> > > > >       }
> > > > >       raw->cur_len = idx;
> > > > >  }
> > > > > @@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
> > > > >                               return -ENOMEM;
> > > > >               }
> > > > >               break;
> > > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > > +             req->u.enc_status.stream_id = buf[idx++];
> > > > > +             for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
> > > > > +                     req->u.enc_status.client_id[i] = buf[idx++];
> > > > > +
> > > > > +             req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
> > > > > +                                                        buf[idx]);
> > > > > +             req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
> > > > > +                                                              buf[idx]);
> > > > > +             req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
> > > > > +                                                           buf[idx]);
> > > > > +             req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
> > > > > +                                                                 buf[idx]);
> > > > > +             break;
> > > > >       }
> > > > >
> > > > >       return 0;
> > > > > @@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
> > > > >                 req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
> > > > >                 req->u.i2c_write.bytes);
> > > > >               break;
> > > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > > +             P("stream_id=%u client_id=%*ph stream_event=%x "
> > > > > +               "valid_event=%d stream_behavior=%x valid_behavior=%d",
> > > > > +               req->u.enc_status.stream_id,
> > > > > +               (int)ARRAY_SIZE(req->u.enc_status.client_id),
> > > > > +               req->u.enc_status.client_id, req->u.enc_status.stream_event,
> > > > > +               req->u.enc_status.valid_stream_event,
> > > > > +               req->u.enc_status.stream_behavior,
> > > > > +               req->u.enc_status.valid_stream_behavior);
> > > > > +             break;
> > > > >       default:
> > > > >               P("???\n");
> > > > >               break;
> > > > > @@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
> > > > >       return true;
> > > > >  }
> > > > >
> > > > > +static bool
> > > > > +drm_dp_sideband_parse_query_stream_enc_status(
> > > > > +                             struct drm_dp_sideband_msg_rx *raw,
> > > > > +                             struct drm_dp_sideband_msg_reply_body *repmsg)
> > > > > +{
> > > > > +     struct drm_dp_query_stream_enc_status_ack_reply *reply;
> > > > > +
> > > > > +     reply = &repmsg->u.enc_status;
> > > > > +
> > > > > +     reply->stream_id = raw->msg[3];
> > It seems msg[0] is not part of reply data,
> > could you help me with pointers, where msg is formatted.
> > > > > +
> > > > > +     reply->reply_signed = raw->msg[2] & BIT(0);
> This whole patch looks good to me i could have given RB but i am having
> some concerns regarding parsing of bits here.
> reply_signed is 15th bit of reply message i.e MSB of msg[2] here.
> it seems bit parsing is in reverse order in all places.
> > > > > +
> > > > > +     reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> > > > > +     reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
> But these two bits are not parse as reverse order, these are parse
> as similar in DP specs, hdcp_1x 11th bit (bit 3 of msg[2]),
> hdcp_2x 12th bit (bit 4 of msg[2]).
> Please correct me if i am wrong here.

I'm not really sure what to make of this field since when I connect a
display which only supports HDCP 1.x (no HDCP 2.x), I get:

msg[2][4:3] = 01b

I've reproduced this with multiple hubs. I don't have an HDCP 2.x
display, so I can't reproduce to see if the other bit lights up under
those conditions.

We're not using these fields at the moment, so I suppose I can switch
them around and leave a comment in case someone notices weirdness.

Sean



> Thanks,
> Anshuman Gupta.
> > > > > +
> > > > > +     reply->query_capable_device_present = raw->msg[2] & BIT(5);
> > > > > +     reply->legacy_device_present = raw->msg[2] & BIT(6);
> > > > > +     reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> > > > > +
> > > > > +     reply->auth_completed = !!(raw->msg[1] & BIT(3));
>
> > > > > +     reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> > > > > +     reply->repeater_present = !!(raw->msg[1] & BIT(5));
> > > > > +     reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> > > > > +
> > > > > +     return true;
> > > > > +}
> > > > > +
> > > > >  static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > > > >                                       struct drm_dp_sideband_msg_reply_body *msg)
> > > > >  {
> > > > > @@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > > > >               return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
> > > > >       case DP_CLEAR_PAYLOAD_ID_TABLE:
> > > > >               return true; /* since there's nothing to parse */
> > > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > > +             return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
> > > > >       default:
> > > > >               DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
> > > > >                         drm_dp_mst_req_type_str(msg->req_type));
> > > > > @@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
> > > > >       msg->path_msg = true;
> > > > >  }
> > > > >
> > > > > +static int
> > > > > +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
> > > > > +                           u8 *q_id)
> > > > > +{
> > > > > +     struct drm_dp_sideband_msg_req_body req;
> > > > > +
> > > > > +     req.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > > > +     req.u.enc_status.stream_id = stream_id;
> > > > > +     memcpy(req.u.enc_status.client_id, q_id,
> > > > > +            sizeof(req.u.enc_status.client_id));
> > > > > +     req.u.enc_status.stream_event = 0;
> > > > > +     req.u.enc_status.valid_stream_event = false;
> > > > > +     req.u.enc_status.stream_behavior = 0;
> > > > > +     req.u.enc_status.valid_stream_behavior = false;
> > > > > +
> > > > > +     drm_dp_encode_sideband_req(&req, msg);
> > > > > +     return 0;
> > > > > +}
> > > > > +
> > > > >  static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
> > > > >                                       struct drm_dp_vcpi *vcpi)
> > > > >  {
> > > > > @@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > > >  }
> > > > >  EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
> > > > >
> > > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > > +             struct drm_dp_mst_port *port,
> > > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status)
> > > > > +{
> > > > > +     struct drm_dp_sideband_msg_tx *txmsg;
> > > > > +     u8 nonce[7];
> > > > > +     int len, ret;
> > > > > +
> > > > > +     txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> > > > > +     if (!txmsg)
> > > > > +             return -ENOMEM;
> > > > > +
> > > > > +     port = drm_dp_mst_topology_get_port_validated(mgr, port);
> > > > > +     if (!port) {
> > > > > +             ret = -EINVAL;
> > > > > +             goto out_get_port;
> > > > > +     }
> > > > > +
> > > > > +     get_random_bytes(nonce, sizeof(nonce));
> > > > > +
> > > > > +     /*
> > > > > +      * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
> > > > > +      *  transaction at the MST Branch device directly connected to the
> > > > > +      *  Source"
> > > > > +      */
> > > > > +     txmsg->dst = mgr->mst_primary;
> > > > > +
> > > > > +     len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
> > > > > +
> > > > > +     drm_dp_queue_down_tx(mgr, txmsg);
> > > > > +
> > > > > +     ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
> > > > > +     if (ret < 0) {
> > > > > +             goto out;
> > > > > +     } else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
> > > > > +             DRM_DEBUG_KMS("query encryption status nak received\n");
> > > > > +             ret = -ENXIO;
> > > > > +             goto out;
> > > > > +     }
> > > > > +
> > > > > +     ret = 0;
> > > > > +     memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
> > > > > +
> > > > > +out:
> > > > > +     drm_dp_mst_topology_put_port(port);
> > > > > +out_get_port:
> > > > > +     kfree(txmsg);
> > > > > +     return ret;
> > > > > +}
> > > > > +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
> > > > > +
> > > > >  static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
> > > > >                                      int id,
> > > > >                                      struct drm_dp_payload *payload)
> > > > > diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > > index bd990d178765..1d696ec001cf 100644
> > > > > --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > > +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > > @@ -5,6 +5,8 @@
> > > > >
> > > > >  #define PREFIX_STR "[drm_dp_mst_helper]"
> > > > >
> > > > > +#include <linux/random.h>
> > > > > +
> > > > >  #include <drm/drm_dp_mst_helper.h>
> > > > >  #include <drm/drm_print.h>
> > > > >
> > > > > @@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
> > > > >       in.u.i2c_write.bytes = data;
> > > > >       DO_TEST();
> > > > >
> > > > > +     in.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > > > +     in.u.enc_status.stream_id = 1;
> > > > > +     DO_TEST();
> > > > > +     get_random_bytes(in.u.enc_status.client_id,
> > > > > +                      sizeof(in.u.enc_status.client_id));
> > > > > +     DO_TEST();
> > > > > +     in.u.enc_status.stream_event = 3;
> > > > > +     DO_TEST();
> > > > > +     in.u.enc_status.valid_stream_event = 0;
> > > > > +     DO_TEST();
> > > > > +     in.u.enc_status.stream_behavior = 3;
> > > > > +     DO_TEST();
> > > > > +     in.u.enc_status.valid_stream_behavior = 1;
> > > > > +     DO_TEST();
> > > > > +
> > > > >  #undef DO_TEST
> > > > >       return 0;
> > > > >  }
> > > > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > > > > index e47dc22ebf50..e2d2df5e869e 100644
> > > > > --- a/include/drm/drm_dp_helper.h
> > > > > +++ b/include/drm/drm_dp_helper.h
> > > > > @@ -1108,6 +1108,9 @@
> > > > >  #define DP_POWER_DOWN_PHY            0x25
> > > > >  #define DP_SINK_EVENT_NOTIFY         0x30
> > > > >  #define DP_QUERY_STREAM_ENC_STATUS   0x38
> > > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST   0
> > > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE   1
> > > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE     2
> > > > >
> > > > >  /* DP 1.2 MST sideband reply types */
> > > > >  #define DP_SIDEBAND_REPLY_ACK                0x00
> > > > > diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> > > > > index 8b9eb4db3381..371eef8798ad 100644
> > > > > --- a/include/drm/drm_dp_mst_helper.h
> > > > > +++ b/include/drm/drm_dp_mst_helper.h
> > > > > @@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
> > > > >       u8 port_number;
> > > > >  };
> > > > >
> > > > > +struct drm_dp_query_stream_enc_status_ack_reply {
> > > > > +     /* Bit[23:16]- Stream Id */
> > > > > +     u8 stream_id;
> > > > > +
> > > > > +     /* Bit[15]- Signed */
> > > > > +     bool reply_signed;
> > > > > +
> > > > > +     /* Bit[10:8]- Stream Output Sink Type */
> > > > > +     bool unauthorizable_device_present;
> > > > > +     bool legacy_device_present;
> > > > > +     bool query_capable_device_present;
> > > > > +
> > > > > +     /* Bit[12:11]- Stream Output CP Type */
> > > > > +     bool hdcp_1x_device_present;
> > > > > +     bool hdcp_2x_device_present;
> > > > > +
> > > > > +     /* Bit[4]- Stream Authentication */
> > > > > +     bool auth_completed;
> > > > > +
> > > > > +     /* Bit[3]- Stream Encryption */
> > > > > +     bool encryption_enabled;
> > > > > +
> > > > > +     /* Bit[2]- Stream Repeater Function Present */
> > > > > +     bool repeater_present;
> > > > > +
> > > > > +     /* Bit[1:0]- Stream State */
> > > > > +     u8 state;
> > reply msg also has 20 byte of signature L' (HDCP 1.4),
> > AFAIU it has lefted out for HDCP 2.2 implementation, which is of 32 bytes for HDCP 2.2.
> > Please correct me if i am wrong here.
> > Thanks,
> > Anshuman Gupta.
> > > > > +};
> > > > >
> > > > >  #define DRM_DP_MAX_SDP_STREAMS 16
> > > > >  struct drm_dp_allocate_payload {
> > > > > @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
> > > > >       u8 *bytes;
> > > > >  };
> > > > >
> > > > > +struct drm_dp_query_stream_enc_status {
> > > > > +     u8 stream_id;
> > > > > +     u8 client_id[7];        /* 56-bit nonce */
> > > > > +     u8 stream_event;
> > > > > +     bool valid_stream_event;
> > > > > +     u8 stream_behavior;
> > > > > +     u8 valid_stream_behavior;
> > > > > +};
> > > > > +
> > > > >  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
> > > > >  struct drm_dp_port_number_req {
> > > > >       u8 port_number;
> > > > > @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
> > > > >
> > > > >               struct drm_dp_remote_i2c_read i2c_read;
> > > > >               struct drm_dp_remote_i2c_write i2c_write;
> > > > > +
> > > > > +             struct drm_dp_query_stream_enc_status enc_status;
> > > > >       } u;
> > > > >  };
> > > > >
> > > > > @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
> > > > >               struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
> > > > >               struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
> > > > >               struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> > > > > +
> > > > > +             struct drm_dp_query_stream_enc_status_ack_reply enc_status;
> > > > >       } u;
> > > > >  };
> > > > >
> > > > > @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
> > > > >                                struct drm_dp_mst_port *port);
> > > > >  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > > >                                struct drm_dp_mst_port *port, bool power_up);
> > > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > > +             struct drm_dp_mst_port *port,
> > > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status);
> > > > >  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
> > > > >
> > > > >  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> > > > > --
> > > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > > >
> > > > > _______________________________________________
> > > > > Intel-gfx mailing list
> > > > > Intel-gfx@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
  2020-07-09 12:28       ` Anshuman Gupta
@ 2020-08-11 17:28         ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-08-11 17:28 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: intel-gfx, Sean Paul, dri-devel, daniel.vetter

On Thu, Jul 9, 2020 at 8:40 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
>

\snip

> > > +static int
> > > +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> > > +                               enum transcoder cpu_transcoder,
> > > +                               bool enable)
> > > +{
> > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > +   int ret;
> > > +
> > > +   if (!enable)
> > > +           usleep_range(6, 60); /* Bspec says >= 6us */
> > > +
> > > +   ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> > > +                                          cpu_transcoder, enable);
> > Sean,
> >
> > This function toggles the TRANS_DDI_HDCP_SIGNALLING (9th)bit of TRANS_DDI_FUNC_CTL(tran)
> > But in the hw specification this bit is mentioned to be ignored for non
> > HDMI/DVI modes of the TRANS DDI.
> >
> > Any reason why we need this? Did you try with out this function?
> >

Under "Authentication Part 1 for Multi-stream DisplayPort", bspec says:
2. Select HDCP for the desired stream using the Pipe DDI Function
Control register.

> > Apart from that Patch looks good to me.
> IMHO it seems we are still missing to enable the Multistream HDCP Select
> bit (5) in TRANS_DDI_FUNC_CTL register which is required to enable the
> stream encryption.
>

Could you send me some docs on this? I don't see have info on this bit.

Sean

> Thanks,
> Anshuman Gupta.
> >
> > -Ram
> >
> > > +   if (ret)
> > > +           drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> > > +                         enable ? "Enable" : "Disable", ret);
> > > +   return ret;
> > > +}
> > > +
> > > +static
> > > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> > > +                             struct intel_connector *connector)
> > > +{
> > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > +   struct intel_dp *intel_dp = &intel_dig_port->dp;
> > > +   struct drm_dp_query_stream_enc_status_ack_reply reply;
> > > +   int ret;
> > > +
> > > +   if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> > > +           return false;
> > > +
> > > +   ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> > > +                                             connector->port, &reply);
> > > +   if (ret) {
> > > +           drm_dbg_kms(&i915->drm,
> > > +                       "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> > > +                       connector->base.base.id, connector->base.name, ret);
> > > +           return false;
> > > +   }
> > > +
> > > +   return reply.auth_completed && reply.encryption_enabled;
> > > +}
> > > +
> > > +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> > > +   .write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > > +   .read_bksv = intel_dp_hdcp_read_bksv,
> > > +   .read_bstatus = intel_dp_hdcp_read_bstatus,
> > > +   .repeater_present = intel_dp_hdcp_repeater_present,
> > > +   .read_ri_prime = intel_dp_hdcp_read_ri_prime,
> > > +   .read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> > > +   .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> > > +   .read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> > > +   .toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> > > +   .check_link = intel_dp_mst_hdcp_check_link,
> > > +   .hdcp_capable = intel_dp_hdcp_capable,
> > > +
> > > +   .protocol = HDCP_PROTOCOL_DP,
> > > +};
> > > +
> > >  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > >                    struct intel_connector *intel_connector)
> > >  {
> > > @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > >     if (!is_hdcp_supported(dev_priv, port))
> > >             return 0;
> > >
> > > -   if (!intel_dp_is_edp(intel_dp))
> > > +   if (intel_connector->mst_port)
> > > +           return intel_hdcp_init(intel_connector, port,
> > > +                                  &intel_dp_mst_hdcp_shim);
> > > +   else if (!intel_dp_is_edp(intel_dp))
> > >             return intel_hdcp_init(intel_connector, port,
> > >                                    &intel_dp_hdcp_shim);
> > >
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > index 0675825dcc20..abaaeeb963d2 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > @@ -37,6 +37,7 @@
> > >  #include "intel_dp.h"
> > >  #include "intel_dp_mst.h"
> > >  #include "intel_dpio_phy.h"
> > > +#include "intel_hdcp.h"
> > >
> > >  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > >                                         struct intel_crtc_state *crtc_state,
> > > @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
> > >     drm_dbg_kms(&i915->drm, "active links %d\n",
> > >                 intel_dp->active_mst_links);
> > >
> > > +   intel_hdcp_disable(intel_mst->connector);
> > > +
> > >     drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
> > >
> > >     ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> > > @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
> > >
> > >     if (pipe_config->has_audio)
> > >             intel_audio_codec_enable(encoder, pipe_config, conn_state);
> > > +
> > > +   /* Enable hdcp if it's desired */
> > > +   if (conn_state->content_protection ==
> > > +       DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > > +           intel_hdcp_enable(to_intel_connector(conn_state->connector),
> > > +                             pipe_config->cpu_transcoder,
> > > +                             (u8)conn_state->hdcp_content_type);
> > >  }
> > >
> > >  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> > > @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
> > >     intel_attach_force_audio_property(connector);
> > >     intel_attach_broadcast_rgb_property(connector);
> > >
> > > +
> > > +   /* TODO: Figure out how to make HDCP work on GEN12+ */
> > > +   if (INTEL_GEN(dev_priv) < 12) {
> > > +           ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> > > +           if (ret)
> > > +                   DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> > > +   }
> > > +
> > >     /*
> > >      * Reuse the prop from the SST connector because we're
> > >      * not allowed to create new props after device registration.
> > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > index 6bd0e4616ee1..ddc9db8de2bc 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
> > >     if (!shim)
> > >             return -EINVAL;
> > >
> > > -   if (is_hdcp2_supported(dev_priv))
> > > +   if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
> > >             intel_hdcp2_init(connector, port, shim);
> > >
> > >     ret =
> > > --
> > > Sean Paul, Software Engineer, Google / Chromium OS
> > >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
@ 2020-08-11 17:28         ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-08-11 17:28 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: intel-gfx, Sean Paul, dri-devel, daniel.vetter

On Thu, Jul 9, 2020 at 8:40 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
>

\snip

> > > +static int
> > > +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> > > +                               enum transcoder cpu_transcoder,
> > > +                               bool enable)
> > > +{
> > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > +   int ret;
> > > +
> > > +   if (!enable)
> > > +           usleep_range(6, 60); /* Bspec says >= 6us */
> > > +
> > > +   ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> > > +                                          cpu_transcoder, enable);
> > Sean,
> >
> > This function toggles the TRANS_DDI_HDCP_SIGNALLING (9th)bit of TRANS_DDI_FUNC_CTL(tran)
> > But in the hw specification this bit is mentioned to be ignored for non
> > HDMI/DVI modes of the TRANS DDI.
> >
> > Any reason why we need this? Did you try with out this function?
> >

Under "Authentication Part 1 for Multi-stream DisplayPort", bspec says:
2. Select HDCP for the desired stream using the Pipe DDI Function
Control register.

> > Apart from that Patch looks good to me.
> IMHO it seems we are still missing to enable the Multistream HDCP Select
> bit (5) in TRANS_DDI_FUNC_CTL register which is required to enable the
> stream encryption.
>

Could you send me some docs on this? I don't see have info on this bit.

Sean

> Thanks,
> Anshuman Gupta.
> >
> > -Ram
> >
> > > +   if (ret)
> > > +           drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> > > +                         enable ? "Enable" : "Disable", ret);
> > > +   return ret;
> > > +}
> > > +
> > > +static
> > > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> > > +                             struct intel_connector *connector)
> > > +{
> > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > +   struct intel_dp *intel_dp = &intel_dig_port->dp;
> > > +   struct drm_dp_query_stream_enc_status_ack_reply reply;
> > > +   int ret;
> > > +
> > > +   if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> > > +           return false;
> > > +
> > > +   ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> > > +                                             connector->port, &reply);
> > > +   if (ret) {
> > > +           drm_dbg_kms(&i915->drm,
> > > +                       "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> > > +                       connector->base.base.id, connector->base.name, ret);
> > > +           return false;
> > > +   }
> > > +
> > > +   return reply.auth_completed && reply.encryption_enabled;
> > > +}
> > > +
> > > +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> > > +   .write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > > +   .read_bksv = intel_dp_hdcp_read_bksv,
> > > +   .read_bstatus = intel_dp_hdcp_read_bstatus,
> > > +   .repeater_present = intel_dp_hdcp_repeater_present,
> > > +   .read_ri_prime = intel_dp_hdcp_read_ri_prime,
> > > +   .read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> > > +   .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> > > +   .read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> > > +   .toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> > > +   .check_link = intel_dp_mst_hdcp_check_link,
> > > +   .hdcp_capable = intel_dp_hdcp_capable,
> > > +
> > > +   .protocol = HDCP_PROTOCOL_DP,
> > > +};
> > > +
> > >  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > >                    struct intel_connector *intel_connector)
> > >  {
> > > @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > >     if (!is_hdcp_supported(dev_priv, port))
> > >             return 0;
> > >
> > > -   if (!intel_dp_is_edp(intel_dp))
> > > +   if (intel_connector->mst_port)
> > > +           return intel_hdcp_init(intel_connector, port,
> > > +                                  &intel_dp_mst_hdcp_shim);
> > > +   else if (!intel_dp_is_edp(intel_dp))
> > >             return intel_hdcp_init(intel_connector, port,
> > >                                    &intel_dp_hdcp_shim);
> > >
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > index 0675825dcc20..abaaeeb963d2 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > @@ -37,6 +37,7 @@
> > >  #include "intel_dp.h"
> > >  #include "intel_dp_mst.h"
> > >  #include "intel_dpio_phy.h"
> > > +#include "intel_hdcp.h"
> > >
> > >  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > >                                         struct intel_crtc_state *crtc_state,
> > > @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
> > >     drm_dbg_kms(&i915->drm, "active links %d\n",
> > >                 intel_dp->active_mst_links);
> > >
> > > +   intel_hdcp_disable(intel_mst->connector);
> > > +
> > >     drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
> > >
> > >     ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> > > @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
> > >
> > >     if (pipe_config->has_audio)
> > >             intel_audio_codec_enable(encoder, pipe_config, conn_state);
> > > +
> > > +   /* Enable hdcp if it's desired */
> > > +   if (conn_state->content_protection ==
> > > +       DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > > +           intel_hdcp_enable(to_intel_connector(conn_state->connector),
> > > +                             pipe_config->cpu_transcoder,
> > > +                             (u8)conn_state->hdcp_content_type);
> > >  }
> > >
> > >  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> > > @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
> > >     intel_attach_force_audio_property(connector);
> > >     intel_attach_broadcast_rgb_property(connector);
> > >
> > > +
> > > +   /* TODO: Figure out how to make HDCP work on GEN12+ */
> > > +   if (INTEL_GEN(dev_priv) < 12) {
> > > +           ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> > > +           if (ret)
> > > +                   DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> > > +   }
> > > +
> > >     /*
> > >      * Reuse the prop from the SST connector because we're
> > >      * not allowed to create new props after device registration.
> > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > index 6bd0e4616ee1..ddc9db8de2bc 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
> > >     if (!shim)
> > >             return -EINVAL;
> > >
> > > -   if (is_hdcp2_supported(dev_priv))
> > > +   if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
> > >             intel_hdcp2_init(connector, port, shim);
> > >
> > >     ret =
> > > --
> > > Sean Paul, Software Engineer, Google / Chromium OS
> > >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
  2020-08-11 17:28         ` Sean Paul
@ 2020-08-12  7:03           ` Anshuman Gupta
  -1 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-08-12  7:03 UTC (permalink / raw)
  To: Sean Paul; +Cc: intel-gfx, Sean Paul, dri-devel, daniel.vetter

On 2020-08-11 at 13:28:46 -0400, Sean Paul wrote:
> On Thu, Jul 9, 2020 at 8:40 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
> >
> 
> \snip
> 
> > > > +static int
> > > > +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> > > > +                               enum transcoder cpu_transcoder,
> > > > +                               bool enable)
> > > > +{
> > > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > > +   int ret;
> > > > +
> > > > +   if (!enable)
> > > > +           usleep_range(6, 60); /* Bspec says >= 6us */
> > > > +
> > > > +   ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> > > > +                                          cpu_transcoder, enable);
> > > Sean,
> > >
> > > This function toggles the TRANS_DDI_HDCP_SIGNALLING (9th)bit of TRANS_DDI_FUNC_CTL(tran)
> > > But in the hw specification this bit is mentioned to be ignored for non
> > > HDMI/DVI modes of the TRANS DDI.
> > >
> > > Any reason why we need this? Did you try with out this function?
> > >
> 
> Under "Authentication Part 1 for Multi-stream DisplayPort", bspec says:
> 2. Select HDCP for the desired stream using the Pipe DDI Function
> Control register.
This is the 5th bit (Multistream HDCP Select) of Pipe DDI Function Control register i.e
TRANS_DDI_FUNC_CTL register. This bit ensures HDCP encryption to this transcoder stream when used in
multistream DisplayPort mode.
Unfortunately public specs of Gen11 has discrepency and doesn't describe this bit.
https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-icllp-vol02c-commandreference-registers-part2_0.pdf
Page No.1026 TRANS_DDI_FUNC_CTL
> 
> > > Apart from that Patch looks good to me.
> > IMHO it seems we are still missing to enable the Multistream HDCP Select
> > bit (5) in TRANS_DDI_FUNC_CTL register which is required to enable the
> > stream encryption.
> >
> 
> Could you send me some docs on this? I don't see have info on this bit.
This bit is not described in above mentioned public spec, but neither bit TRANS_DDI_HDCP_SIGNALLING bit (9th)
which used in this patch, what is the source of public B.spec you are following?
Thanks,
Anshuman Gupta.
> 
> Sean
> 
> > Thanks,
> > Anshuman Gupta.
> > >
> > > -Ram
> > >
> > > > +   if (ret)
> > > > +           drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> > > > +                         enable ? "Enable" : "Disable", ret);
> > > > +   return ret;
> > > > +}
> > > > +
> > > > +static
> > > > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> > > > +                             struct intel_connector *connector)
> > > > +{
> > > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > > +   struct intel_dp *intel_dp = &intel_dig_port->dp;
> > > > +   struct drm_dp_query_stream_enc_status_ack_reply reply;
> > > > +   int ret;
> > > > +
> > > > +   if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> > > > +           return false;
> > > > +
> > > > +   ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> > > > +                                             connector->port, &reply);
> > > > +   if (ret) {
> > > > +           drm_dbg_kms(&i915->drm,
> > > > +                       "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> > > > +                       connector->base.base.id, connector->base.name, ret);
> > > > +           return false;
> > > > +   }
> > > > +
> > > > +   return reply.auth_completed && reply.encryption_enabled;
> > > > +}
> > > > +
> > > > +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> > > > +   .write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > > > +   .read_bksv = intel_dp_hdcp_read_bksv,
> > > > +   .read_bstatus = intel_dp_hdcp_read_bstatus,
> > > > +   .repeater_present = intel_dp_hdcp_repeater_present,
> > > > +   .read_ri_prime = intel_dp_hdcp_read_ri_prime,
> > > > +   .read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> > > > +   .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> > > > +   .read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> > > > +   .toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> > > > +   .check_link = intel_dp_mst_hdcp_check_link,
> > > > +   .hdcp_capable = intel_dp_hdcp_capable,
> > > > +
> > > > +   .protocol = HDCP_PROTOCOL_DP,
> > > > +};
> > > > +
> > > >  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > > >                    struct intel_connector *intel_connector)
> > > >  {
> > > > @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > > >     if (!is_hdcp_supported(dev_priv, port))
> > > >             return 0;
> > > >
> > > > -   if (!intel_dp_is_edp(intel_dp))
> > > > +   if (intel_connector->mst_port)
> > > > +           return intel_hdcp_init(intel_connector, port,
> > > > +                                  &intel_dp_mst_hdcp_shim);
> > > > +   else if (!intel_dp_is_edp(intel_dp))
> > > >             return intel_hdcp_init(intel_connector, port,
> > > >                                    &intel_dp_hdcp_shim);
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > index 0675825dcc20..abaaeeb963d2 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > @@ -37,6 +37,7 @@
> > > >  #include "intel_dp.h"
> > > >  #include "intel_dp_mst.h"
> > > >  #include "intel_dpio_phy.h"
> > > > +#include "intel_hdcp.h"
> > > >
> > > >  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > > >                                         struct intel_crtc_state *crtc_state,
> > > > @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
> > > >     drm_dbg_kms(&i915->drm, "active links %d\n",
> > > >                 intel_dp->active_mst_links);
> > > >
> > > > +   intel_hdcp_disable(intel_mst->connector);
> > > > +
> > > >     drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
> > > >
> > > >     ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> > > > @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
> > > >
> > > >     if (pipe_config->has_audio)
> > > >             intel_audio_codec_enable(encoder, pipe_config, conn_state);
> > > > +
> > > > +   /* Enable hdcp if it's desired */
> > > > +   if (conn_state->content_protection ==
> > > > +       DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > > > +           intel_hdcp_enable(to_intel_connector(conn_state->connector),
> > > > +                             pipe_config->cpu_transcoder,
> > > > +                             (u8)conn_state->hdcp_content_type);
> > > >  }
> > > >
> > > >  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> > > > @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
> > > >     intel_attach_force_audio_property(connector);
> > > >     intel_attach_broadcast_rgb_property(connector);
> > > >
> > > > +
> > > > +   /* TODO: Figure out how to make HDCP work on GEN12+ */
> > > > +   if (INTEL_GEN(dev_priv) < 12) {
> > > > +           ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> > > > +           if (ret)
> > > > +                   DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> > > > +   }
> > > > +
> > > >     /*
> > > >      * Reuse the prop from the SST connector because we're
> > > >      * not allowed to create new props after device registration.
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > index 6bd0e4616ee1..ddc9db8de2bc 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
> > > >     if (!shim)
> > > >             return -EINVAL;
> > > >
> > > > -   if (is_hdcp2_supported(dev_priv))
> > > > +   if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
> > > >             intel_hdcp2_init(connector, port, shim);
> > > >
> > > >     ret =
> > > > --
> > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > >
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
@ 2020-08-12  7:03           ` Anshuman Gupta
  0 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-08-12  7:03 UTC (permalink / raw)
  To: Sean Paul; +Cc: intel-gfx, Sean Paul, dri-devel, daniel.vetter

On 2020-08-11 at 13:28:46 -0400, Sean Paul wrote:
> On Thu, Jul 9, 2020 at 8:40 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
> >
> 
> \snip
> 
> > > > +static int
> > > > +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> > > > +                               enum transcoder cpu_transcoder,
> > > > +                               bool enable)
> > > > +{
> > > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > > +   int ret;
> > > > +
> > > > +   if (!enable)
> > > > +           usleep_range(6, 60); /* Bspec says >= 6us */
> > > > +
> > > > +   ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> > > > +                                          cpu_transcoder, enable);
> > > Sean,
> > >
> > > This function toggles the TRANS_DDI_HDCP_SIGNALLING (9th)bit of TRANS_DDI_FUNC_CTL(tran)
> > > But in the hw specification this bit is mentioned to be ignored for non
> > > HDMI/DVI modes of the TRANS DDI.
> > >
> > > Any reason why we need this? Did you try with out this function?
> > >
> 
> Under "Authentication Part 1 for Multi-stream DisplayPort", bspec says:
> 2. Select HDCP for the desired stream using the Pipe DDI Function
> Control register.
This is the 5th bit (Multistream HDCP Select) of Pipe DDI Function Control register i.e
TRANS_DDI_FUNC_CTL register. This bit ensures HDCP encryption to this transcoder stream when used in
multistream DisplayPort mode.
Unfortunately public specs of Gen11 has discrepency and doesn't describe this bit.
https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-icllp-vol02c-commandreference-registers-part2_0.pdf
Page No.1026 TRANS_DDI_FUNC_CTL
> 
> > > Apart from that Patch looks good to me.
> > IMHO it seems we are still missing to enable the Multistream HDCP Select
> > bit (5) in TRANS_DDI_FUNC_CTL register which is required to enable the
> > stream encryption.
> >
> 
> Could you send me some docs on this? I don't see have info on this bit.
This bit is not described in above mentioned public spec, but neither bit TRANS_DDI_HDCP_SIGNALLING bit (9th)
which used in this patch, what is the source of public B.spec you are following?
Thanks,
Anshuman Gupta.
> 
> Sean
> 
> > Thanks,
> > Anshuman Gupta.
> > >
> > > -Ram
> > >
> > > > +   if (ret)
> > > > +           drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> > > > +                         enable ? "Enable" : "Disable", ret);
> > > > +   return ret;
> > > > +}
> > > > +
> > > > +static
> > > > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> > > > +                             struct intel_connector *connector)
> > > > +{
> > > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > > +   struct intel_dp *intel_dp = &intel_dig_port->dp;
> > > > +   struct drm_dp_query_stream_enc_status_ack_reply reply;
> > > > +   int ret;
> > > > +
> > > > +   if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> > > > +           return false;
> > > > +
> > > > +   ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> > > > +                                             connector->port, &reply);
> > > > +   if (ret) {
> > > > +           drm_dbg_kms(&i915->drm,
> > > > +                       "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> > > > +                       connector->base.base.id, connector->base.name, ret);
> > > > +           return false;
> > > > +   }
> > > > +
> > > > +   return reply.auth_completed && reply.encryption_enabled;
> > > > +}
> > > > +
> > > > +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> > > > +   .write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > > > +   .read_bksv = intel_dp_hdcp_read_bksv,
> > > > +   .read_bstatus = intel_dp_hdcp_read_bstatus,
> > > > +   .repeater_present = intel_dp_hdcp_repeater_present,
> > > > +   .read_ri_prime = intel_dp_hdcp_read_ri_prime,
> > > > +   .read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> > > > +   .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> > > > +   .read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> > > > +   .toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> > > > +   .check_link = intel_dp_mst_hdcp_check_link,
> > > > +   .hdcp_capable = intel_dp_hdcp_capable,
> > > > +
> > > > +   .protocol = HDCP_PROTOCOL_DP,
> > > > +};
> > > > +
> > > >  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > > >                    struct intel_connector *intel_connector)
> > > >  {
> > > > @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > > >     if (!is_hdcp_supported(dev_priv, port))
> > > >             return 0;
> > > >
> > > > -   if (!intel_dp_is_edp(intel_dp))
> > > > +   if (intel_connector->mst_port)
> > > > +           return intel_hdcp_init(intel_connector, port,
> > > > +                                  &intel_dp_mst_hdcp_shim);
> > > > +   else if (!intel_dp_is_edp(intel_dp))
> > > >             return intel_hdcp_init(intel_connector, port,
> > > >                                    &intel_dp_hdcp_shim);
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > index 0675825dcc20..abaaeeb963d2 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > @@ -37,6 +37,7 @@
> > > >  #include "intel_dp.h"
> > > >  #include "intel_dp_mst.h"
> > > >  #include "intel_dpio_phy.h"
> > > > +#include "intel_hdcp.h"
> > > >
> > > >  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > > >                                         struct intel_crtc_state *crtc_state,
> > > > @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
> > > >     drm_dbg_kms(&i915->drm, "active links %d\n",
> > > >                 intel_dp->active_mst_links);
> > > >
> > > > +   intel_hdcp_disable(intel_mst->connector);
> > > > +
> > > >     drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
> > > >
> > > >     ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> > > > @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
> > > >
> > > >     if (pipe_config->has_audio)
> > > >             intel_audio_codec_enable(encoder, pipe_config, conn_state);
> > > > +
> > > > +   /* Enable hdcp if it's desired */
> > > > +   if (conn_state->content_protection ==
> > > > +       DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > > > +           intel_hdcp_enable(to_intel_connector(conn_state->connector),
> > > > +                             pipe_config->cpu_transcoder,
> > > > +                             (u8)conn_state->hdcp_content_type);
> > > >  }
> > > >
> > > >  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> > > > @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
> > > >     intel_attach_force_audio_property(connector);
> > > >     intel_attach_broadcast_rgb_property(connector);
> > > >
> > > > +
> > > > +   /* TODO: Figure out how to make HDCP work on GEN12+ */
> > > > +   if (INTEL_GEN(dev_priv) < 12) {
> > > > +           ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> > > > +           if (ret)
> > > > +                   DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> > > > +   }
> > > > +
> > > >     /*
> > > >      * Reuse the prop from the SST connector because we're
> > > >      * not allowed to create new props after device registration.
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > index 6bd0e4616ee1..ddc9db8de2bc 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
> > > >     if (!shim)
> > > >             return -EINVAL;
> > > >
> > > > -   if (is_hdcp2_supported(dev_priv))
> > > > +   if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
> > > >             intel_hdcp2_init(connector, port, shim);
> > > >
> > > >     ret =
> > > > --
> > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > >
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
  2020-08-11 17:21             ` Sean Paul
@ 2020-08-12  8:18               ` Anshuman Gupta
  -1 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-08-12  8:18 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-08-11 at 13:21:38 -0400, Sean Paul wrote:
> On Thu, Jul 9, 2020 at 9:09 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
> >
> > On 2020-07-02 at 20:07:36 +0530, Anshuman Gupta wrote:
> > > On 2020-06-30 at 12:48:34 -0400, Sean Paul wrote:
> > > > On Tue, Jun 30, 2020 at 10:21 AM Anshuman Gupta
> > > > <anshuman.gupta@intel.com> wrote:
> > > > >
> > > > > On 2020-06-23 at 21:29:05 +0530, Sean Paul wrote:
> > > > > Hi Sean,
> > > > > I am new to DP MST stuff, I am looking to DP MST spec DP v1.2a.
> > > > > I have looked the entire series, i will take up this opportunity to review
> > > > > the series from HDCP over DP MST POV.
> > > > > I think theoretically this series should work or Gen12 as well, as DP MST streams
> > > > > are getting encrypted by QUERY_STREAM_ENCRYPTION_STATUS reply tranaction msg
> > > > > (generating Stream State Signature L’).
> > > > > I will test this on Gen12 H/W with DP MST support and will provide my inputs.
> > > > >
> > > > > Meanwhile while going through DP MST v1.2a specs(Page 262) came to know about
> > > > > a DP irq vector LINK_SERVICE_IRQ_VECTOR_ESI0 (02005h),
> > > > > Bit 2 : STREAM_STATUS_CHANGED.
> > > > > When this bit set to ‘1’ indicates the source must re-check the Stream Status
> > > > > with the QUERY_STREAM_ENCRYPTION_STATUS message.
> > > > > Currently i feel this irq support is missing, do we require to support
> > > > > above IRQ vector for DP MST stream encryption.
> > > > >
> > > >
> > > > Hi Anshuman,
> > > > Thank you for your comments.
> > > >
> > > > QUERY_STREAM_ENCRYPTION_STATUS is not necessary for HDCP 1.x, I added
> > > > this as a safety check to ensure that the streams were being
> > > > encrypted. As such, the existing integrity checks in place for DP are
> > > > sufficient to satisfy spec. When HDCP 2.2 support is added for MST,
> > > > handling QSES will need to be addressed to meet spec. Note also that
> > > > we're not validating the QSES signature for the same reason.
> > > Thanks sean for the explanation,
> > > overall patch looks good to me but i have couple of doubt see below.
> > > >
> > > > Sean
> > > >
> > > >
> > > > > Thanks,
> > > > > Anshuman Gupta.
> > > > >
> > > > > > From: Sean Paul <seanpaul@chromium.org>
> > > > > >
> > > > > > Used to query whether an MST stream is encrypted or not.
> > > > > >
> > > > > > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > > > > >
> > > > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
> > > > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
> > > > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6
> > > > > >
> > > > > > Changes in v4:
> > > > > > -Added to the set
> > > > > > Changes in v5:
> > > > > > -None
> > > > > > Changes in v6:
> > > > > > -Use FIELD_PREP to generate request buffer bitfields (Lyude)
> > > > > > -Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
> > > > > > Changes in v7:
> > > > > > -None
> > > > > > ---
> > > > > >  drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
> > > > > >  .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
> > > > > >  include/drm/drm_dp_helper.h                   |   3 +
> > > > > >  include/drm/drm_dp_mst_helper.h               |  44 ++++++
> > > > > >  4 files changed, 206 insertions(+)
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > > > index b2f5a84b4cfb..fc68478eaeb4 100644
> > > > > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > > > @@ -20,11 +20,13 @@
> > > > > >   * OF THIS SOFTWARE.
> > > > > >   */
> > > > > >
> > > > > > +#include <linux/bitfield.h>
> > > > > >  #include <linux/delay.h>
> > > > > >  #include <linux/errno.h>
> > > > > >  #include <linux/i2c.h>
> > > > > >  #include <linux/init.h>
> > > > > >  #include <linux/kernel.h>
> > > > > > +#include <linux/random.h>
> > > > > >  #include <linux/sched.h>
> > > > > >  #include <linux/seq_file.h>
> > > > > >  #include <linux/iopoll.h>
> > > > > > @@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
> > > > > >               memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
> > > > > >               idx += req->u.i2c_write.num_bytes;
> > > > > >               break;
> > > > > > +     case DP_QUERY_STREAM_ENC_STATUS: {
> > > > > > +             const struct drm_dp_query_stream_enc_status *msg;
> > > > > > +
> > > > > > +             msg = &req->u.enc_status;
> > > > > > +             buf[idx] = msg->stream_id;
> > > > > > +             idx++;
> > > > > > +             memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
> > > > > > +             idx += sizeof(msg->client_id);
> > > > > > +             buf[idx] = 0;
> > > > > > +             buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
> > > > > > +             buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
> > > > > > +             buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
> > > > > > +             buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
> > > > > > +             idx++;
> > > > > > +             }
> > > > > > +             break;
> > > > > >       }
> > > > > >       raw->cur_len = idx;
> > > > > >  }
> > > > > > @@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
> > > > > >                               return -ENOMEM;
> > > > > >               }
> > > > > >               break;
> > > > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > > > +             req->u.enc_status.stream_id = buf[idx++];
> > > > > > +             for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
> > > > > > +                     req->u.enc_status.client_id[i] = buf[idx++];
> > > > > > +
> > > > > > +             req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
> > > > > > +                                                        buf[idx]);
> > > > > > +             req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
> > > > > > +                                                              buf[idx]);
> > > > > > +             req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
> > > > > > +                                                           buf[idx]);
> > > > > > +             req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
> > > > > > +                                                                 buf[idx]);
> > > > > > +             break;
> > > > > >       }
> > > > > >
> > > > > >       return 0;
> > > > > > @@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
> > > > > >                 req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
> > > > > >                 req->u.i2c_write.bytes);
> > > > > >               break;
> > > > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > > > +             P("stream_id=%u client_id=%*ph stream_event=%x "
> > > > > > +               "valid_event=%d stream_behavior=%x valid_behavior=%d",
> > > > > > +               req->u.enc_status.stream_id,
> > > > > > +               (int)ARRAY_SIZE(req->u.enc_status.client_id),
> > > > > > +               req->u.enc_status.client_id, req->u.enc_status.stream_event,
> > > > > > +               req->u.enc_status.valid_stream_event,
> > > > > > +               req->u.enc_status.stream_behavior,
> > > > > > +               req->u.enc_status.valid_stream_behavior);
> > > > > > +             break;
> > > > > >       default:
> > > > > >               P("???\n");
> > > > > >               break;
> > > > > > @@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
> > > > > >       return true;
> > > > > >  }
> > > > > >
> > > > > > +static bool
> > > > > > +drm_dp_sideband_parse_query_stream_enc_status(
> > > > > > +                             struct drm_dp_sideband_msg_rx *raw,
> > > > > > +                             struct drm_dp_sideband_msg_reply_body *repmsg)
> > > > > > +{
> > > > > > +     struct drm_dp_query_stream_enc_status_ack_reply *reply;
> > > > > > +
> > > > > > +     reply = &repmsg->u.enc_status;
> > > > > > +
> > > > > > +     reply->stream_id = raw->msg[3];
> > > It seems msg[0] is not part of reply data,
> > > could you help me with pointers, where msg is formatted.
> > > > > > +
> > > > > > +     reply->reply_signed = raw->msg[2] & BIT(0);
> > This whole patch looks good to me i could have given RB but i am having
> > some concerns regarding parsing of bits here.
> > reply_signed is 15th bit of reply message i.e MSB of msg[2] here.
> > it seems bit parsing is in reverse order in all places.
> > > > > > +
> > > > > > +     reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> > > > > > +     reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
> > But these two bits are not parse as reverse order, these are parse
> > as similar in DP specs, hdcp_1x 11th bit (bit 3 of msg[2]),
> > hdcp_2x 12th bit (bit 4 of msg[2]).
> > Please correct me if i am wrong here.
> 
> I'm not really sure what to make of this field since when I connect a
> display which only supports HDCP 1.x (no HDCP 2.x), I get:
> 
> msg[2][4:3] = 01b
> 
> I've reproduced this with multiple hubs. I don't have an HDCP 2.x
> display, so I can't reproduce to see if the other bit lights up under
> those conditions.
> 
> We're not using these fields at the moment, so I suppose I can switch
> them around and leave a comment in case someone notices weirdness.
Yes that should be fine.
Considering that all reply msg bits should parsed in reverse order,
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
> 
> Sean
> 
> 
> 
> > Thanks,
> > Anshuman Gupta.
> > > > > > +
> > > > > > +     reply->query_capable_device_present = raw->msg[2] & BIT(5);
> > > > > > +     reply->legacy_device_present = raw->msg[2] & BIT(6);
> > > > > > +     reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> > > > > > +
> > > > > > +     reply->auth_completed = !!(raw->msg[1] & BIT(3));
> >
> > > > > > +     reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> > > > > > +     reply->repeater_present = !!(raw->msg[1] & BIT(5));
> > > > > > +     reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> > > > > > +
> > > > > > +     return true;
> > > > > > +}
> > > > > > +
> > > > > >  static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > > > > >                                       struct drm_dp_sideband_msg_reply_body *msg)
> > > > > >  {
> > > > > > @@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > > > > >               return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
> > > > > >       case DP_CLEAR_PAYLOAD_ID_TABLE:
> > > > > >               return true; /* since there's nothing to parse */
> > > > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > > > +             return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
> > > > > >       default:
> > > > > >               DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
> > > > > >                         drm_dp_mst_req_type_str(msg->req_type));
> > > > > > @@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
> > > > > >       msg->path_msg = true;
> > > > > >  }
> > > > > >
> > > > > > +static int
> > > > > > +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
> > > > > > +                           u8 *q_id)
> > > > > > +{
> > > > > > +     struct drm_dp_sideband_msg_req_body req;
> > > > > > +
> > > > > > +     req.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > > > > +     req.u.enc_status.stream_id = stream_id;
> > > > > > +     memcpy(req.u.enc_status.client_id, q_id,
> > > > > > +            sizeof(req.u.enc_status.client_id));
> > > > > > +     req.u.enc_status.stream_event = 0;
> > > > > > +     req.u.enc_status.valid_stream_event = false;
> > > > > > +     req.u.enc_status.stream_behavior = 0;
> > > > > > +     req.u.enc_status.valid_stream_behavior = false;
> > > > > > +
> > > > > > +     drm_dp_encode_sideband_req(&req, msg);
> > > > > > +     return 0;
> > > > > > +}
> > > > > > +
> > > > > >  static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
> > > > > >                                       struct drm_dp_vcpi *vcpi)
> > > > > >  {
> > > > > > @@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > > > >  }
> > > > > >  EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
> > > > > >
> > > > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > > > +             struct drm_dp_mst_port *port,
> > > > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status)
> > > > > > +{
> > > > > > +     struct drm_dp_sideband_msg_tx *txmsg;
> > > > > > +     u8 nonce[7];
> > > > > > +     int len, ret;
> > > > > > +
> > > > > > +     txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> > > > > > +     if (!txmsg)
> > > > > > +             return -ENOMEM;
> > > > > > +
> > > > > > +     port = drm_dp_mst_topology_get_port_validated(mgr, port);
> > > > > > +     if (!port) {
> > > > > > +             ret = -EINVAL;
> > > > > > +             goto out_get_port;
> > > > > > +     }
> > > > > > +
> > > > > > +     get_random_bytes(nonce, sizeof(nonce));
> > > > > > +
> > > > > > +     /*
> > > > > > +      * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
> > > > > > +      *  transaction at the MST Branch device directly connected to the
> > > > > > +      *  Source"
> > > > > > +      */
> > > > > > +     txmsg->dst = mgr->mst_primary;
> > > > > > +
> > > > > > +     len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
> > > > > > +
> > > > > > +     drm_dp_queue_down_tx(mgr, txmsg);
> > > > > > +
> > > > > > +     ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
> > > > > > +     if (ret < 0) {
> > > > > > +             goto out;
> > > > > > +     } else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
> > > > > > +             DRM_DEBUG_KMS("query encryption status nak received\n");
> > > > > > +             ret = -ENXIO;
> > > > > > +             goto out;
> > > > > > +     }
> > > > > > +
> > > > > > +     ret = 0;
> > > > > > +     memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
> > > > > > +
> > > > > > +out:
> > > > > > +     drm_dp_mst_topology_put_port(port);
> > > > > > +out_get_port:
> > > > > > +     kfree(txmsg);
> > > > > > +     return ret;
> > > > > > +}
> > > > > > +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
> > > > > > +
> > > > > >  static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
> > > > > >                                      int id,
> > > > > >                                      struct drm_dp_payload *payload)
> > > > > > diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > > > index bd990d178765..1d696ec001cf 100644
> > > > > > --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > > > +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > > > @@ -5,6 +5,8 @@
> > > > > >
> > > > > >  #define PREFIX_STR "[drm_dp_mst_helper]"
> > > > > >
> > > > > > +#include <linux/random.h>
> > > > > > +
> > > > > >  #include <drm/drm_dp_mst_helper.h>
> > > > > >  #include <drm/drm_print.h>
> > > > > >
> > > > > > @@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
> > > > > >       in.u.i2c_write.bytes = data;
> > > > > >       DO_TEST();
> > > > > >
> > > > > > +     in.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > > > > +     in.u.enc_status.stream_id = 1;
> > > > > > +     DO_TEST();
> > > > > > +     get_random_bytes(in.u.enc_status.client_id,
> > > > > > +                      sizeof(in.u.enc_status.client_id));
> > > > > > +     DO_TEST();
> > > > > > +     in.u.enc_status.stream_event = 3;
> > > > > > +     DO_TEST();
> > > > > > +     in.u.enc_status.valid_stream_event = 0;
> > > > > > +     DO_TEST();
> > > > > > +     in.u.enc_status.stream_behavior = 3;
> > > > > > +     DO_TEST();
> > > > > > +     in.u.enc_status.valid_stream_behavior = 1;
> > > > > > +     DO_TEST();
> > > > > > +
> > > > > >  #undef DO_TEST
> > > > > >       return 0;
> > > > > >  }
> > > > > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > > > > > index e47dc22ebf50..e2d2df5e869e 100644
> > > > > > --- a/include/drm/drm_dp_helper.h
> > > > > > +++ b/include/drm/drm_dp_helper.h
> > > > > > @@ -1108,6 +1108,9 @@
> > > > > >  #define DP_POWER_DOWN_PHY            0x25
> > > > > >  #define DP_SINK_EVENT_NOTIFY         0x30
> > > > > >  #define DP_QUERY_STREAM_ENC_STATUS   0x38
> > > > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST   0
> > > > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE   1
> > > > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE     2
> > > > > >
> > > > > >  /* DP 1.2 MST sideband reply types */
> > > > > >  #define DP_SIDEBAND_REPLY_ACK                0x00
> > > > > > diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> > > > > > index 8b9eb4db3381..371eef8798ad 100644
> > > > > > --- a/include/drm/drm_dp_mst_helper.h
> > > > > > +++ b/include/drm/drm_dp_mst_helper.h
> > > > > > @@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
> > > > > >       u8 port_number;
> > > > > >  };
> > > > > >
> > > > > > +struct drm_dp_query_stream_enc_status_ack_reply {
> > > > > > +     /* Bit[23:16]- Stream Id */
> > > > > > +     u8 stream_id;
> > > > > > +
> > > > > > +     /* Bit[15]- Signed */
> > > > > > +     bool reply_signed;
> > > > > > +
> > > > > > +     /* Bit[10:8]- Stream Output Sink Type */
> > > > > > +     bool unauthorizable_device_present;
> > > > > > +     bool legacy_device_present;
> > > > > > +     bool query_capable_device_present;
> > > > > > +
> > > > > > +     /* Bit[12:11]- Stream Output CP Type */
> > > > > > +     bool hdcp_1x_device_present;
> > > > > > +     bool hdcp_2x_device_present;
> > > > > > +
> > > > > > +     /* Bit[4]- Stream Authentication */
> > > > > > +     bool auth_completed;
> > > > > > +
> > > > > > +     /* Bit[3]- Stream Encryption */
> > > > > > +     bool encryption_enabled;
> > > > > > +
> > > > > > +     /* Bit[2]- Stream Repeater Function Present */
> > > > > > +     bool repeater_present;
> > > > > > +
> > > > > > +     /* Bit[1:0]- Stream State */
> > > > > > +     u8 state;
> > > reply msg also has 20 byte of signature L' (HDCP 1.4),
> > > AFAIU it has lefted out for HDCP 2.2 implementation, which is of 32 bytes for HDCP 2.2.
> > > Please correct me if i am wrong here.
> > > Thanks,
> > > Anshuman Gupta.
> > > > > > +};
> > > > > >
> > > > > >  #define DRM_DP_MAX_SDP_STREAMS 16
> > > > > >  struct drm_dp_allocate_payload {
> > > > > > @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
> > > > > >       u8 *bytes;
> > > > > >  };
> > > > > >
> > > > > > +struct drm_dp_query_stream_enc_status {
> > > > > > +     u8 stream_id;
> > > > > > +     u8 client_id[7];        /* 56-bit nonce */
> > > > > > +     u8 stream_event;
> > > > > > +     bool valid_stream_event;
> > > > > > +     u8 stream_behavior;
> > > > > > +     u8 valid_stream_behavior;
> > > > > > +};
> > > > > > +
> > > > > >  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
> > > > > >  struct drm_dp_port_number_req {
> > > > > >       u8 port_number;
> > > > > > @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
> > > > > >
> > > > > >               struct drm_dp_remote_i2c_read i2c_read;
> > > > > >               struct drm_dp_remote_i2c_write i2c_write;
> > > > > > +
> > > > > > +             struct drm_dp_query_stream_enc_status enc_status;
> > > > > >       } u;
> > > > > >  };
> > > > > >
> > > > > > @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
> > > > > >               struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
> > > > > >               struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
> > > > > >               struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> > > > > > +
> > > > > > +             struct drm_dp_query_stream_enc_status_ack_reply enc_status;
> > > > > >       } u;
> > > > > >  };
> > > > > >
> > > > > > @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
> > > > > >                                struct drm_dp_mst_port *port);
> > > > > >  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > > > >                                struct drm_dp_mst_port *port, bool power_up);
> > > > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > > > +             struct drm_dp_mst_port *port,
> > > > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status);
> > > > > >  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
> > > > > >
> > > > > >  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> > > > > > --
> > > > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > > > >
> > > > > > _______________________________________________
> > > > > > Intel-gfx mailing list
> > > > > > Intel-gfx@lists.freedesktop.org
> > > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message
@ 2020-08-12  8:18               ` Anshuman Gupta
  0 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-08-12  8:18 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2020-08-11 at 13:21:38 -0400, Sean Paul wrote:
> On Thu, Jul 9, 2020 at 9:09 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
> >
> > On 2020-07-02 at 20:07:36 +0530, Anshuman Gupta wrote:
> > > On 2020-06-30 at 12:48:34 -0400, Sean Paul wrote:
> > > > On Tue, Jun 30, 2020 at 10:21 AM Anshuman Gupta
> > > > <anshuman.gupta@intel.com> wrote:
> > > > >
> > > > > On 2020-06-23 at 21:29:05 +0530, Sean Paul wrote:
> > > > > Hi Sean,
> > > > > I am new to DP MST stuff, I am looking to DP MST spec DP v1.2a.
> > > > > I have looked the entire series, i will take up this opportunity to review
> > > > > the series from HDCP over DP MST POV.
> > > > > I think theoretically this series should work or Gen12 as well, as DP MST streams
> > > > > are getting encrypted by QUERY_STREAM_ENCRYPTION_STATUS reply tranaction msg
> > > > > (generating Stream State Signature L’).
> > > > > I will test this on Gen12 H/W with DP MST support and will provide my inputs.
> > > > >
> > > > > Meanwhile while going through DP MST v1.2a specs(Page 262) came to know about
> > > > > a DP irq vector LINK_SERVICE_IRQ_VECTOR_ESI0 (02005h),
> > > > > Bit 2 : STREAM_STATUS_CHANGED.
> > > > > When this bit set to ‘1’ indicates the source must re-check the Stream Status
> > > > > with the QUERY_STREAM_ENCRYPTION_STATUS message.
> > > > > Currently i feel this irq support is missing, do we require to support
> > > > > above IRQ vector for DP MST stream encryption.
> > > > >
> > > >
> > > > Hi Anshuman,
> > > > Thank you for your comments.
> > > >
> > > > QUERY_STREAM_ENCRYPTION_STATUS is not necessary for HDCP 1.x, I added
> > > > this as a safety check to ensure that the streams were being
> > > > encrypted. As such, the existing integrity checks in place for DP are
> > > > sufficient to satisfy spec. When HDCP 2.2 support is added for MST,
> > > > handling QSES will need to be addressed to meet spec. Note also that
> > > > we're not validating the QSES signature for the same reason.
> > > Thanks sean for the explanation,
> > > overall patch looks good to me but i have couple of doubt see below.
> > > >
> > > > Sean
> > > >
> > > >
> > > > > Thanks,
> > > > > Anshuman Gupta.
> > > > >
> > > > > > From: Sean Paul <seanpaul@chromium.org>
> > > > > >
> > > > > > Used to query whether an MST stream is encrypted or not.
> > > > > >
> > > > > > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > > > > >
> > > > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-14-sean@poorly.run #v4
> > > > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-15-sean@poorly.run #v5
> > > > > > Link: https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-15-sean@poorly.run #v6
> > > > > >
> > > > > > Changes in v4:
> > > > > > -Added to the set
> > > > > > Changes in v5:
> > > > > > -None
> > > > > > Changes in v6:
> > > > > > -Use FIELD_PREP to generate request buffer bitfields (Lyude)
> > > > > > -Add mst selftest and dump/decode_sideband_req for QSES (Lyude)
> > > > > > Changes in v7:
> > > > > > -None
> > > > > > ---
> > > > > >  drivers/gpu/drm/drm_dp_mst_topology.c         | 142 ++++++++++++++++++
> > > > > >  .../drm/selftests/test-drm_dp_mst_helper.c    |  17 +++
> > > > > >  include/drm/drm_dp_helper.h                   |   3 +
> > > > > >  include/drm/drm_dp_mst_helper.h               |  44 ++++++
> > > > > >  4 files changed, 206 insertions(+)
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > > > index b2f5a84b4cfb..fc68478eaeb4 100644
> > > > > > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > > > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > > > > > @@ -20,11 +20,13 @@
> > > > > >   * OF THIS SOFTWARE.
> > > > > >   */
> > > > > >
> > > > > > +#include <linux/bitfield.h>
> > > > > >  #include <linux/delay.h>
> > > > > >  #include <linux/errno.h>
> > > > > >  #include <linux/i2c.h>
> > > > > >  #include <linux/init.h>
> > > > > >  #include <linux/kernel.h>
> > > > > > +#include <linux/random.h>
> > > > > >  #include <linux/sched.h>
> > > > > >  #include <linux/seq_file.h>
> > > > > >  #include <linux/iopoll.h>
> > > > > > @@ -419,6 +421,22 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
> > > > > >               memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
> > > > > >               idx += req->u.i2c_write.num_bytes;
> > > > > >               break;
> > > > > > +     case DP_QUERY_STREAM_ENC_STATUS: {
> > > > > > +             const struct drm_dp_query_stream_enc_status *msg;
> > > > > > +
> > > > > > +             msg = &req->u.enc_status;
> > > > > > +             buf[idx] = msg->stream_id;
> > > > > > +             idx++;
> > > > > > +             memcpy(&buf[idx], msg->client_id, sizeof(msg->client_id));
> > > > > > +             idx += sizeof(msg->client_id);
> > > > > > +             buf[idx] = 0;
> > > > > > +             buf[idx] |= FIELD_PREP(GENMASK(1, 0), msg->stream_event);
> > > > > > +             buf[idx] |= msg->valid_stream_event ? BIT(2) : 0;
> > > > > > +             buf[idx] |= FIELD_PREP(GENMASK(4, 3), msg->stream_behavior);
> > > > > > +             buf[idx] |= msg->valid_stream_behavior ? BIT(5) : 0;
> > > > > > +             idx++;
> > > > > > +             }
> > > > > > +             break;
> > > > > >       }
> > > > > >       raw->cur_len = idx;
> > > > > >  }
> > > > > > @@ -547,6 +565,20 @@ drm_dp_decode_sideband_req(const struct drm_dp_sideband_msg_tx *raw,
> > > > > >                               return -ENOMEM;
> > > > > >               }
> > > > > >               break;
> > > > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > > > +             req->u.enc_status.stream_id = buf[idx++];
> > > > > > +             for (i = 0; i < sizeof(req->u.enc_status.client_id); i++)
> > > > > > +                     req->u.enc_status.client_id[i] = buf[idx++];
> > > > > > +
> > > > > > +             req->u.enc_status.stream_event = FIELD_GET(GENMASK(1, 0),
> > > > > > +                                                        buf[idx]);
> > > > > > +             req->u.enc_status.valid_stream_event = FIELD_GET(BIT(2),
> > > > > > +                                                              buf[idx]);
> > > > > > +             req->u.enc_status.stream_behavior = FIELD_GET(GENMASK(4, 3),
> > > > > > +                                                           buf[idx]);
> > > > > > +             req->u.enc_status.valid_stream_behavior = FIELD_GET(BIT(5),
> > > > > > +                                                                 buf[idx]);
> > > > > > +             break;
> > > > > >       }
> > > > > >
> > > > > >       return 0;
> > > > > > @@ -625,6 +657,16 @@ drm_dp_dump_sideband_msg_req_body(const struct drm_dp_sideband_msg_req_body *req
> > > > > >                 req->u.i2c_write.num_bytes, req->u.i2c_write.num_bytes,
> > > > > >                 req->u.i2c_write.bytes);
> > > > > >               break;
> > > > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > > > +             P("stream_id=%u client_id=%*ph stream_event=%x "
> > > > > > +               "valid_event=%d stream_behavior=%x valid_behavior=%d",
> > > > > > +               req->u.enc_status.stream_id,
> > > > > > +               (int)ARRAY_SIZE(req->u.enc_status.client_id),
> > > > > > +               req->u.enc_status.client_id, req->u.enc_status.stream_event,
> > > > > > +               req->u.enc_status.valid_stream_event,
> > > > > > +               req->u.enc_status.stream_behavior,
> > > > > > +               req->u.enc_status.valid_stream_behavior);
> > > > > > +             break;
> > > > > >       default:
> > > > > >               P("???\n");
> > > > > >               break;
> > > > > > @@ -925,6 +967,34 @@ static bool drm_dp_sideband_parse_power_updown_phy_ack(struct drm_dp_sideband_ms
> > > > > >       return true;
> > > > > >  }
> > > > > >
> > > > > > +static bool
> > > > > > +drm_dp_sideband_parse_query_stream_enc_status(
> > > > > > +                             struct drm_dp_sideband_msg_rx *raw,
> > > > > > +                             struct drm_dp_sideband_msg_reply_body *repmsg)
> > > > > > +{
> > > > > > +     struct drm_dp_query_stream_enc_status_ack_reply *reply;
> > > > > > +
> > > > > > +     reply = &repmsg->u.enc_status;
> > > > > > +
> > > > > > +     reply->stream_id = raw->msg[3];
> > > It seems msg[0] is not part of reply data,
> > > could you help me with pointers, where msg is formatted.
> > > > > > +
> > > > > > +     reply->reply_signed = raw->msg[2] & BIT(0);
> > This whole patch looks good to me i could have given RB but i am having
> > some concerns regarding parsing of bits here.
> > reply_signed is 15th bit of reply message i.e MSB of msg[2] here.
> > it seems bit parsing is in reverse order in all places.
> > > > > > +
> > > > > > +     reply->hdcp_1x_device_present = raw->msg[2] & BIT(3);
> > > > > > +     reply->hdcp_2x_device_present = raw->msg[2] & BIT(4);
> > But these two bits are not parse as reverse order, these are parse
> > as similar in DP specs, hdcp_1x 11th bit (bit 3 of msg[2]),
> > hdcp_2x 12th bit (bit 4 of msg[2]).
> > Please correct me if i am wrong here.
> 
> I'm not really sure what to make of this field since when I connect a
> display which only supports HDCP 1.x (no HDCP 2.x), I get:
> 
> msg[2][4:3] = 01b
> 
> I've reproduced this with multiple hubs. I don't have an HDCP 2.x
> display, so I can't reproduce to see if the other bit lights up under
> those conditions.
> 
> We're not using these fields at the moment, so I suppose I can switch
> them around and leave a comment in case someone notices weirdness.
Yes that should be fine.
Considering that all reply msg bits should parsed in reverse order,
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>
> 
> Sean
> 
> 
> 
> > Thanks,
> > Anshuman Gupta.
> > > > > > +
> > > > > > +     reply->query_capable_device_present = raw->msg[2] & BIT(5);
> > > > > > +     reply->legacy_device_present = raw->msg[2] & BIT(6);
> > > > > > +     reply->unauthorizable_device_present = raw->msg[2] & BIT(7);
> > > > > > +
> > > > > > +     reply->auth_completed = !!(raw->msg[1] & BIT(3));
> >
> > > > > > +     reply->encryption_enabled = !!(raw->msg[1] & BIT(4));
> > > > > > +     reply->repeater_present = !!(raw->msg[1] & BIT(5));
> > > > > > +     reply->state = (raw->msg[1] & GENMASK(7, 6)) >> 6;
> > > > > > +
> > > > > > +     return true;
> > > > > > +}
> > > > > > +
> > > > > >  static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > > > > >                                       struct drm_dp_sideband_msg_reply_body *msg)
> > > > > >  {
> > > > > > @@ -959,6 +1029,8 @@ static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
> > > > > >               return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
> > > > > >       case DP_CLEAR_PAYLOAD_ID_TABLE:
> > > > > >               return true; /* since there's nothing to parse */
> > > > > > +     case DP_QUERY_STREAM_ENC_STATUS:
> > > > > > +             return drm_dp_sideband_parse_query_stream_enc_status(raw, msg);
> > > > > >       default:
> > > > > >               DRM_ERROR("Got unknown reply 0x%02x (%s)\n", msg->req_type,
> > > > > >                         drm_dp_mst_req_type_str(msg->req_type));
> > > > > > @@ -1109,6 +1181,25 @@ static void build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
> > > > > >       msg->path_msg = true;
> > > > > >  }
> > > > > >
> > > > > > +static int
> > > > > > +build_query_stream_enc_status(struct drm_dp_sideband_msg_tx *msg, u8 stream_id,
> > > > > > +                           u8 *q_id)
> > > > > > +{
> > > > > > +     struct drm_dp_sideband_msg_req_body req;
> > > > > > +
> > > > > > +     req.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > > > > +     req.u.enc_status.stream_id = stream_id;
> > > > > > +     memcpy(req.u.enc_status.client_id, q_id,
> > > > > > +            sizeof(req.u.enc_status.client_id));
> > > > > > +     req.u.enc_status.stream_event = 0;
> > > > > > +     req.u.enc_status.valid_stream_event = false;
> > > > > > +     req.u.enc_status.stream_behavior = 0;
> > > > > > +     req.u.enc_status.valid_stream_behavior = false;
> > > > > > +
> > > > > > +     drm_dp_encode_sideband_req(&req, msg);
> > > > > > +     return 0;
> > > > > > +}
> > > > > > +
> > > > > >  static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
> > > > > >                                       struct drm_dp_vcpi *vcpi)
> > > > > >  {
> > > > > > @@ -3137,6 +3228,57 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > > > >  }
> > > > > >  EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
> > > > > >
> > > > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > > > +             struct drm_dp_mst_port *port,
> > > > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status)
> > > > > > +{
> > > > > > +     struct drm_dp_sideband_msg_tx *txmsg;
> > > > > > +     u8 nonce[7];
> > > > > > +     int len, ret;
> > > > > > +
> > > > > > +     txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
> > > > > > +     if (!txmsg)
> > > > > > +             return -ENOMEM;
> > > > > > +
> > > > > > +     port = drm_dp_mst_topology_get_port_validated(mgr, port);
> > > > > > +     if (!port) {
> > > > > > +             ret = -EINVAL;
> > > > > > +             goto out_get_port;
> > > > > > +     }
> > > > > > +
> > > > > > +     get_random_bytes(nonce, sizeof(nonce));
> > > > > > +
> > > > > > +     /*
> > > > > > +      * "Source device targets the QUERY_STREAM_ENCRYPTION_STATUS message
> > > > > > +      *  transaction at the MST Branch device directly connected to the
> > > > > > +      *  Source"
> > > > > > +      */
> > > > > > +     txmsg->dst = mgr->mst_primary;
> > > > > > +
> > > > > > +     len = build_query_stream_enc_status(txmsg, port->vcpi.vcpi, nonce);
> > > > > > +
> > > > > > +     drm_dp_queue_down_tx(mgr, txmsg);
> > > > > > +
> > > > > > +     ret = drm_dp_mst_wait_tx_reply(mgr->mst_primary, txmsg);
> > > > > > +     if (ret < 0) {
> > > > > > +             goto out;
> > > > > > +     } else if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
> > > > > > +             DRM_DEBUG_KMS("query encryption status nak received\n");
> > > > > > +             ret = -ENXIO;
> > > > > > +             goto out;
> > > > > > +     }
> > > > > > +
> > > > > > +     ret = 0;
> > > > > > +     memcpy(status, &txmsg->reply.u.enc_status, sizeof(*status));
> > > > > > +
> > > > > > +out:
> > > > > > +     drm_dp_mst_topology_put_port(port);
> > > > > > +out_get_port:
> > > > > > +     kfree(txmsg);
> > > > > > +     return ret;
> > > > > > +}
> > > > > > +EXPORT_SYMBOL(drm_dp_send_query_stream_enc_status);
> > > > > > +
> > > > > >  static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
> > > > > >                                      int id,
> > > > > >                                      struct drm_dp_payload *payload)
> > > > > > diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > > > index bd990d178765..1d696ec001cf 100644
> > > > > > --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > > > +++ b/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c
> > > > > > @@ -5,6 +5,8 @@
> > > > > >
> > > > > >  #define PREFIX_STR "[drm_dp_mst_helper]"
> > > > > >
> > > > > > +#include <linux/random.h>
> > > > > > +
> > > > > >  #include <drm/drm_dp_mst_helper.h>
> > > > > >  #include <drm/drm_print.h>
> > > > > >
> > > > > > @@ -237,6 +239,21 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused)
> > > > > >       in.u.i2c_write.bytes = data;
> > > > > >       DO_TEST();
> > > > > >
> > > > > > +     in.req_type = DP_QUERY_STREAM_ENC_STATUS;
> > > > > > +     in.u.enc_status.stream_id = 1;
> > > > > > +     DO_TEST();
> > > > > > +     get_random_bytes(in.u.enc_status.client_id,
> > > > > > +                      sizeof(in.u.enc_status.client_id));
> > > > > > +     DO_TEST();
> > > > > > +     in.u.enc_status.stream_event = 3;
> > > > > > +     DO_TEST();
> > > > > > +     in.u.enc_status.valid_stream_event = 0;
> > > > > > +     DO_TEST();
> > > > > > +     in.u.enc_status.stream_behavior = 3;
> > > > > > +     DO_TEST();
> > > > > > +     in.u.enc_status.valid_stream_behavior = 1;
> > > > > > +     DO_TEST();
> > > > > > +
> > > > > >  #undef DO_TEST
> > > > > >       return 0;
> > > > > >  }
> > > > > > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> > > > > > index e47dc22ebf50..e2d2df5e869e 100644
> > > > > > --- a/include/drm/drm_dp_helper.h
> > > > > > +++ b/include/drm/drm_dp_helper.h
> > > > > > @@ -1108,6 +1108,9 @@
> > > > > >  #define DP_POWER_DOWN_PHY            0x25
> > > > > >  #define DP_SINK_EVENT_NOTIFY         0x30
> > > > > >  #define DP_QUERY_STREAM_ENC_STATUS   0x38
> > > > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_NO_EXIST   0
> > > > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_INACTIVE   1
> > > > > > +#define  DP_QUERY_STREAM_ENC_STATUS_STATE_ACTIVE     2
> > > > > >
> > > > > >  /* DP 1.2 MST sideband reply types */
> > > > > >  #define DP_SIDEBAND_REPLY_ACK                0x00
> > > > > > diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> > > > > > index 8b9eb4db3381..371eef8798ad 100644
> > > > > > --- a/include/drm/drm_dp_mst_helper.h
> > > > > > +++ b/include/drm/drm_dp_mst_helper.h
> > > > > > @@ -313,6 +313,34 @@ struct drm_dp_remote_i2c_write_ack_reply {
> > > > > >       u8 port_number;
> > > > > >  };
> > > > > >
> > > > > > +struct drm_dp_query_stream_enc_status_ack_reply {
> > > > > > +     /* Bit[23:16]- Stream Id */
> > > > > > +     u8 stream_id;
> > > > > > +
> > > > > > +     /* Bit[15]- Signed */
> > > > > > +     bool reply_signed;
> > > > > > +
> > > > > > +     /* Bit[10:8]- Stream Output Sink Type */
> > > > > > +     bool unauthorizable_device_present;
> > > > > > +     bool legacy_device_present;
> > > > > > +     bool query_capable_device_present;
> > > > > > +
> > > > > > +     /* Bit[12:11]- Stream Output CP Type */
> > > > > > +     bool hdcp_1x_device_present;
> > > > > > +     bool hdcp_2x_device_present;
> > > > > > +
> > > > > > +     /* Bit[4]- Stream Authentication */
> > > > > > +     bool auth_completed;
> > > > > > +
> > > > > > +     /* Bit[3]- Stream Encryption */
> > > > > > +     bool encryption_enabled;
> > > > > > +
> > > > > > +     /* Bit[2]- Stream Repeater Function Present */
> > > > > > +     bool repeater_present;
> > > > > > +
> > > > > > +     /* Bit[1:0]- Stream State */
> > > > > > +     u8 state;
> > > reply msg also has 20 byte of signature L' (HDCP 1.4),
> > > AFAIU it has lefted out for HDCP 2.2 implementation, which is of 32 bytes for HDCP 2.2.
> > > Please correct me if i am wrong here.
> > > Thanks,
> > > Anshuman Gupta.
> > > > > > +};
> > > > > >
> > > > > >  #define DRM_DP_MAX_SDP_STREAMS 16
> > > > > >  struct drm_dp_allocate_payload {
> > > > > > @@ -374,6 +402,15 @@ struct drm_dp_remote_i2c_write {
> > > > > >       u8 *bytes;
> > > > > >  };
> > > > > >
> > > > > > +struct drm_dp_query_stream_enc_status {
> > > > > > +     u8 stream_id;
> > > > > > +     u8 client_id[7];        /* 56-bit nonce */
> > > > > > +     u8 stream_event;
> > > > > > +     bool valid_stream_event;
> > > > > > +     u8 stream_behavior;
> > > > > > +     u8 valid_stream_behavior;
> > > > > > +};
> > > > > > +
> > > > > >  /* this covers ENUM_RESOURCES, POWER_DOWN_PHY, POWER_UP_PHY */
> > > > > >  struct drm_dp_port_number_req {
> > > > > >       u8 port_number;
> > > > > > @@ -422,6 +459,8 @@ struct drm_dp_sideband_msg_req_body {
> > > > > >
> > > > > >               struct drm_dp_remote_i2c_read i2c_read;
> > > > > >               struct drm_dp_remote_i2c_write i2c_write;
> > > > > > +
> > > > > > +             struct drm_dp_query_stream_enc_status enc_status;
> > > > > >       } u;
> > > > > >  };
> > > > > >
> > > > > > @@ -444,6 +483,8 @@ struct drm_dp_sideband_msg_reply_body {
> > > > > >               struct drm_dp_remote_i2c_read_ack_reply remote_i2c_read_ack;
> > > > > >               struct drm_dp_remote_i2c_read_nak_reply remote_i2c_read_nack;
> > > > > >               struct drm_dp_remote_i2c_write_ack_reply remote_i2c_write_ack;
> > > > > > +
> > > > > > +             struct drm_dp_query_stream_enc_status_ack_reply enc_status;
> > > > > >       } u;
> > > > > >  };
> > > > > >
> > > > > > @@ -808,6 +849,9 @@ drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
> > > > > >                                struct drm_dp_mst_port *port);
> > > > > >  int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
> > > > > >                                struct drm_dp_mst_port *port, bool power_up);
> > > > > > +int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr,
> > > > > > +             struct drm_dp_mst_port *port,
> > > > > > +             struct drm_dp_query_stream_enc_status_ack_reply *status);
> > > > > >  int __must_check drm_dp_mst_atomic_check(struct drm_atomic_state *state);
> > > > > >
> > > > > >  void drm_dp_mst_get_port_malloc(struct drm_dp_mst_port *port);
> > > > > > --
> > > > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > > > >
> > > > > > _______________________________________________
> > > > > > Intel-gfx mailing list
> > > > > > Intel-gfx@lists.freedesktop.org
> > > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
  2020-08-12  7:03           ` Anshuman Gupta
@ 2020-08-12 17:21             ` Sean Paul
  -1 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-08-12 17:21 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: intel-gfx, Sean Paul, dri-devel, daniel.vetter

On Wed, Aug 12, 2020 at 3:15 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
>
> On 2020-08-11 at 13:28:46 -0400, Sean Paul wrote:
> > On Thu, Jul 9, 2020 at 8:40 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
> > >
> >
> > \snip
> >
> > > > > +static int
> > > > > +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> > > > > +                               enum transcoder cpu_transcoder,
> > > > > +                               bool enable)
> > > > > +{
> > > > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > > > +   int ret;
> > > > > +
> > > > > +   if (!enable)
> > > > > +           usleep_range(6, 60); /* Bspec says >= 6us */
> > > > > +
> > > > > +   ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> > > > > +                                          cpu_transcoder, enable);
> > > > Sean,
> > > >
> > > > This function toggles the TRANS_DDI_HDCP_SIGNALLING (9th)bit of TRANS_DDI_FUNC_CTL(tran)
> > > > But in the hw specification this bit is mentioned to be ignored for non
> > > > HDMI/DVI modes of the TRANS DDI.
> > > >
> > > > Any reason why we need this? Did you try with out this function?
> > > >
> >
> > Under "Authentication Part 1 for Multi-stream DisplayPort", bspec says:
> > 2. Select HDCP for the desired stream using the Pipe DDI Function
> > Control register.
> This is the 5th bit (Multistream HDCP Select) of Pipe DDI Function Control register i.e
> TRANS_DDI_FUNC_CTL register. This bit ensures HDCP encryption to this transcoder stream when used in
> multistream DisplayPort mode.
> Unfortunately public specs of Gen11 has discrepency and doesn't describe this bit.
> https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-icllp-vol02c-commandreference-registers-part2_0.pdf
> Page No.1026 TRANS_DDI_FUNC_CTL
> >
> > > > Apart from that Patch looks good to me.
> > > IMHO it seems we are still missing to enable the Multistream HDCP Select
> > > bit (5) in TRANS_DDI_FUNC_CTL register which is required to enable the
> > > stream encryption.
> > >
> >
> > Could you send me some docs on this? I don't see have info on this bit.
> This bit is not described in above mentioned public spec, but neither bit TRANS_DDI_HDCP_SIGNALLING bit (9th)
> which used in this patch, what is the source of public B.spec you are following?

I think it's been removed from public now, but there was a public doc
on Intel's site when I originally wrote these which described the
TRANS_DDI_FUNC_CTL register.

So do I just need to set bit 5 at the same time as the HDCP SIGNALLING bit?

Sean

> Thanks,
> Anshuman Gupta.
> >
> > Sean
> >
> > > Thanks,
> > > Anshuman Gupta.
> > > >
> > > > -Ram
> > > >
> > > > > +   if (ret)
> > > > > +           drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> > > > > +                         enable ? "Enable" : "Disable", ret);
> > > > > +   return ret;
> > > > > +}
> > > > > +
> > > > > +static
> > > > > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> > > > > +                             struct intel_connector *connector)
> > > > > +{
> > > > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > > > +   struct intel_dp *intel_dp = &intel_dig_port->dp;
> > > > > +   struct drm_dp_query_stream_enc_status_ack_reply reply;
> > > > > +   int ret;
> > > > > +
> > > > > +   if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> > > > > +           return false;
> > > > > +
> > > > > +   ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> > > > > +                                             connector->port, &reply);
> > > > > +   if (ret) {
> > > > > +           drm_dbg_kms(&i915->drm,
> > > > > +                       "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> > > > > +                       connector->base.base.id, connector->base.name, ret);
> > > > > +           return false;
> > > > > +   }
> > > > > +
> > > > > +   return reply.auth_completed && reply.encryption_enabled;
> > > > > +}
> > > > > +
> > > > > +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> > > > > +   .write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > > > > +   .read_bksv = intel_dp_hdcp_read_bksv,
> > > > > +   .read_bstatus = intel_dp_hdcp_read_bstatus,
> > > > > +   .repeater_present = intel_dp_hdcp_repeater_present,
> > > > > +   .read_ri_prime = intel_dp_hdcp_read_ri_prime,
> > > > > +   .read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> > > > > +   .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> > > > > +   .read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> > > > > +   .toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> > > > > +   .check_link = intel_dp_mst_hdcp_check_link,
> > > > > +   .hdcp_capable = intel_dp_hdcp_capable,
> > > > > +
> > > > > +   .protocol = HDCP_PROTOCOL_DP,
> > > > > +};
> > > > > +
> > > > >  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > > > >                    struct intel_connector *intel_connector)
> > > > >  {
> > > > > @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > > > >     if (!is_hdcp_supported(dev_priv, port))
> > > > >             return 0;
> > > > >
> > > > > -   if (!intel_dp_is_edp(intel_dp))
> > > > > +   if (intel_connector->mst_port)
> > > > > +           return intel_hdcp_init(intel_connector, port,
> > > > > +                                  &intel_dp_mst_hdcp_shim);
> > > > > +   else if (!intel_dp_is_edp(intel_dp))
> > > > >             return intel_hdcp_init(intel_connector, port,
> > > > >                                    &intel_dp_hdcp_shim);
> > > > >
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > index 0675825dcc20..abaaeeb963d2 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > @@ -37,6 +37,7 @@
> > > > >  #include "intel_dp.h"
> > > > >  #include "intel_dp_mst.h"
> > > > >  #include "intel_dpio_phy.h"
> > > > > +#include "intel_hdcp.h"
> > > > >
> > > > >  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > > > >                                         struct intel_crtc_state *crtc_state,
> > > > > @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
> > > > >     drm_dbg_kms(&i915->drm, "active links %d\n",
> > > > >                 intel_dp->active_mst_links);
> > > > >
> > > > > +   intel_hdcp_disable(intel_mst->connector);
> > > > > +
> > > > >     drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
> > > > >
> > > > >     ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> > > > > @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
> > > > >
> > > > >     if (pipe_config->has_audio)
> > > > >             intel_audio_codec_enable(encoder, pipe_config, conn_state);
> > > > > +
> > > > > +   /* Enable hdcp if it's desired */
> > > > > +   if (conn_state->content_protection ==
> > > > > +       DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > > > > +           intel_hdcp_enable(to_intel_connector(conn_state->connector),
> > > > > +                             pipe_config->cpu_transcoder,
> > > > > +                             (u8)conn_state->hdcp_content_type);
> > > > >  }
> > > > >
> > > > >  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> > > > > @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
> > > > >     intel_attach_force_audio_property(connector);
> > > > >     intel_attach_broadcast_rgb_property(connector);
> > > > >
> > > > > +
> > > > > +   /* TODO: Figure out how to make HDCP work on GEN12+ */
> > > > > +   if (INTEL_GEN(dev_priv) < 12) {
> > > > > +           ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> > > > > +           if (ret)
> > > > > +                   DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> > > > > +   }
> > > > > +
> > > > >     /*
> > > > >      * Reuse the prop from the SST connector because we're
> > > > >      * not allowed to create new props after device registration.
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > > index 6bd0e4616ee1..ddc9db8de2bc 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > > @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
> > > > >     if (!shim)
> > > > >             return -EINVAL;
> > > > >
> > > > > -   if (is_hdcp2_supported(dev_priv))
> > > > > +   if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
> > > > >             intel_hdcp2_init(connector, port, shim);
> > > > >
> > > > >     ret =
> > > > > --
> > > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > > >
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
@ 2020-08-12 17:21             ` Sean Paul
  0 siblings, 0 replies; 98+ messages in thread
From: Sean Paul @ 2020-08-12 17:21 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: intel-gfx, Sean Paul, dri-devel, daniel.vetter

On Wed, Aug 12, 2020 at 3:15 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
>
> On 2020-08-11 at 13:28:46 -0400, Sean Paul wrote:
> > On Thu, Jul 9, 2020 at 8:40 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
> > >
> >
> > \snip
> >
> > > > > +static int
> > > > > +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> > > > > +                               enum transcoder cpu_transcoder,
> > > > > +                               bool enable)
> > > > > +{
> > > > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > > > +   int ret;
> > > > > +
> > > > > +   if (!enable)
> > > > > +           usleep_range(6, 60); /* Bspec says >= 6us */
> > > > > +
> > > > > +   ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> > > > > +                                          cpu_transcoder, enable);
> > > > Sean,
> > > >
> > > > This function toggles the TRANS_DDI_HDCP_SIGNALLING (9th)bit of TRANS_DDI_FUNC_CTL(tran)
> > > > But in the hw specification this bit is mentioned to be ignored for non
> > > > HDMI/DVI modes of the TRANS DDI.
> > > >
> > > > Any reason why we need this? Did you try with out this function?
> > > >
> >
> > Under "Authentication Part 1 for Multi-stream DisplayPort", bspec says:
> > 2. Select HDCP for the desired stream using the Pipe DDI Function
> > Control register.
> This is the 5th bit (Multistream HDCP Select) of Pipe DDI Function Control register i.e
> TRANS_DDI_FUNC_CTL register. This bit ensures HDCP encryption to this transcoder stream when used in
> multistream DisplayPort mode.
> Unfortunately public specs of Gen11 has discrepency and doesn't describe this bit.
> https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-icllp-vol02c-commandreference-registers-part2_0.pdf
> Page No.1026 TRANS_DDI_FUNC_CTL
> >
> > > > Apart from that Patch looks good to me.
> > > IMHO it seems we are still missing to enable the Multistream HDCP Select
> > > bit (5) in TRANS_DDI_FUNC_CTL register which is required to enable the
> > > stream encryption.
> > >
> >
> > Could you send me some docs on this? I don't see have info on this bit.
> This bit is not described in above mentioned public spec, but neither bit TRANS_DDI_HDCP_SIGNALLING bit (9th)
> which used in this patch, what is the source of public B.spec you are following?

I think it's been removed from public now, but there was a public doc
on Intel's site when I originally wrote these which described the
TRANS_DDI_FUNC_CTL register.

So do I just need to set bit 5 at the same time as the HDCP SIGNALLING bit?

Sean

> Thanks,
> Anshuman Gupta.
> >
> > Sean
> >
> > > Thanks,
> > > Anshuman Gupta.
> > > >
> > > > -Ram
> > > >
> > > > > +   if (ret)
> > > > > +           drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> > > > > +                         enable ? "Enable" : "Disable", ret);
> > > > > +   return ret;
> > > > > +}
> > > > > +
> > > > > +static
> > > > > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> > > > > +                             struct intel_connector *connector)
> > > > > +{
> > > > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > > > +   struct intel_dp *intel_dp = &intel_dig_port->dp;
> > > > > +   struct drm_dp_query_stream_enc_status_ack_reply reply;
> > > > > +   int ret;
> > > > > +
> > > > > +   if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> > > > > +           return false;
> > > > > +
> > > > > +   ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> > > > > +                                             connector->port, &reply);
> > > > > +   if (ret) {
> > > > > +           drm_dbg_kms(&i915->drm,
> > > > > +                       "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> > > > > +                       connector->base.base.id, connector->base.name, ret);
> > > > > +           return false;
> > > > > +   }
> > > > > +
> > > > > +   return reply.auth_completed && reply.encryption_enabled;
> > > > > +}
> > > > > +
> > > > > +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> > > > > +   .write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > > > > +   .read_bksv = intel_dp_hdcp_read_bksv,
> > > > > +   .read_bstatus = intel_dp_hdcp_read_bstatus,
> > > > > +   .repeater_present = intel_dp_hdcp_repeater_present,
> > > > > +   .read_ri_prime = intel_dp_hdcp_read_ri_prime,
> > > > > +   .read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> > > > > +   .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> > > > > +   .read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> > > > > +   .toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> > > > > +   .check_link = intel_dp_mst_hdcp_check_link,
> > > > > +   .hdcp_capable = intel_dp_hdcp_capable,
> > > > > +
> > > > > +   .protocol = HDCP_PROTOCOL_DP,
> > > > > +};
> > > > > +
> > > > >  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > > > >                    struct intel_connector *intel_connector)
> > > > >  {
> > > > > @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > > > >     if (!is_hdcp_supported(dev_priv, port))
> > > > >             return 0;
> > > > >
> > > > > -   if (!intel_dp_is_edp(intel_dp))
> > > > > +   if (intel_connector->mst_port)
> > > > > +           return intel_hdcp_init(intel_connector, port,
> > > > > +                                  &intel_dp_mst_hdcp_shim);
> > > > > +   else if (!intel_dp_is_edp(intel_dp))
> > > > >             return intel_hdcp_init(intel_connector, port,
> > > > >                                    &intel_dp_hdcp_shim);
> > > > >
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > index 0675825dcc20..abaaeeb963d2 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > @@ -37,6 +37,7 @@
> > > > >  #include "intel_dp.h"
> > > > >  #include "intel_dp_mst.h"
> > > > >  #include "intel_dpio_phy.h"
> > > > > +#include "intel_hdcp.h"
> > > > >
> > > > >  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > > > >                                         struct intel_crtc_state *crtc_state,
> > > > > @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
> > > > >     drm_dbg_kms(&i915->drm, "active links %d\n",
> > > > >                 intel_dp->active_mst_links);
> > > > >
> > > > > +   intel_hdcp_disable(intel_mst->connector);
> > > > > +
> > > > >     drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
> > > > >
> > > > >     ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> > > > > @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
> > > > >
> > > > >     if (pipe_config->has_audio)
> > > > >             intel_audio_codec_enable(encoder, pipe_config, conn_state);
> > > > > +
> > > > > +   /* Enable hdcp if it's desired */
> > > > > +   if (conn_state->content_protection ==
> > > > > +       DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > > > > +           intel_hdcp_enable(to_intel_connector(conn_state->connector),
> > > > > +                             pipe_config->cpu_transcoder,
> > > > > +                             (u8)conn_state->hdcp_content_type);
> > > > >  }
> > > > >
> > > > >  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> > > > > @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
> > > > >     intel_attach_force_audio_property(connector);
> > > > >     intel_attach_broadcast_rgb_property(connector);
> > > > >
> > > > > +
> > > > > +   /* TODO: Figure out how to make HDCP work on GEN12+ */
> > > > > +   if (INTEL_GEN(dev_priv) < 12) {
> > > > > +           ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> > > > > +           if (ret)
> > > > > +                   DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> > > > > +   }
> > > > > +
> > > > >     /*
> > > > >      * Reuse the prop from the SST connector because we're
> > > > >      * not allowed to create new props after device registration.
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > > index 6bd0e4616ee1..ddc9db8de2bc 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > > @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
> > > > >     if (!shim)
> > > > >             return -EINVAL;
> > > > >
> > > > > -   if (is_hdcp2_supported(dev_priv))
> > > > > +   if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
> > > > >             intel_hdcp2_init(connector, port, shim);
> > > > >
> > > > >     ret =
> > > > > --
> > > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > > >
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
  2020-08-12 17:21             ` Sean Paul
@ 2020-08-13  9:17               ` Anshuman Gupta
  -1 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-08-13  9:17 UTC (permalink / raw)
  To: Sean Paul; +Cc: intel-gfx, Sean Paul, dri-devel, daniel.vetter

On 2020-08-12 at 13:21:51 -0400, Sean Paul wrote:
> On Wed, Aug 12, 2020 at 3:15 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
> >
> > On 2020-08-11 at 13:28:46 -0400, Sean Paul wrote:
> > > On Thu, Jul 9, 2020 at 8:40 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
> > > >
> > >
> > > \snip
> > >
> > > > > > +static int
> > > > > > +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> > > > > > +                               enum transcoder cpu_transcoder,
> > > > > > +                               bool enable)
> > > > > > +{
> > > > > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > > > > +   int ret;
> > > > > > +
> > > > > > +   if (!enable)
> > > > > > +           usleep_range(6, 60); /* Bspec says >= 6us */
> > > > > > +
> > > > > > +   ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> > > > > > +                                          cpu_transcoder, enable);
> > > > > Sean,
> > > > >
> > > > > This function toggles the TRANS_DDI_HDCP_SIGNALLING (9th)bit of TRANS_DDI_FUNC_CTL(tran)
> > > > > But in the hw specification this bit is mentioned to be ignored for non
> > > > > HDMI/DVI modes of the TRANS DDI.
> > > > >
> > > > > Any reason why we need this? Did you try with out this function?
> > > > >
> > >
> > > Under "Authentication Part 1 for Multi-stream DisplayPort", bspec says:
> > > 2. Select HDCP for the desired stream using the Pipe DDI Function
> > > Control register.
> > This is the 5th bit (Multistream HDCP Select) of Pipe DDI Function Control register i.e
> > TRANS_DDI_FUNC_CTL register. This bit ensures HDCP encryption to this transcoder stream when used in
> > multistream DisplayPort mode.
> > Unfortunately public specs of Gen11 has discrepency and doesn't describe this bit.
> > https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-icllp-vol02c-commandreference-registers-part2_0.pdf
> > Page No.1026 TRANS_DDI_FUNC_CTL
> > >
> > > > > Apart from that Patch looks good to me.
> > > > IMHO it seems we are still missing to enable the Multistream HDCP Select
> > > > bit (5) in TRANS_DDI_FUNC_CTL register which is required to enable the
> > > > stream encryption.
> > > >
> > >
> > > Could you send me some docs on this? I don't see have info on this bit.
> > This bit is not described in above mentioned public spec, but neither bit TRANS_DDI_HDCP_SIGNALLING bit (9th)
> > which used in this patch, what is the source of public B.spec you are following?
> 
> I think it's been removed from public now, but there was a public doc
> on Intel's site when I originally wrote these which described the
> TRANS_DDI_FUNC_CTL register.
> 
> So do I just need to set bit 5 at the same time as the HDCP SIGNALLING bit?
Yes that should be the ideal way with respect to B.Specs Documentation but
as you had already tested it and stream level encryption is confirmed via
QUERY_STREAM_ENCRYPTION_STATUS sideband message, considering that it is really confusing
whether HDCP select bit required to be set for each stream.
I feel based upon your test results this patch should be good to be merged.
if any iterative development will be required, it can be pursued later. 
Either way, 
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>  
> 
> Sean
> 
> > Thanks,
> > Anshuman Gupta.
> > >
> > > Sean
> > >
> > > > Thanks,
> > > > Anshuman Gupta.
> > > > >
> > > > > -Ram
> > > > >
> > > > > > +   if (ret)
> > > > > > +           drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> > > > > > +                         enable ? "Enable" : "Disable", ret);
> > > > > > +   return ret;
> > > > > > +}
> > > > > > +
> > > > > > +static
> > > > > > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> > > > > > +                             struct intel_connector *connector)
> > > > > > +{
> > > > > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > > > > +   struct intel_dp *intel_dp = &intel_dig_port->dp;
> > > > > > +   struct drm_dp_query_stream_enc_status_ack_reply reply;
> > > > > > +   int ret;
> > > > > > +
> > > > > > +   if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> > > > > > +           return false;
> > > > > > +
> > > > > > +   ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> > > > > > +                                             connector->port, &reply);
> > > > > > +   if (ret) {
> > > > > > +           drm_dbg_kms(&i915->drm,
> > > > > > +                       "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> > > > > > +                       connector->base.base.id, connector->base.name, ret);
> > > > > > +           return false;
> > > > > > +   }
> > > > > > +
> > > > > > +   return reply.auth_completed && reply.encryption_enabled;
> > > > > > +}
> > > > > > +
> > > > > > +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> > > > > > +   .write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > > > > > +   .read_bksv = intel_dp_hdcp_read_bksv,
> > > > > > +   .read_bstatus = intel_dp_hdcp_read_bstatus,
> > > > > > +   .repeater_present = intel_dp_hdcp_repeater_present,
> > > > > > +   .read_ri_prime = intel_dp_hdcp_read_ri_prime,
> > > > > > +   .read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> > > > > > +   .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> > > > > > +   .read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> > > > > > +   .toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> > > > > > +   .check_link = intel_dp_mst_hdcp_check_link,
> > > > > > +   .hdcp_capable = intel_dp_hdcp_capable,
> > > > > > +
> > > > > > +   .protocol = HDCP_PROTOCOL_DP,
> > > > > > +};
> > > > > > +
> > > > > >  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > > > > >                    struct intel_connector *intel_connector)
> > > > > >  {
> > > > > > @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > > > > >     if (!is_hdcp_supported(dev_priv, port))
> > > > > >             return 0;
> > > > > >
> > > > > > -   if (!intel_dp_is_edp(intel_dp))
> > > > > > +   if (intel_connector->mst_port)
> > > > > > +           return intel_hdcp_init(intel_connector, port,
> > > > > > +                                  &intel_dp_mst_hdcp_shim);
> > > > > > +   else if (!intel_dp_is_edp(intel_dp))
> > > > > >             return intel_hdcp_init(intel_connector, port,
> > > > > >                                    &intel_dp_hdcp_shim);
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > index 0675825dcc20..abaaeeb963d2 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > @@ -37,6 +37,7 @@
> > > > > >  #include "intel_dp.h"
> > > > > >  #include "intel_dp_mst.h"
> > > > > >  #include "intel_dpio_phy.h"
> > > > > > +#include "intel_hdcp.h"
> > > > > >
> > > > > >  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > > > > >                                         struct intel_crtc_state *crtc_state,
> > > > > > @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
> > > > > >     drm_dbg_kms(&i915->drm, "active links %d\n",
> > > > > >                 intel_dp->active_mst_links);
> > > > > >
> > > > > > +   intel_hdcp_disable(intel_mst->connector);
> > > > > > +
> > > > > >     drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
> > > > > >
> > > > > >     ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> > > > > > @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
> > > > > >
> > > > > >     if (pipe_config->has_audio)
> > > > > >             intel_audio_codec_enable(encoder, pipe_config, conn_state);
> > > > > > +
> > > > > > +   /* Enable hdcp if it's desired */
> > > > > > +   if (conn_state->content_protection ==
> > > > > > +       DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > > > > > +           intel_hdcp_enable(to_intel_connector(conn_state->connector),
> > > > > > +                             pipe_config->cpu_transcoder,
> > > > > > +                             (u8)conn_state->hdcp_content_type);
> > > > > >  }
> > > > > >
> > > > > >  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> > > > > > @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
> > > > > >     intel_attach_force_audio_property(connector);
> > > > > >     intel_attach_broadcast_rgb_property(connector);
> > > > > >
> > > > > > +
> > > > > > +   /* TODO: Figure out how to make HDCP work on GEN12+ */
> > > > > > +   if (INTEL_GEN(dev_priv) < 12) {
> > > > > > +           ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> > > > > > +           if (ret)
> > > > > > +                   DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> > > > > > +   }
> > > > > > +
> > > > > >     /*
> > > > > >      * Reuse the prop from the SST connector because we're
> > > > > >      * not allowed to create new props after device registration.
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > > > index 6bd0e4616ee1..ddc9db8de2bc 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > > > @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
> > > > > >     if (!shim)
> > > > > >             return -EINVAL;
> > > > > >
> > > > > > -   if (is_hdcp2_supported(dev_priv))
> > > > > > +   if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
> > > > > >             intel_hdcp2_init(connector, port, shim);
> > > > > >
> > > > > >     ret =
> > > > > > --
> > > > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > > > >
> > > > > _______________________________________________
> > > > > Intel-gfx mailing list
> > > > > Intel-gfx@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Intel-gfx] [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors
@ 2020-08-13  9:17               ` Anshuman Gupta
  0 siblings, 0 replies; 98+ messages in thread
From: Anshuman Gupta @ 2020-08-13  9:17 UTC (permalink / raw)
  To: Sean Paul; +Cc: intel-gfx, Sean Paul, dri-devel, daniel.vetter

On 2020-08-12 at 13:21:51 -0400, Sean Paul wrote:
> On Wed, Aug 12, 2020 at 3:15 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
> >
> > On 2020-08-11 at 13:28:46 -0400, Sean Paul wrote:
> > > On Thu, Jul 9, 2020 at 8:40 AM Anshuman Gupta <anshuman.gupta@intel.com> wrote:
> > > >
> > >
> > > \snip
> > >
> > > > > > +static int
> > > > > > +intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
> > > > > > +                               enum transcoder cpu_transcoder,
> > > > > > +                               bool enable)
> > > > > > +{
> > > > > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > > > > +   int ret;
> > > > > > +
> > > > > > +   if (!enable)
> > > > > > +           usleep_range(6, 60); /* Bspec says >= 6us */
> > > > > > +
> > > > > > +   ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
> > > > > > +                                          cpu_transcoder, enable);
> > > > > Sean,
> > > > >
> > > > > This function toggles the TRANS_DDI_HDCP_SIGNALLING (9th)bit of TRANS_DDI_FUNC_CTL(tran)
> > > > > But in the hw specification this bit is mentioned to be ignored for non
> > > > > HDMI/DVI modes of the TRANS DDI.
> > > > >
> > > > > Any reason why we need this? Did you try with out this function?
> > > > >
> > >
> > > Under "Authentication Part 1 for Multi-stream DisplayPort", bspec says:
> > > 2. Select HDCP for the desired stream using the Pipe DDI Function
> > > Control register.
> > This is the 5th bit (Multistream HDCP Select) of Pipe DDI Function Control register i.e
> > TRANS_DDI_FUNC_CTL register. This bit ensures HDCP encryption to this transcoder stream when used in
> > multistream DisplayPort mode.
> > Unfortunately public specs of Gen11 has discrepency and doesn't describe this bit.
> > https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-icllp-vol02c-commandreference-registers-part2_0.pdf
> > Page No.1026 TRANS_DDI_FUNC_CTL
> > >
> > > > > Apart from that Patch looks good to me.
> > > > IMHO it seems we are still missing to enable the Multistream HDCP Select
> > > > bit (5) in TRANS_DDI_FUNC_CTL register which is required to enable the
> > > > stream encryption.
> > > >
> > >
> > > Could you send me some docs on this? I don't see have info on this bit.
> > This bit is not described in above mentioned public spec, but neither bit TRANS_DDI_HDCP_SIGNALLING bit (9th)
> > which used in this patch, what is the source of public B.spec you are following?
> 
> I think it's been removed from public now, but there was a public doc
> on Intel's site when I originally wrote these which described the
> TRANS_DDI_FUNC_CTL register.
> 
> So do I just need to set bit 5 at the same time as the HDCP SIGNALLING bit?
Yes that should be the ideal way with respect to B.Specs Documentation but
as you had already tested it and stream level encryption is confirmed via
QUERY_STREAM_ENCRYPTION_STATUS sideband message, considering that it is really confusing
whether HDCP select bit required to be set for each stream.
I feel based upon your test results this patch should be good to be merged.
if any iterative development will be required, it can be pursued later. 
Either way, 
Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com>  
> 
> Sean
> 
> > Thanks,
> > Anshuman Gupta.
> > >
> > > Sean
> > >
> > > > Thanks,
> > > > Anshuman Gupta.
> > > > >
> > > > > -Ram
> > > > >
> > > > > > +   if (ret)
> > > > > > +           drm_dbg_kms(&i915->drm, "%s HDCP signalling failed (%d)\n",
> > > > > > +                         enable ? "Enable" : "Disable", ret);
> > > > > > +   return ret;
> > > > > > +}
> > > > > > +
> > > > > > +static
> > > > > > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *intel_dig_port,
> > > > > > +                             struct intel_connector *connector)
> > > > > > +{
> > > > > > +   struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
> > > > > > +   struct intel_dp *intel_dp = &intel_dig_port->dp;
> > > > > > +   struct drm_dp_query_stream_enc_status_ack_reply reply;
> > > > > > +   int ret;
> > > > > > +
> > > > > > +   if (!intel_dp_hdcp_check_link(intel_dig_port, connector))
> > > > > > +           return false;
> > > > > > +
> > > > > > +   ret = drm_dp_send_query_stream_enc_status(&intel_dp->mst_mgr,
> > > > > > +                                             connector->port, &reply);
> > > > > > +   if (ret) {
> > > > > > +           drm_dbg_kms(&i915->drm,
> > > > > > +                       "[CONNECTOR:%d:%s] failed QSES ret=%d\n",
> > > > > > +                       connector->base.base.id, connector->base.name, ret);
> > > > > > +           return false;
> > > > > > +   }
> > > > > > +
> > > > > > +   return reply.auth_completed && reply.encryption_enabled;
> > > > > > +}
> > > > > > +
> > > > > > +static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
> > > > > > +   .write_an_aksv = intel_dp_hdcp_write_an_aksv,
> > > > > > +   .read_bksv = intel_dp_hdcp_read_bksv,
> > > > > > +   .read_bstatus = intel_dp_hdcp_read_bstatus,
> > > > > > +   .repeater_present = intel_dp_hdcp_repeater_present,
> > > > > > +   .read_ri_prime = intel_dp_hdcp_read_ri_prime,
> > > > > > +   .read_ksv_ready = intel_dp_hdcp_read_ksv_ready,
> > > > > > +   .read_ksv_fifo = intel_dp_hdcp_read_ksv_fifo,
> > > > > > +   .read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
> > > > > > +   .toggle_signalling = intel_dp_mst_hdcp_toggle_signalling,
> > > > > > +   .check_link = intel_dp_mst_hdcp_check_link,
> > > > > > +   .hdcp_capable = intel_dp_hdcp_capable,
> > > > > > +
> > > > > > +   .protocol = HDCP_PROTOCOL_DP,
> > > > > > +};
> > > > > > +
> > > > > >  int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > > > > >                    struct intel_connector *intel_connector)
> > > > > >  {
> > > > > > @@ -630,7 +691,10 @@ int intel_dp_init_hdcp(struct intel_digital_port *intel_dig_port,
> > > > > >     if (!is_hdcp_supported(dev_priv, port))
> > > > > >             return 0;
> > > > > >
> > > > > > -   if (!intel_dp_is_edp(intel_dp))
> > > > > > +   if (intel_connector->mst_port)
> > > > > > +           return intel_hdcp_init(intel_connector, port,
> > > > > > +                                  &intel_dp_mst_hdcp_shim);
> > > > > > +   else if (!intel_dp_is_edp(intel_dp))
> > > > > >             return intel_hdcp_init(intel_connector, port,
> > > > > >                                    &intel_dp_hdcp_shim);
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > index 0675825dcc20..abaaeeb963d2 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > > > @@ -37,6 +37,7 @@
> > > > > >  #include "intel_dp.h"
> > > > > >  #include "intel_dp_mst.h"
> > > > > >  #include "intel_dpio_phy.h"
> > > > > > +#include "intel_hdcp.h"
> > > > > >
> > > > > >  static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> > > > > >                                         struct intel_crtc_state *crtc_state,
> > > > > > @@ -352,6 +353,8 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
> > > > > >     drm_dbg_kms(&i915->drm, "active links %d\n",
> > > > > >                 intel_dp->active_mst_links);
> > > > > >
> > > > > > +   intel_hdcp_disable(intel_mst->connector);
> > > > > > +
> > > > > >     drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
> > > > > >
> > > > > >     ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
> > > > > > @@ -548,6 +551,13 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
> > > > > >
> > > > > >     if (pipe_config->has_audio)
> > > > > >             intel_audio_codec_enable(encoder, pipe_config, conn_state);
> > > > > > +
> > > > > > +   /* Enable hdcp if it's desired */
> > > > > > +   if (conn_state->content_protection ==
> > > > > > +       DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > > > > > +           intel_hdcp_enable(to_intel_connector(conn_state->connector),
> > > > > > +                             pipe_config->cpu_transcoder,
> > > > > > +                             (u8)conn_state->hdcp_content_type);
> > > > > >  }
> > > > > >
> > > > > >  static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
> > > > > > @@ -770,6 +780,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
> > > > > >     intel_attach_force_audio_property(connector);
> > > > > >     intel_attach_broadcast_rgb_property(connector);
> > > > > >
> > > > > > +
> > > > > > +   /* TODO: Figure out how to make HDCP work on GEN12+ */
> > > > > > +   if (INTEL_GEN(dev_priv) < 12) {
> > > > > > +           ret = intel_dp_init_hdcp(intel_dig_port, intel_connector);
> > > > > > +           if (ret)
> > > > > > +                   DRM_DEBUG_KMS("HDCP init failed, skipping.\n");
> > > > > > +   }
> > > > > > +
> > > > > >     /*
> > > > > >      * Reuse the prop from the SST connector because we're
> > > > > >      * not allowed to create new props after device registration.
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > > > index 6bd0e4616ee1..ddc9db8de2bc 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > > > > > @@ -2060,7 +2060,7 @@ int intel_hdcp_init(struct intel_connector *connector,
> > > > > >     if (!shim)
> > > > > >             return -EINVAL;
> > > > > >
> > > > > > -   if (is_hdcp2_supported(dev_priv))
> > > > > > +   if (is_hdcp2_supported(dev_priv) && !connector->mst_port)
> > > > > >             intel_hdcp2_init(connector, port, shim);
> > > > > >
> > > > > >     ret =
> > > > > > --
> > > > > > Sean Paul, Software Engineer, Google / Chromium OS
> > > > > >
> > > > > _______________________________________________
> > > > > Intel-gfx mailing list
> > > > > Intel-gfx@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

end of thread, other threads:[~2020-08-13  9:29 UTC | newest]

Thread overview: 98+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-23 15:58 [PATCH v7 00/17] drm/i915: Add support for HDCP 1.4 over MST Sean Paul
2020-06-23 15:58 ` [Intel-gfx] " Sean Paul
2020-06-23 15:58 ` [PATCH v7 01/17] drm/i915: Fix sha_text population code Sean Paul
2020-06-23 15:58   ` [Intel-gfx] " Sean Paul
2020-06-23 15:58   ` Sean Paul
2020-06-25 14:53   ` Sasha Levin
2020-06-25 14:53     ` [Intel-gfx] " Sasha Levin
2020-06-25 14:53     ` Sasha Levin
2020-06-23 15:58 ` [PATCH v7 02/17] drm/i915: Clear the repeater bit on HDCP disable Sean Paul
2020-06-23 15:58   ` [Intel-gfx] " Sean Paul
2020-06-23 15:58   ` Sean Paul
2020-06-25 14:53   ` Sasha Levin
2020-06-25 14:53     ` [Intel-gfx] " Sasha Levin
2020-06-25 14:53     ` Sasha Levin
2020-06-23 15:58 ` [PATCH v7 03/17] drm/i915: WARN if HDCP signalling is enabled upon disable Sean Paul
2020-06-23 15:58   ` [Intel-gfx] " Sean Paul
2020-06-23 15:58 ` [PATCH v7 04/17] drm/i915: Intercept Aksv writes in the aux hooks Sean Paul
2020-06-23 15:58   ` [Intel-gfx] " Sean Paul
2020-06-23 15:58 ` [PATCH v7 05/17] drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling Sean Paul
2020-06-23 15:58   ` [Intel-gfx] " Sean Paul
2020-06-23 15:58 ` [PATCH v7 06/17] drm/i915: Factor out hdcp->value assignments Sean Paul
2020-06-23 15:58   ` [Intel-gfx] " Sean Paul
2020-06-23 15:58 ` [PATCH v7 07/17] drm/i915: Protect workers against disappearing connectors Sean Paul
2020-06-23 15:58   ` [Intel-gfx] " Sean Paul
2020-06-23 15:58 ` [PATCH v7 08/17] drm/i915: Clean up intel_hdcp_disable Sean Paul
2020-06-23 15:58   ` [Intel-gfx] " Sean Paul
2020-07-03 11:36   ` Anshuman Gupta
2020-07-03 11:36     ` Anshuman Gupta
2020-07-09  5:40   ` Ramalingam C
2020-07-09  5:40     ` [Intel-gfx] " Ramalingam C
2020-06-23 15:58 ` [PATCH v7 09/17] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it Sean Paul
2020-06-23 15:58   ` [Intel-gfx] " Sean Paul
2020-07-09  5:57   ` Ramalingam C
2020-07-09  5:57     ` [Intel-gfx] " Ramalingam C
2020-06-23 15:59 ` [PATCH v7 10/17] drm/i915: Support DP MST in enc_to_dig_port() function Sean Paul
2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
2020-07-09 10:16   ` Ramalingam C
2020-07-09 10:16     ` [Intel-gfx] " Ramalingam C
2020-06-23 15:59 ` [PATCH v7 11/17] drm/i915: Use ddi_update_pipe in intel_dp_mst Sean Paul
2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
2020-07-09 10:49   ` C, Ramalingam
2020-07-09 10:49     ` [Intel-gfx] " C, Ramalingam
2020-06-23 15:59 ` [PATCH v7 12/17] drm/i915: Factor out HDCP shim functions from dp for use by dp_mst Sean Paul
2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
2020-07-09 10:51   ` C, Ramalingam
2020-07-09 10:51     ` [Intel-gfx] " C, Ramalingam
2020-06-23 15:59 ` [PATCH v7 13/17] drm/i915: Plumb port through hdcp init Sean Paul
2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
2020-07-03 10:22   ` Anshuman Gupta
2020-07-03 10:22     ` Anshuman Gupta
2020-07-09 10:55   ` Ramalingam C
2020-07-09 10:55     ` [Intel-gfx] " Ramalingam C
2020-06-23 15:59 ` [PATCH v7 14/17] drm/i915: Add connector to hdcp_shim->check_link() Sean Paul
2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
2020-07-03 10:13   ` Anshuman Gupta
2020-07-03 10:13     ` Anshuman Gupta
2020-07-09 10:56   ` C, Ramalingam
2020-07-09 10:56     ` [Intel-gfx] " C, Ramalingam
2020-06-23 15:59 ` [PATCH v7 15/17] drm/mst: Add support for QUERY_STREAM_ENCRYPTION_STATUS MST sideband message Sean Paul
2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
2020-06-30 14:09   ` Anshuman Gupta
2020-06-30 14:09     ` Anshuman Gupta
2020-06-30 16:48     ` Sean Paul
2020-06-30 16:48       ` Sean Paul
2020-07-02 14:37       ` Anshuman Gupta
2020-07-02 14:37         ` Anshuman Gupta
2020-07-09 12:58         ` Anshuman Gupta
2020-07-09 12:58           ` Anshuman Gupta
2020-08-11 17:21           ` Sean Paul
2020-08-11 17:21             ` Sean Paul
2020-08-12  8:18             ` Anshuman Gupta
2020-08-12  8:18               ` Anshuman Gupta
2020-08-11 14:43         ` Sean Paul
2020-08-11 14:43           ` Sean Paul
2020-06-23 15:59 ` [PATCH v7 16/17] drm/i915: Print HDCP version info for all connectors Sean Paul
2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
2020-06-23 15:59 ` [PATCH v7 17/17] drm/i915: Add HDCP 1.4 support for MST connectors Sean Paul
2020-06-23 15:59   ` [Intel-gfx] " Sean Paul
2020-07-03 11:18   ` Anshuman Gupta
2020-07-03 11:18     ` Anshuman Gupta
2020-07-03 14:55     ` Anshuman Gupta
2020-07-03 14:55       ` Anshuman Gupta
2020-07-09 10:37   ` Ramalingam C
2020-07-09 10:37     ` [Intel-gfx] " Ramalingam C
2020-07-09 12:28     ` Anshuman Gupta
2020-07-09 12:28       ` Anshuman Gupta
2020-08-11 17:28       ` Sean Paul
2020-08-11 17:28         ` Sean Paul
2020-08-12  7:03         ` Anshuman Gupta
2020-08-12  7:03           ` Anshuman Gupta
2020-08-12 17:21           ` Sean Paul
2020-08-12 17:21             ` Sean Paul
2020-08-13  9:17             ` Anshuman Gupta
2020-08-13  9:17               ` Anshuman Gupta
2020-06-23 16:38 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add support for HDCP 1.4 over MST Patchwork
2020-06-23 16:39 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-06-23 16:58 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-06-24  2:15 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.