All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/12] drm/i915: Add support for HDCP 1.4 over MST connectors
@ 2019-12-12 19:02 ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

Hello again,
Here's the second version of my set to enable MST over HDCP. The big
changes stemmed from Ville's review. It was super helpful to get that
pushback, and led me to more critically debug the disable paths. As a
result, I think I chased a few more gremlins out of the system.
Individual commit messages have the v2 changes, so I won't enumerate
them here.

Thanks in advance,

Sean

v1 cover: https://lists.freedesktop.org/archives/dri-devel/2019-December/247501.html

Sean Paul (12):
  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: 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: Expose HDCP shim functions from dp for use by dp_mst
  drm/i915: Add HDCP 1.4 support for MST connectors

 drivers/gpu/drm/i915/display/intel_ddi.c      |  27 +--
 drivers/gpu/drm/i915/display/intel_ddi.h      |   2 +
 .../drm/i915/display/intel_display_types.h    |  47 ++++-
 drivers/gpu/drm/i915/display/intel_dp.c       |  79 ++++----
 drivers/gpu/drm/i915/display/intel_dp.h       |   6 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  90 +++++++++
 drivers/gpu/drm/i915/display/intel_hdcp.c     | 190 ++++++++++++++----
 drivers/gpu/drm/i915/display/intel_hdmi.c     |  18 +-
 include/drm/drm_hdcp.h                        |   3 +
 9 files changed, 352 insertions(+), 110 deletions(-)

-- 
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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 00/12] drm/i915: Add support for HDCP 1.4 over MST connectors
@ 2019-12-12 19:02 ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

Hello again,
Here's the second version of my set to enable MST over HDCP. The big
changes stemmed from Ville's review. It was super helpful to get that
pushback, and led me to more critically debug the disable paths. As a
result, I think I chased a few more gremlins out of the system.
Individual commit messages have the v2 changes, so I won't enumerate
them here.

Thanks in advance,

Sean

v1 cover: https://lists.freedesktop.org/archives/dri-devel/2019-December/247501.html

Sean Paul (12):
  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: 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: Expose HDCP shim functions from dp for use by dp_mst
  drm/i915: Add HDCP 1.4 support for MST connectors

 drivers/gpu/drm/i915/display/intel_ddi.c      |  27 +--
 drivers/gpu/drm/i915/display/intel_ddi.h      |   2 +
 .../drm/i915/display/intel_display_types.h    |  47 ++++-
 drivers/gpu/drm/i915/display/intel_dp.c       |  79 ++++----
 drivers/gpu/drm/i915/display/intel_dp.h       |   6 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |  90 +++++++++
 drivers/gpu/drm/i915/display/intel_hdcp.c     | 190 ++++++++++++++----
 drivers/gpu/drm/i915/display/intel_hdmi.c     |  18 +-
 include/drm/drm_hdcp.h                        |   3 +
 9 files changed, 352 insertions(+), 110 deletions(-)

-- 
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] 61+ messages in thread

* [PATCH v2 01/12] drm/i915: Fix sha_text population code
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
  (?)
@ 2019-12-12 19:02   ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx
  Cc: 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+
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-2-sean@poorly.run #v1

Changes in v2:
-None
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 25 +++++++++++++++++------
 include/drm/drm_hdcp.h                    |  3 +++
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 0fdbd39f6641..eaab9008feef 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -335,8 +335,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)
@@ -426,7 +428,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
 	} else if (sha_leftovers == 2) {
 		/* Write 32 bits of text */
 		I915_WRITE(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;
@@ -440,16 +442,27 @@ 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.
+		 */
+		I915_WRITE(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) */
 		I915_WRITE(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 */
 		I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_8);
 		ret = intel_write_sha_text(dev_priv, bstatus[1]);
 		if (ret < 0)
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 06a11202a097..20498c822204 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] 61+ messages in thread

* [PATCH v2 01/12] drm/i915: Fix sha_text population code
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, 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+
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-2-sean@poorly.run #v1

Changes in v2:
-None
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 25 +++++++++++++++++------
 include/drm/drm_hdcp.h                    |  3 +++
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 0fdbd39f6641..eaab9008feef 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -335,8 +335,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)
@@ -426,7 +428,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
 	} else if (sha_leftovers == 2) {
 		/* Write 32 bits of text */
 		I915_WRITE(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;
@@ -440,16 +442,27 @@ 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.
+		 */
+		I915_WRITE(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) */
 		I915_WRITE(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 */
 		I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_8);
 		ret = intel_write_sha_text(dev_priv, bstatus[1]);
 		if (ret < 0)
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 06a11202a097..20498c822204 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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 01/12] drm/i915: Fix sha_text population code
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: 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+
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-2-sean@poorly.run #v1

Changes in v2:
-None
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 25 +++++++++++++++++------
 include/drm/drm_hdcp.h                    |  3 +++
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 0fdbd39f6641..eaab9008feef 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -335,8 +335,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)
@@ -426,7 +428,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
 	} else if (sha_leftovers == 2) {
 		/* Write 32 bits of text */
 		I915_WRITE(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;
@@ -440,16 +442,27 @@ 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.
+		 */
+		I915_WRITE(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) */
 		I915_WRITE(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 */
 		I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_8);
 		ret = intel_write_sha_text(dev_priv, bstatus[1]);
 		if (ret < 0)
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 06a11202a097..20498c822204 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] 61+ messages in thread

* [PATCH v2 02/12] drm/i915: Clear the repeater bit on HDCP disable
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
  (?)
@ 2019-12-12 19:02   ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx
  Cc: 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+
Signed-off-by: Sean Paul <seanpaul@chromium.org>

Changes in v2:
-Added to the set
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index eaab9008feef..c4394c8e10eb 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -773,6 +773,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
 	enum port port = intel_dig_port->base.port;
 	enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
+	u32 repeater_ctl;
 	int ret;
 
 	DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
@@ -787,6 +788,10 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 		return -ETIMEDOUT;
 	}
 
+	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
+						   port);
+	I915_WRITE(HDCP_REP_CTL, I915_READ(HDCP_REP_CTL) & ~repeater_ctl);
+
 	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
 	if (ret) {
 		DRM_ERROR("Failed to disable HDCP signalling\n");
-- 
Sean Paul, Software Engineer, Google / Chromium OS


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

* [PATCH v2 02/12] drm/i915: Clear the repeater bit on HDCP disable
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, 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+
Signed-off-by: Sean Paul <seanpaul@chromium.org>

Changes in v2:
-Added to the set
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index eaab9008feef..c4394c8e10eb 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -773,6 +773,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
 	enum port port = intel_dig_port->base.port;
 	enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
+	u32 repeater_ctl;
 	int ret;
 
 	DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
@@ -787,6 +788,10 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 		return -ETIMEDOUT;
 	}
 
+	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
+						   port);
+	I915_WRITE(HDCP_REP_CTL, I915_READ(HDCP_REP_CTL) & ~repeater_ctl);
+
 	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
 	if (ret) {
 		DRM_ERROR("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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 02/12] drm/i915: Clear the repeater bit on HDCP disable
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: 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+
Signed-off-by: Sean Paul <seanpaul@chromium.org>

Changes in v2:
-Added to the set
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index eaab9008feef..c4394c8e10eb 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -773,6 +773,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
 	enum port port = intel_dig_port->base.port;
 	enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
+	u32 repeater_ctl;
 	int ret;
 
 	DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
@@ -787,6 +788,10 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 		return -ETIMEDOUT;
 	}
 
+	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
+						   port);
+	I915_WRITE(HDCP_REP_CTL, I915_READ(HDCP_REP_CTL) & ~repeater_ctl);
+
 	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
 	if (ret) {
 		DRM_ERROR("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] 61+ messages in thread

* [PATCH v2 03/12] drm/i915: WARN if HDCP signalling is enabled upon disable
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
@ 2019-12-12 19:02   ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, 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>
Signed-off-by: Sean Paul <seanpaul@chromium.org>

Changes in v2:
- Added to the set in lieu of just clearing the bit
---
 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 5b6f32517c75..4a5bdf3ef51d 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1951,6 +1951,8 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
 	i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
 	u32 val = I915_READ(reg);
 
+	WARN_ON(val & TRANS_DDI_HDCP_SIGNALLING);
+
 	if (INTEL_GEN(dev_priv) >= 12) {
 		val &= ~(TRANS_DDI_FUNC_ENABLE | TGL_TRANS_DDI_PORT_MASK |
 			 TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
-- 
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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 03/12] drm/i915: WARN if HDCP signalling is enabled upon disable
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 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>
Signed-off-by: Sean Paul <seanpaul@chromium.org>

Changes in v2:
- Added to the set in lieu of just clearing the bit
---
 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 5b6f32517c75..4a5bdf3ef51d 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1951,6 +1951,8 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
 	i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
 	u32 val = I915_READ(reg);
 
+	WARN_ON(val & TRANS_DDI_HDCP_SIGNALLING);
+
 	if (INTEL_GEN(dev_priv) >= 12) {
 		val &= ~(TRANS_DDI_FUNC_ENABLE | TGL_TRANS_DDI_PORT_MASK |
 			 TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
-- 
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] 61+ messages in thread

* [PATCH v2 04/12] drm/i915: Intercept Aksv writes in the aux hooks
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
@ 2019-12-12 19:02   ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, 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>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-3-sean@poorly.run #v1

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)
---
 drivers/gpu/drm/i915/display/intel_dp.c | 62 ++++++++++++-------------
 1 file changed, 29 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index fe31bbfd6c62..5576193b4fed 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1515,12 +1515,27 @@ 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)
 {
 	struct intel_dp *intel_dp = container_of(aux, struct intel_dp, aux);
 	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);
@@ -1541,7 +1556,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;
 
@@ -1564,7 +1579,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;
 			/*
@@ -5904,17 +5919,9 @@ static
 int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 				u8 *an)
 {
-	struct intel_dp *intel_dp = enc_to_intel_dp(&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) {
@@ -5924,29 +5931,18 @@ 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_DEBUG_KMS("Write Aksv over DP/AUX failed (%d)\n", ret);
-		return ret;
-	} else if (ret == 0) {
-		DRM_DEBUG_KMS("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) {
-		DRM_DEBUG_KMS("Aksv write: no DP_AUX_NATIVE_REPLY_ACK %x\n",
-			      reply);
-		return -EIO;
+	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_DEBUG_KMS("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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 04/12] drm/i915: Intercept Aksv writes in the aux hooks
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 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>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-3-sean@poorly.run #v1

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)
---
 drivers/gpu/drm/i915/display/intel_dp.c | 62 ++++++++++++-------------
 1 file changed, 29 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index fe31bbfd6c62..5576193b4fed 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1515,12 +1515,27 @@ 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)
 {
 	struct intel_dp *intel_dp = container_of(aux, struct intel_dp, aux);
 	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);
@@ -1541,7 +1556,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;
 
@@ -1564,7 +1579,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;
 			/*
@@ -5904,17 +5919,9 @@ static
 int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 				u8 *an)
 {
-	struct intel_dp *intel_dp = enc_to_intel_dp(&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) {
@@ -5924,29 +5931,18 @@ 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_DEBUG_KMS("Write Aksv over DP/AUX failed (%d)\n", ret);
-		return ret;
-	} else if (ret == 0) {
-		DRM_DEBUG_KMS("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) {
-		DRM_DEBUG_KMS("Aksv write: no DP_AUX_NATIVE_REPLY_ACK %x\n",
-			      reply);
-		return -EIO;
+	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_DEBUG_KMS("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] 61+ messages in thread

* [PATCH v2 05/12] drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
@ 2019-12-12 19:02   ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, 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>
Signed-off-by: Sean Paul <seanpaul@chromium.org>

Changes in v2:
- Added to the set
---
 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        | 11 +++++++----
 drivers/gpu/drm/i915/display/intel_hdmi.c        | 16 +++++++++++-----
 6 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 4a5bdf3ef51d..bbdaa6d1deec 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1971,12 +1971,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;
 
@@ -1985,18 +1985,13 @@ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
 	if (WARN_ON(!wakeref))
 		return -ENXIO;
 
-	if (WARN_ON(!intel_encoder->get_hw_state(intel_encoder, &pipe))) {
-		ret = -EIO;
-		goto out;
-	}
-
-	tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe));
+	tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (enable)
 		tmp |= TRANS_DDI_HDCP_SIGNALLING;
 	else
 		tmp &= ~TRANS_DDI_HDCP_SIGNALLING;
-	I915_WRITE(TRANS_DDI_FUNC_CTL(pipe), tmp);
-out:
+	I915_WRITE(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 19aeab1246ee..0644edaa7542 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -18,6 +18,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_encoder *intel_encoder,
 				const struct intel_crtc_state *old_crtc_state,
@@ -45,6 +46,7 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
 u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder,
 				 u8 voltage_swing);
 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);
 int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 83ea04149b77..687768a913f6 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -301,6 +301,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 5576193b4fed..c1a228b5f879 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6083,6 +6083,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 c4394c8e10eb..f8d56d3b2ddb 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -693,7 +693,7 @@ static int intel_hdcp_auth(struct intel_connector *connector)
 			   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;
 
@@ -792,7 +792,8 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 						   port);
 	I915_WRITE(HDCP_REP_CTL, I915_READ(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_ERROR("Failed to disable HDCP signalling\n");
 		return ret;
@@ -1552,7 +1553,8 @@ static int hdcp2_enable_encryption(struct intel_connector *connector)
 	WARN_ON(I915_READ(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_ERROR("Failed to enable HDCP signalling. %d\n",
 				  ret);
@@ -1603,7 +1605,8 @@ static int hdcp2_disable_encryption(struct intel_connector *connector)
 		DRM_DEBUG_KMS("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_ERROR("Failed to disable HDCP signalling. %d\n",
 				  ret);
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index a89a09b25260..5066efadca85 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -1443,7 +1443,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 = conn_to_dig_port(connector);
@@ -1460,12 +1461,14 @@ 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_ERROR("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_ERROR("Enable HDCP signalling failed (%d)\n", ret);
 		return ret;
@@ -1476,6 +1479,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;
@@ -1486,7 +1490,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_ERROR("%s HDCP signalling failed (%d)\n",
 			  enable ? "Enable" : "Disable", ret);
@@ -1498,7 +1503,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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 05/12] drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 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>
Signed-off-by: Sean Paul <seanpaul@chromium.org>

Changes in v2:
- Added to the set
---
 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        | 11 +++++++----
 drivers/gpu/drm/i915/display/intel_hdmi.c        | 16 +++++++++++-----
 6 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 4a5bdf3ef51d..bbdaa6d1deec 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1971,12 +1971,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;
 
@@ -1985,18 +1985,13 @@ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
 	if (WARN_ON(!wakeref))
 		return -ENXIO;
 
-	if (WARN_ON(!intel_encoder->get_hw_state(intel_encoder, &pipe))) {
-		ret = -EIO;
-		goto out;
-	}
-
-	tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe));
+	tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (enable)
 		tmp |= TRANS_DDI_HDCP_SIGNALLING;
 	else
 		tmp &= ~TRANS_DDI_HDCP_SIGNALLING;
-	I915_WRITE(TRANS_DDI_FUNC_CTL(pipe), tmp);
-out:
+	I915_WRITE(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 19aeab1246ee..0644edaa7542 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -18,6 +18,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_encoder *intel_encoder,
 				const struct intel_crtc_state *old_crtc_state,
@@ -45,6 +46,7 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
 u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder,
 				 u8 voltage_swing);
 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);
 int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 83ea04149b77..687768a913f6 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -301,6 +301,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 5576193b4fed..c1a228b5f879 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6083,6 +6083,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 c4394c8e10eb..f8d56d3b2ddb 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -693,7 +693,7 @@ static int intel_hdcp_auth(struct intel_connector *connector)
 			   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;
 
@@ -792,7 +792,8 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 						   port);
 	I915_WRITE(HDCP_REP_CTL, I915_READ(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_ERROR("Failed to disable HDCP signalling\n");
 		return ret;
@@ -1552,7 +1553,8 @@ static int hdcp2_enable_encryption(struct intel_connector *connector)
 	WARN_ON(I915_READ(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_ERROR("Failed to enable HDCP signalling. %d\n",
 				  ret);
@@ -1603,7 +1605,8 @@ static int hdcp2_disable_encryption(struct intel_connector *connector)
 		DRM_DEBUG_KMS("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_ERROR("Failed to disable HDCP signalling. %d\n",
 				  ret);
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index a89a09b25260..5066efadca85 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -1443,7 +1443,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 = conn_to_dig_port(connector);
@@ -1460,12 +1461,14 @@ 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_ERROR("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_ERROR("Enable HDCP signalling failed (%d)\n", ret);
 		return ret;
@@ -1476,6 +1479,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;
@@ -1486,7 +1490,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_ERROR("%s HDCP signalling failed (%d)\n",
 			  enable ? "Enable" : "Disable", ret);
@@ -1498,7 +1503,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] 61+ messages in thread

* [PATCH v2 06/12] drm/i915: Factor out hdcp->value assignments
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
@ 2019-12-12 19:02   ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, 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.

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

Changes in v2:
-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 f8d56d3b2ddb..798e7e1a19fc 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -852,6 +852,21 @@ 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;
+
+	WARN_ON(!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)
 {
@@ -878,15 +893,16 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 			  I915_READ(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;
 	}
@@ -897,16 +913,18 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 	ret = _intel_hdcp_disable(connector);
 	if (ret) {
 		DRM_ERROR("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_ERROR("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;
 	}
 
@@ -1716,16 +1734,18 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 			  I915_READ(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;
 	}
@@ -1737,8 +1757,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 		DRM_DEBUG_KMS("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_DEBUG_KMS("[%s:%d] Repeater topology auth failed.(%d)\n",
@@ -1753,8 +1774,8 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 	if (ret) {
 		DRM_ERROR("[%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;
 	}
 
@@ -1763,8 +1784,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 		DRM_DEBUG_KMS("[%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;
 	}
 
@@ -2004,8 +2026,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);
@@ -2023,7 +2046,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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 06/12] drm/i915: Factor out hdcp->value assignments
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 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.

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

Changes in v2:
-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 f8d56d3b2ddb..798e7e1a19fc 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -852,6 +852,21 @@ 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;
+
+	WARN_ON(!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)
 {
@@ -878,15 +893,16 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 			  I915_READ(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;
 	}
@@ -897,16 +913,18 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 	ret = _intel_hdcp_disable(connector);
 	if (ret) {
 		DRM_ERROR("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_ERROR("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;
 	}
 
@@ -1716,16 +1734,18 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 			  I915_READ(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;
 	}
@@ -1737,8 +1757,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 		DRM_DEBUG_KMS("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_DEBUG_KMS("[%s:%d] Repeater topology auth failed.(%d)\n",
@@ -1753,8 +1774,8 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 	if (ret) {
 		DRM_ERROR("[%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;
 	}
 
@@ -1763,8 +1784,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
 		DRM_DEBUG_KMS("[%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;
 	}
 
@@ -2004,8 +2026,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);
@@ -2023,7 +2046,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] 61+ messages in thread

* [PATCH v2 07/12] drm/i915: Protect workers against disappearing connectors
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
@ 2019-12-12 19:02   ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, 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.

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

Changes in v2:
- Added to the set
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 38 ++++++++++++++++++++---
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 798e7e1a19fc..c79dca2c74d1 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -863,8 +863,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 */
@@ -954,6 +956,8 @@ static void intel_hdcp_prop_work(struct work_struct *work)
 
 	mutex_unlock(&hdcp->mutex);
 	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+	drm_connector_put(&connector->base);
 }
 
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
@@ -1802,6 +1806,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);
@@ -2076,12 +2083,33 @@ 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);
+	WARN_ON(!drm_connector_is_unregistered(&connector->base));
+
+	/*
+	 * Now that the connector is unregistered, 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).
+	 */
+	WARN_ON(work_pending(&hdcp->prop_work));
+
+	mutex_lock(&hdcp->mutex);
+	kfree(hdcp->port_data.streams);
+	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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 07/12] drm/i915: Protect workers against disappearing connectors
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 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.

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

Changes in v2:
- Added to the set
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 38 ++++++++++++++++++++---
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 798e7e1a19fc..c79dca2c74d1 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -863,8 +863,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 */
@@ -954,6 +956,8 @@ static void intel_hdcp_prop_work(struct work_struct *work)
 
 	mutex_unlock(&hdcp->mutex);
 	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+	drm_connector_put(&connector->base);
 }
 
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
@@ -1802,6 +1806,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);
@@ -2076,12 +2083,33 @@ 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);
+	WARN_ON(!drm_connector_is_unregistered(&connector->base));
+
+	/*
+	 * Now that the connector is unregistered, 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).
+	 */
+	WARN_ON(work_pending(&hdcp->prop_work));
+
+	mutex_lock(&hdcp->mutex);
+	kfree(hdcp->port_data.streams);
+	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] 61+ messages in thread

* [PATCH v2 08/12] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
@ 2019-12-12 19:02   ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, 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.

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

Changes in v2:
- Move the toggle_signalling call into _intel_hdcp_disable so it's called from check_work
---
 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     | 52 +++++++++++++++----
 drivers/gpu/drm/i915/display/intel_hdmi.c     |  2 +
 5 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index bbdaa6d1deec..ea8dd8dbc445 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4788,6 +4788,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
 
 	encoder = &intel_dig_port->base;
 
+	mutex_init(&intel_dig_port->hdcp_mutex);
+	intel_dig_port->num_hdcp_streams = 0;
+
 	drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
 			 DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port));
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 687768a913f6..8e98840fc597 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1354,6 +1354,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 c1a228b5f879..155067657e23 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -7580,6 +7580,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 c79dca2c74d1..fbbd4da7c491 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -779,6 +779,19 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 	DRM_DEBUG_KMS("[%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;
 	I915_WRITE(HDCP_CONF(dev_priv, cpu_transcoder, port), 0);
 	if (intel_de_wait_for_clear(dev_priv,
@@ -855,6 +868,7 @@ 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 intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 
 	WARN_ON(!mutex_is_locked(&hdcp->mutex));
@@ -862,6 +876,15 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
 	if (hdcp->value == value)
 		return;
 
+	WARN_ON(!mutex_is_locked(&intel_dig_port->hdcp_mutex));
+
+	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
+		if (!WARN_ON(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);
@@ -880,6 +903,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 */
@@ -931,6 +956,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;
 }
@@ -1996,6 +2022,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 = conn_to_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
 	int ret = -EINVAL;
@@ -2004,6 +2031,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
 		return -ENOENT;
 
 	mutex_lock(&hdcp->mutex);
+	mutex_lock(&intel_dig_port->hdcp_mutex);
 	WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
 	hdcp->content_type = content_type;
 
@@ -2038,12 +2066,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 = conn_to_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	int ret = 0;
 
@@ -2051,17 +2081,21 @@ 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) {
-		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(&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 5066efadca85..905b188782ed 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -3247,6 +3247,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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 08/12] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 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.

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

Changes in v2:
- Move the toggle_signalling call into _intel_hdcp_disable so it's called from check_work
---
 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     | 52 +++++++++++++++----
 drivers/gpu/drm/i915/display/intel_hdmi.c     |  2 +
 5 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index bbdaa6d1deec..ea8dd8dbc445 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4788,6 +4788,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
 
 	encoder = &intel_dig_port->base;
 
+	mutex_init(&intel_dig_port->hdcp_mutex);
+	intel_dig_port->num_hdcp_streams = 0;
+
 	drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
 			 DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port));
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 687768a913f6..8e98840fc597 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1354,6 +1354,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 c1a228b5f879..155067657e23 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -7580,6 +7580,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 c79dca2c74d1..fbbd4da7c491 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -779,6 +779,19 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 	DRM_DEBUG_KMS("[%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;
 	I915_WRITE(HDCP_CONF(dev_priv, cpu_transcoder, port), 0);
 	if (intel_de_wait_for_clear(dev_priv,
@@ -855,6 +868,7 @@ 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 intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 
 	WARN_ON(!mutex_is_locked(&hdcp->mutex));
@@ -862,6 +876,15 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
 	if (hdcp->value == value)
 		return;
 
+	WARN_ON(!mutex_is_locked(&intel_dig_port->hdcp_mutex));
+
+	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
+		if (!WARN_ON(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);
@@ -880,6 +903,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 */
@@ -931,6 +956,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;
 }
@@ -1996,6 +2022,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 = conn_to_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
 	int ret = -EINVAL;
@@ -2004,6 +2031,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
 		return -ENOENT;
 
 	mutex_lock(&hdcp->mutex);
+	mutex_lock(&intel_dig_port->hdcp_mutex);
 	WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
 	hdcp->content_type = content_type;
 
@@ -2038,12 +2066,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 = conn_to_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	int ret = 0;
 
@@ -2051,17 +2081,21 @@ 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) {
-		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(&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 5066efadca85..905b188782ed 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -3247,6 +3247,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] 61+ messages in thread

* [PATCH v2 09/12] drm/i915: Support DP MST in enc_to_dig_port() function
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
@ 2019-12-12 19:02   ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, 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

Changes in v2:
-none
---
 .../drm/i915/display/intel_display_types.h    | 19 +++++++++++++------
 1 file changed, 13 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 8e98840fc597..ac5af925e403 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1459,6 +1459,17 @@ 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 drm_encoder *encoder)
+{
+	return container_of(encoder, struct intel_dp_mst_encoder, base.base);
+}
+
 static inline struct intel_digital_port *
 enc_to_dig_port(struct drm_encoder *encoder)
 {
@@ -1467,6 +1478,8 @@ enc_to_dig_port(struct drm_encoder *encoder)
 	if (intel_encoder_is_dig_port(intel_encoder))
 		return container_of(encoder, struct intel_digital_port,
 				    base.base);
+	else if (intel_encoder_is_mst(intel_encoder))
+		return enc_to_mst(encoder)->primary;
 	else
 		return NULL;
 }
@@ -1477,12 +1490,6 @@ conn_to_dig_port(struct intel_connector *connector)
 	return enc_to_dig_port(&intel_attached_encoder(&connector->base)->base);
 }
 
-static inline struct intel_dp_mst_encoder *
-enc_to_mst(struct drm_encoder *encoder)
-{
-	return container_of(encoder, struct intel_dp_mst_encoder, base.base);
-}
-
 static inline struct intel_dp *enc_to_intel_dp(struct drm_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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 09/12] drm/i915: Support DP MST in enc_to_dig_port() function
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 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

Changes in v2:
-none
---
 .../drm/i915/display/intel_display_types.h    | 19 +++++++++++++------
 1 file changed, 13 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 8e98840fc597..ac5af925e403 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1459,6 +1459,17 @@ 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 drm_encoder *encoder)
+{
+	return container_of(encoder, struct intel_dp_mst_encoder, base.base);
+}
+
 static inline struct intel_digital_port *
 enc_to_dig_port(struct drm_encoder *encoder)
 {
@@ -1467,6 +1478,8 @@ enc_to_dig_port(struct drm_encoder *encoder)
 	if (intel_encoder_is_dig_port(intel_encoder))
 		return container_of(encoder, struct intel_digital_port,
 				    base.base);
+	else if (intel_encoder_is_mst(intel_encoder))
+		return enc_to_mst(encoder)->primary;
 	else
 		return NULL;
 }
@@ -1477,12 +1490,6 @@ conn_to_dig_port(struct intel_connector *connector)
 	return enc_to_dig_port(&intel_attached_encoder(&connector->base)->base);
 }
 
-static inline struct intel_dp_mst_encoder *
-enc_to_mst(struct drm_encoder *encoder)
-{
-	return container_of(encoder, struct intel_dp_mst_encoder, base.base);
-}
-
 static inline struct intel_dp *enc_to_intel_dp(struct drm_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] 61+ messages in thread

* [PATCH v2 10/12] drm/i915: Use ddi_update_pipe in intel_dp_mst
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
@ 2019-12-12 19:02   ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, 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

Changes in v2:
-none
---
 drivers/gpu/drm/i915/display/intel_ddi.c    | 9 +++++----
 drivers/gpu/drm/i915/display/intel_dp.h     | 6 ++++++
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 1 +
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index ea8dd8dbc445..3742c5dbd8b4 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4097,9 +4097,9 @@ static void intel_ddi_update_pipe_dp(struct intel_encoder *encoder,
 	intel_panel_update_backlight(encoder, crtc_state, conn_state);
 }
 
-static void intel_ddi_update_pipe(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_encoder *encoder,
+			   const struct intel_crtc_state *crtc_state,
+			   const struct drm_connector_state *conn_state)
 {
 	struct intel_connector *connector =
 				to_intel_connector(conn_state->connector);
@@ -4109,7 +4109,8 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
 			 conn_state->content_protection !=
 			 DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
 
-	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(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 3da166054788..db732b432809 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -123,6 +123,12 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 	return ~((1 << lane_count) - 1) & 0xf;
 }
 
+
 u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
 
+/* Shared between intel_dp and intel_dp_mst */
+void intel_ddi_update_pipe(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 926e49f449a6..fbd9a6c543e7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -655,6 +655,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum
 	intel_encoder->compute_config = intel_dp_mst_compute_config;
 	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->post_pll_disable = intel_mst_post_pll_disable_dp;
 	intel_encoder->pre_enable = intel_mst_pre_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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 10/12] drm/i915: Use ddi_update_pipe in intel_dp_mst
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 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

Changes in v2:
-none
---
 drivers/gpu/drm/i915/display/intel_ddi.c    | 9 +++++----
 drivers/gpu/drm/i915/display/intel_dp.h     | 6 ++++++
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 1 +
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index ea8dd8dbc445..3742c5dbd8b4 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4097,9 +4097,9 @@ static void intel_ddi_update_pipe_dp(struct intel_encoder *encoder,
 	intel_panel_update_backlight(encoder, crtc_state, conn_state);
 }
 
-static void intel_ddi_update_pipe(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_encoder *encoder,
+			   const struct intel_crtc_state *crtc_state,
+			   const struct drm_connector_state *conn_state)
 {
 	struct intel_connector *connector =
 				to_intel_connector(conn_state->connector);
@@ -4109,7 +4109,8 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
 			 conn_state->content_protection !=
 			 DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
 
-	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(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 3da166054788..db732b432809 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -123,6 +123,12 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 	return ~((1 << lane_count) - 1) & 0xf;
 }
 
+
 u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
 
+/* Shared between intel_dp and intel_dp_mst */
+void intel_ddi_update_pipe(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 926e49f449a6..fbd9a6c543e7 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -655,6 +655,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum
 	intel_encoder->compute_config = intel_dp_mst_compute_config;
 	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->post_pll_disable = intel_mst_post_pll_disable_dp;
 	intel_encoder->pre_enable = intel_mst_pre_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] 61+ messages in thread

* [PATCH v2 11/12] drm/i915: Expose HDCP shim functions from dp for use by dp_mst
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
@ 2019-12-12 19:02   ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, Sean Paul

From: Sean Paul <seanpaul@chromium.org>

These functions are all the same for dp and dp_mst, so expose them for
use by the dp_mst hdcp implementation.

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

Changes in v2:
-none
---
 .../drm/i915/display/intel_display_types.h    | 22 +++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dp.c       | 14 ++----------
 2 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index ac5af925e403..b9e1f4638ff2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1636,4 +1636,26 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
 	return i915_ggtt_offset(state->vma);
 }
 
+int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
+				u8 *an);
+int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
+			    u8 *bksv);
+int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
+				      u8 *bstatus);
+int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
+			     u8 *bcaps);
+int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
+				   bool *repeater_present);
+int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
+				u8 *ri_prime);
+int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
+				 bool *ksv_ready);
+int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
+				int num_downstream, u8 *ksv_fifo);
+int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
+				    int i, u32 *part);
+bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port);
+int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
+			  bool *hdcp_capable);
+
 #endif /*  __INTEL_DISPLAY_TYPES_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 155067657e23..3d62b1b7224e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5915,7 +5915,6 @@ static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
 		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)
 {
@@ -5947,8 +5946,7 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
-				   u8 *bksv)
+int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port, u8 *bksv)
 {
 	ssize_t ret;
 	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
@@ -5960,7 +5958,7 @@ static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
+int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
 				      u8 *bstatus)
 {
 	ssize_t ret;
@@ -5978,7 +5976,6 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
 			     u8 *bcaps)
 {
@@ -5994,7 +5991,6 @@ int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
 				   bool *repeater_present)
 {
@@ -6009,7 +6005,6 @@ int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
 				u8 *ri_prime)
 {
@@ -6023,7 +6018,6 @@ int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
 				 bool *ksv_ready)
 {
@@ -6039,7 +6033,6 @@ int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
 				int num_downstream, u8 *ksv_fifo)
 {
@@ -6062,7 +6055,6 @@ int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
 				    int i, u32 *part)
 {
@@ -6090,7 +6082,6 @@ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
 {
 	ssize_t ret;
@@ -6106,7 +6097,6 @@ bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
 	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)
 {
-- 
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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 11/12] drm/i915: Expose HDCP shim functions from dp for use by dp_mst
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 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 expose them for
use by the dp_mst hdcp implementation.

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

Changes in v2:
-none
---
 .../drm/i915/display/intel_display_types.h    | 22 +++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dp.c       | 14 ++----------
 2 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index ac5af925e403..b9e1f4638ff2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1636,4 +1636,26 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
 	return i915_ggtt_offset(state->vma);
 }
 
+int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
+				u8 *an);
+int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
+			    u8 *bksv);
+int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
+				      u8 *bstatus);
+int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
+			     u8 *bcaps);
+int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
+				   bool *repeater_present);
+int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
+				u8 *ri_prime);
+int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
+				 bool *ksv_ready);
+int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
+				int num_downstream, u8 *ksv_fifo);
+int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
+				    int i, u32 *part);
+bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port);
+int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
+			  bool *hdcp_capable);
+
 #endif /*  __INTEL_DISPLAY_TYPES_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 155067657e23..3d62b1b7224e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5915,7 +5915,6 @@ static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
 		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)
 {
@@ -5947,8 +5946,7 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
-				   u8 *bksv)
+int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port, u8 *bksv)
 {
 	ssize_t ret;
 	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
@@ -5960,7 +5958,7 @@ static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
+int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
 				      u8 *bstatus)
 {
 	ssize_t ret;
@@ -5978,7 +5976,6 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
 			     u8 *bcaps)
 {
@@ -5994,7 +5991,6 @@ int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
 				   bool *repeater_present)
 {
@@ -6009,7 +6005,6 @@ int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
 				u8 *ri_prime)
 {
@@ -6023,7 +6018,6 @@ int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
 				 bool *ksv_ready)
 {
@@ -6039,7 +6033,6 @@ int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
 				int num_downstream, u8 *ksv_fifo)
 {
@@ -6062,7 +6055,6 @@ int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
 				    int i, u32 *part)
 {
@@ -6090,7 +6082,6 @@ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
 	return 0;
 }
 
-static
 bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
 {
 	ssize_t ret;
@@ -6106,7 +6097,6 @@ bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
 	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)
 {
-- 
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] 61+ messages in thread

* [PATCH v2 12/12] drm/i915: Add HDCP 1.4 support for MST connectors
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
@ 2019-12-12 19:02   ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 UTC (permalink / raw)
  To: dri-devel, intel-gfx; +Cc: daniel.vetter, rodrigo.vivi, 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

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

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
---
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 89 +++++++++++++++++++++
 1 file changed, 89 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index fbd9a6c543e7..1e08ce751abe 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -36,6 +36,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,
@@ -215,6 +216,8 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder,
 
 	DRM_DEBUG_KMS("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);
@@ -378,6 +381,13 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder,
 	drm_dp_update_payload_part2(&intel_dp->mst_mgr);
 	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,
@@ -522,11 +532,84 @@ static bool intel_dp_mst_get_hw_state(struct intel_connector *connector)
 	return false;
 }
 
+static int
+intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
+				    enum transcoder cpu_transcoder,
+				    bool enable)
+{
+	int ret;
+
+	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
+					       cpu_transcoder, enable);
+	if (ret)
+		DRM_DEBUG_KMS("%s HDCP signalling failed (%d)\n",
+			      enable ? "Enable" : "Disable", ret);
+	return ret;
+}
+
+static
+int intel_dp_mst_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
+				 void *buf, size_t size)
+{
+	return -EOPNOTSUPP;
+}
+
+static
+int intel_dp_mst_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
+				u8 msg_id, void *buf, size_t size)
+{
+	return -EOPNOTSUPP;
+}
+
+static int
+intel_dp_mst_hdcp2_config_stream_type(struct intel_digital_port *intel_dig_port,
+				      bool is_repeater, u8 content_type)
+{
+	return -EOPNOTSUPP;
+}
+
+static
+int intel_dp_mst_hdcp2_check_link(struct intel_digital_port *intel_dig_port)
+{
+	return -EOPNOTSUPP;
+}
+
+static
+int intel_dp_mst_hdcp2_capable(struct intel_digital_port *intel_dig_port,
+			       bool *capable)
+{
+	*capable = false;
+	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_mst_hdcp_toggle_signalling,
+	.check_link = intel_dp_hdcp_check_link,
+	.hdcp_capable = intel_dp_hdcp_capable,
+
+	.write_2_2_msg = intel_dp_mst_hdcp2_write_msg,
+	.read_2_2_msg = intel_dp_mst_hdcp2_read_msg,
+	.config_stream_type = intel_dp_mst_hdcp2_config_stream_type,
+	.check_2_2_link = intel_dp_mst_hdcp2_check_link,
+	.hdcp_2_2_capable = intel_dp_mst_hdcp2_capable,
+
+	.protocol = HDCP_PROTOCOL_DP,
+};
+
 static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *pathprop)
 {
 	struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_connector *intel_connector;
 	struct drm_connector *connector;
@@ -571,6 +654,12 @@ 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);
 
+	if (is_hdcp_supported(dev_priv, intel_encoder->port)) {
+		int ret = intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
+		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.
-- 
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] 61+ messages in thread

* [Intel-gfx] [PATCH v2 12/12] drm/i915: Add HDCP 1.4 support for MST connectors
@ 2019-12-12 19:02   ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-12 19:02 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

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

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
---
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 89 +++++++++++++++++++++
 1 file changed, 89 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index fbd9a6c543e7..1e08ce751abe 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -36,6 +36,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,
@@ -215,6 +216,8 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder,
 
 	DRM_DEBUG_KMS("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);
@@ -378,6 +381,13 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder,
 	drm_dp_update_payload_part2(&intel_dp->mst_mgr);
 	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,
@@ -522,11 +532,84 @@ static bool intel_dp_mst_get_hw_state(struct intel_connector *connector)
 	return false;
 }
 
+static int
+intel_dp_mst_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
+				    enum transcoder cpu_transcoder,
+				    bool enable)
+{
+	int ret;
+
+	ret = intel_ddi_toggle_hdcp_signalling(&intel_dig_port->base,
+					       cpu_transcoder, enable);
+	if (ret)
+		DRM_DEBUG_KMS("%s HDCP signalling failed (%d)\n",
+			      enable ? "Enable" : "Disable", ret);
+	return ret;
+}
+
+static
+int intel_dp_mst_hdcp2_write_msg(struct intel_digital_port *intel_dig_port,
+				 void *buf, size_t size)
+{
+	return -EOPNOTSUPP;
+}
+
+static
+int intel_dp_mst_hdcp2_read_msg(struct intel_digital_port *intel_dig_port,
+				u8 msg_id, void *buf, size_t size)
+{
+	return -EOPNOTSUPP;
+}
+
+static int
+intel_dp_mst_hdcp2_config_stream_type(struct intel_digital_port *intel_dig_port,
+				      bool is_repeater, u8 content_type)
+{
+	return -EOPNOTSUPP;
+}
+
+static
+int intel_dp_mst_hdcp2_check_link(struct intel_digital_port *intel_dig_port)
+{
+	return -EOPNOTSUPP;
+}
+
+static
+int intel_dp_mst_hdcp2_capable(struct intel_digital_port *intel_dig_port,
+			       bool *capable)
+{
+	*capable = false;
+	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_mst_hdcp_toggle_signalling,
+	.check_link = intel_dp_hdcp_check_link,
+	.hdcp_capable = intel_dp_hdcp_capable,
+
+	.write_2_2_msg = intel_dp_mst_hdcp2_write_msg,
+	.read_2_2_msg = intel_dp_mst_hdcp2_read_msg,
+	.config_stream_type = intel_dp_mst_hdcp2_config_stream_type,
+	.check_2_2_link = intel_dp_mst_hdcp2_check_link,
+	.hdcp_2_2_capable = intel_dp_mst_hdcp2_capable,
+
+	.protocol = HDCP_PROTOCOL_DP,
+};
+
 static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *pathprop)
 {
 	struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_connector *intel_connector;
 	struct drm_connector *connector;
@@ -571,6 +654,12 @@ 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);
 
+	if (is_hdcp_supported(dev_priv, intel_encoder->port)) {
+		int ret = intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
+		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.
-- 
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] 61+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add support for HDCP 1.4 over MST connectors (rev2)
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
                   ` (12 preceding siblings ...)
  (?)
@ 2019-12-12 21:12 ` Patchwork
  -1 siblings, 0 replies; 61+ messages in thread
From: Patchwork @ 2019-12-12 21:12 UTC (permalink / raw)
  To: Sean Paul; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Add support for HDCP 1.4 over MST connectors (rev2)
URL   : https://patchwork.freedesktop.org/series/70393/
State : warning

== Summary ==

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

total: 0 errors, 1 warnings, 0 checks, 59 lines checked
ab50e164f964 drm/i915: Clear the repeater bit on HDCP disable
b16968ebee0e drm/i915: WARN if HDCP signalling is enabled upon disable
2ef309e174b5 drm/i915: Intercept Aksv writes in the aux hooks
135b02f35aa2 drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling
03cad2db95dc drm/i915: Factor out hdcp->value assignments
-:59: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#59: FILE: drivers/gpu/drm/i915/display/intel_hdcp.c:905:
+			intel_hdcp_update_value(connector,
+				DRM_MODE_CONTENT_PROTECTION_ENABLED, true);

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

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

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

total: 0 errors, 0 warnings, 4 checks, 138 lines checked
46a30f077469 drm/i915: Protect workers against disappearing connectors
5cf2459e1ab8 drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
d1165847a339 drm/i915: Support DP MST in enc_to_dig_port() function
f03715af66e3 drm/i915: Use ddi_update_pipe in intel_dp_mst
-:51: CHECK:LINE_SPACING: Please don't use multiple blank lines
#51: FILE: drivers/gpu/drm/i915/display/intel_dp.h:126:
 
+

total: 0 errors, 0 warnings, 1 checks, 40 lines checked
42978bd3f621 drm/i915: Expose HDCP shim functions from dp for use by dp_mst
-:29: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#29: FILE: drivers/gpu/drm/i915/display/intel_display_types.h:1644:
+int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
+				      u8 *bstatus);

-:75: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#75: FILE: drivers/gpu/drm/i915/display/intel_dp.c:5962:
+int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
 				      u8 *bstatus)

total: 0 errors, 0 warnings, 2 checks, 106 lines checked
33b2dcba156f drm/i915: Add HDCP 1.4 support for MST connectors
-:144: WARNING:LINE_SPACING: Missing a blank line after declarations
#144: FILE: drivers/gpu/drm/i915/display/intel_dp_mst.c:659:
+		int ret = intel_hdcp_init(intel_connector, &intel_dp_hdcp_shim);
+		if (ret)

total: 0 errors, 1 warnings, 0 checks, 124 lines checked

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

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

* [Intel-gfx] ✗ Fi.CI.BAT: failure for drm/i915: Add support for HDCP 1.4 over MST connectors (rev2)
  2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
                   ` (13 preceding siblings ...)
  (?)
@ 2019-12-12 21:34 ` Patchwork
  2019-12-12 22:50   ` Sean Paul
  -1 siblings, 1 reply; 61+ messages in thread
From: Patchwork @ 2019-12-12 21:34 UTC (permalink / raw)
  To: Sean Paul; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Add support for HDCP 1.4 over MST connectors (rev2)
URL   : https://patchwork.freedesktop.org/series/70393/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_7553 -> Patchwork_15728
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_15728 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_15728, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

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

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_15728:

### IGT changes ###

#### Possible regressions ####

  * igt@gem_close_race@basic-threads:
    - fi-byt-j1900:       [PASS][1] -> [TIMEOUT][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-byt-j1900/igt@gem_close_race@basic-threads.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-byt-j1900/igt@gem_close_race@basic-threads.html
    - fi-byt-n2820:       [PASS][3] -> [TIMEOUT][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-byt-n2820/igt@gem_close_race@basic-threads.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-byt-n2820/igt@gem_close_race@basic-threads.html

  * igt@i915_module_load@reload-with-fault-injection:
    - fi-icl-guc:         [PASS][5] -> [DMESG-WARN][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-icl-guc/igt@i915_module_load@reload-with-fault-injection.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-icl-guc/igt@i915_module_load@reload-with-fault-injection.html
    - fi-cfl-guc:         [PASS][7] -> [DMESG-WARN][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-cfl-guc/igt@i915_module_load@reload-with-fault-injection.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-cfl-guc/igt@i915_module_load@reload-with-fault-injection.html
    - fi-skl-guc:         [PASS][9] -> [DMESG-WARN][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-skl-guc/igt@i915_module_load@reload-with-fault-injection.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-skl-guc/igt@i915_module_load@reload-with-fault-injection.html
    - fi-cfl-8700k:       [PASS][11] -> [DMESG-WARN][12]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-cfl-8700k/igt@i915_module_load@reload-with-fault-injection.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-cfl-8700k/igt@i915_module_load@reload-with-fault-injection.html
    - fi-icl-y:           [PASS][13] -> [DMESG-WARN][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-icl-y/igt@i915_module_load@reload-with-fault-injection.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-icl-y/igt@i915_module_load@reload-with-fault-injection.html
    - fi-skl-6700k2:      [PASS][15] -> [DMESG-WARN][16]
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-skl-6700k2/igt@i915_module_load@reload-with-fault-injection.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-skl-6700k2/igt@i915_module_load@reload-with-fault-injection.html
    - fi-apl-guc:         [PASS][17] -> [DMESG-WARN][18]
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-apl-guc/igt@i915_module_load@reload-with-fault-injection.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-apl-guc/igt@i915_module_load@reload-with-fault-injection.html
    - fi-skl-6770hq:      [PASS][19] -> [DMESG-WARN][20]
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-skl-6770hq/igt@i915_module_load@reload-with-fault-injection.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-skl-6770hq/igt@i915_module_load@reload-with-fault-injection.html
    - fi-skl-6600u:       [PASS][21] -> [DMESG-WARN][22]
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-skl-6600u/igt@i915_module_load@reload-with-fault-injection.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-skl-6600u/igt@i915_module_load@reload-with-fault-injection.html
    - fi-kbl-guc:         [PASS][23] -> [DMESG-WARN][24]
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-kbl-guc/igt@i915_module_load@reload-with-fault-injection.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-kbl-guc/igt@i915_module_load@reload-with-fault-injection.html
    - fi-kbl-soraka:      [PASS][25] -> [DMESG-WARN][26]
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-kbl-soraka/igt@i915_module_load@reload-with-fault-injection.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-kbl-soraka/igt@i915_module_load@reload-with-fault-injection.html
    - fi-skl-lmem:        [PASS][27] -> [DMESG-WARN][28]
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-skl-lmem/igt@i915_module_load@reload-with-fault-injection.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-skl-lmem/igt@i915_module_load@reload-with-fault-injection.html
    - fi-kbl-r:           [PASS][29] -> [DMESG-WARN][30]
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-kbl-r/igt@i915_module_load@reload-with-fault-injection.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-kbl-r/igt@i915_module_load@reload-with-fault-injection.html
    - fi-cml-u2:          [PASS][31] -> [DMESG-WARN][32]
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-cml-u2/igt@i915_module_load@reload-with-fault-injection.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-cml-u2/igt@i915_module_load@reload-with-fault-injection.html
    - fi-bxt-dsi:         [PASS][33] -> [DMESG-WARN][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-bxt-dsi/igt@i915_module_load@reload-with-fault-injection.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-bxt-dsi/igt@i915_module_load@reload-with-fault-injection.html
    - fi-whl-u:           [PASS][35] -> [DMESG-WARN][36]
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-whl-u/igt@i915_module_load@reload-with-fault-injection.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-whl-u/igt@i915_module_load@reload-with-fault-injection.html
    - fi-icl-u3:          [PASS][37] -> [DMESG-WARN][38]
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-icl-u3/igt@i915_module_load@reload-with-fault-injection.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-icl-u3/igt@i915_module_load@reload-with-fault-injection.html
    - fi-glk-dsi:         [PASS][39] -> [DMESG-WARN][40]
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-glk-dsi/igt@i915_module_load@reload-with-fault-injection.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-glk-dsi/igt@i915_module_load@reload-with-fault-injection.html
    - fi-kbl-7500u:       [PASS][41] -> [DMESG-WARN][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-kbl-7500u/igt@i915_module_load@reload-with-fault-injection.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-kbl-7500u/igt@i915_module_load@reload-with-fault-injection.html

  * igt@runner@aborted:
    - fi-whl-u:           NOTRUN -> [FAIL][43]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-whl-u/igt@runner@aborted.html
    - fi-byt-j1900:       NOTRUN -> [FAIL][44]
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-byt-j1900/igt@runner@aborted.html
    - fi-cfl-guc:         NOTRUN -> [FAIL][45]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-cfl-guc/igt@runner@aborted.html
    - fi-cfl-8700k:       NOTRUN -> [FAIL][46]
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-cfl-8700k/igt@runner@aborted.html
    - fi-byt-n2820:       NOTRUN -> [FAIL][47]
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-byt-n2820/igt@runner@aborted.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@kms_chamelium@hdmi-hpd-fast:
    - fi-kbl-7500u:       [PASS][48] -> [FAIL][49] ([fdo#111407])
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html

  
#### Possible fixes ####

  * igt@i915_selftest@live_blt:
    - fi-bsw-n3050:       [DMESG-FAIL][50] ([i915#723]) -> [PASS][51]
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-bsw-n3050/igt@i915_selftest@live_blt.html
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-bsw-n3050/igt@i915_selftest@live_blt.html
    - fi-ivb-3770:        [DMESG-FAIL][52] ([i915#725]) -> [PASS][53]
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-ivb-3770/igt@i915_selftest@live_blt.html
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-ivb-3770/igt@i915_selftest@live_blt.html
    - fi-hsw-4770r:       [DMESG-FAIL][54] ([i915#725]) -> [PASS][55]
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-hsw-4770r/igt@i915_selftest@live_blt.html
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-hsw-4770r/igt@i915_selftest@live_blt.html

  
#### Warnings ####

  * igt@gem_exec_suspend@basic-s0:
    - fi-kbl-x1275:       [DMESG-WARN][56] ([i915#62] / [i915#92]) -> [DMESG-WARN][57] ([i915#62] / [i915#92] / [i915#95]) +6 similar issues
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-kbl-x1275/igt@gem_exec_suspend@basic-s0.html
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-kbl-x1275/igt@gem_exec_suspend@basic-s0.html

  * igt@i915_module_load@reload:
    - fi-icl-u2:          [DMESG-WARN][58] ([i915#289]) -> [DMESG-WARN][59] ([i915#109] / [i915#289])
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-icl-u2/igt@i915_module_load@reload.html
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-icl-u2/igt@i915_module_load@reload.html

  * igt@i915_selftest@live_gem_contexts:
    - fi-hsw-peppy:       [INCOMPLETE][60] ([i915#694]) -> [DMESG-FAIL][61] ([i915#722])
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-hsw-peppy/igt@i915_selftest@live_gem_contexts.html
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-hsw-peppy/igt@i915_selftest@live_gem_contexts.html

  * igt@kms_flip@basic-flip-vs-modeset:
    - fi-kbl-x1275:       [DMESG-WARN][62] ([i915#62] / [i915#92] / [i915#95]) -> [DMESG-WARN][63] ([i915#62] / [i915#92]) +4 similar issues
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-modeset.html
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-modeset.html

  * igt@runner@aborted:
    - fi-icl-guc:         [FAIL][64] ([fdo#110943] / [fdo#111093]) -> [FAIL][65] ([fdo#111093])
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-icl-guc/igt@runner@aborted.html
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-icl-guc/igt@runner@aborted.html

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

  [fdo#110943]: https://bugs.freedesktop.org/show_bug.cgi?id=110943
  [fdo#111093]: https://bugs.freedesktop.org/show_bug.cgi?id=111093
  [fdo#111407]: https://bugs.freedesktop.org/show_bug.cgi?id=111407
  [fdo#111593]: https://bugs.freedesktop.org/show_bug.cgi?id=111593
  [i915#109]: https://gitlab.freedesktop.org/drm/intel/issues/109
  [i915#289]: https://gitlab.freedesktop.org/drm/intel/issues/289
  [i915#476]: https://gitlab.freedesktop.org/drm/intel/issues/476
  [i915#62]: https://gitlab.freedesktop.org/drm/intel/issues/62
  [i915#694]: https://gitlab.freedesktop.org/drm/intel/issues/694
  [i915#722]: https://gitlab.freedesktop.org/drm/intel/issues/722
  [i915#723]: https://gitlab.freedesktop.org/drm/intel/issues/723
  [i915#725]: https://gitlab.freedesktop.org/drm/intel/issues/725
  [i915#92]: https://gitlab.freedesktop.org/drm/intel/issues/92
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (52 -> 46)
------------------------------

  Additional (1): fi-bsw-nick 
  Missing    (7): fi-icl-1065g7 fi-ilk-m540 fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-byt-clapper fi-bdw-samus 


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

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_7553 -> Patchwork_15728

  CI-20190529: 20190529
  CI_DRM_7553: 85e34ee26876ad3d0438ed9cc0d1b727761dcded @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5346: 466b0e6cbcbaccff012b484d1fd7676364b37b93 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_15728: 33b2dcba156f572b3107663a3fe393ff1f8ff917 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

33b2dcba156f drm/i915: Add HDCP 1.4 support for MST connectors
42978bd3f621 drm/i915: Expose HDCP shim functions from dp for use by dp_mst
f03715af66e3 drm/i915: Use ddi_update_pipe in intel_dp_mst
d1165847a339 drm/i915: Support DP MST in enc_to_dig_port() function
5cf2459e1ab8 drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
46a30f077469 drm/i915: Protect workers against disappearing connectors
03cad2db95dc drm/i915: Factor out hdcp->value assignments
135b02f35aa2 drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling
2ef309e174b5 drm/i915: Intercept Aksv writes in the aux hooks
b16968ebee0e drm/i915: WARN if HDCP signalling is enabled upon disable
ab50e164f964 drm/i915: Clear the repeater bit on HDCP disable
4f25d7348ece drm/i915: Fix sha_text population code

== Logs ==

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

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

* Re: [Intel-gfx]  ✗ Fi.CI.BAT: failure for drm/i915: Add support for HDCP 1.4 over MST connectors (rev2)
  2019-12-12 21:34 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
@ 2019-12-12 22:50   ` Sean Paul
  2019-12-12 22:55     ` Chris Wilson
  0 siblings, 1 reply; 61+ messages in thread
From: Sean Paul @ 2019-12-12 22:50 UTC (permalink / raw)
  To: Intel Graphics Development, Sean Paul

On Thu, Dec 12, 2019 at 4:34 PM Patchwork
<patchwork@emeril.freedesktop.org> wrote:
>
> == Series Details ==
>
> Series: drm/i915: Add support for HDCP 1.4 over MST connectors (rev2)
> URL   : https://patchwork.freedesktop.org/series/70393/
> State : failure
>
> == Summary ==
>
> CI Bug Log - changes from CI_DRM_7553 -> Patchwork_15728
> ====================================================
>
> Summary
> -------
>
>   **FAILURE**
>
>   Serious unknown changes coming with Patchwork_15728 absolutely need to be
>   verified manually.
>
>   If you think the reported changes have nothing to do with the changes
>   introduced in Patchwork_15728, please notify your bug team to allow them
>   to document this new failure mode, which will reduce false positives in CI.
>
>   External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/index.html
>
> Possible new issues
> -------------------
>
>   Here are the unknown changes that may have been introduced in Patchwork_15728:
>
> ### IGT changes ###
>
> #### Possible regressions ####
>
>   * igt@gem_close_race@basic-threads:
>     - fi-byt-j1900:       [PASS][1] -> [TIMEOUT][2]
>    [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-byt-j1900/igt@gem_close_race@basic-threads.html
>    [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-byt-j1900/igt@gem_close_race@basic-threads.html
>     - fi-byt-n2820:       [PASS][3] -> [TIMEOUT][4]
>    [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-byt-n2820/igt@gem_close_race@basic-threads.html
>    [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-byt-n2820/igt@gem_close_race@basic-threads.html
>

Not sure what's happening here.

>   * igt@i915_module_load@reload-with-fault-injection:
>     - fi-icl-guc:         [PASS][5] -> [DMESG-WARN][6]
>    [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-icl-guc/igt@i915_module_load@reload-with-fault-injection.html
>    [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-icl-guc/igt@i915_module_load@reload-with-fault-injection.html

These are legit, the hdcp cleanup function is called in error paths
where the connector is still registered.

\snip

>
>   * igt@runner@aborted:
>     - fi-whl-u:           NOTRUN -> [FAIL][43]
>    [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-whl-u/igt@runner@aborted.html
>     - fi-byt-j1900:       NOTRUN -> [FAIL][44]
>    [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-byt-j1900/igt@runner@aborted.html
>     - fi-cfl-guc:         NOTRUN -> [FAIL][45]
>    [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-cfl-guc/igt@runner@aborted.html
>     - fi-cfl-8700k:       NOTRUN -> [FAIL][46]
>    [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-cfl-8700k/igt@runner@aborted.html
>     - fi-byt-n2820:       NOTRUN -> [FAIL][47]
>    [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-byt-n2820/igt@runner@aborted.html

Same WARNs as above from the failure paths.

Will revise,

Sean

>
>
> Known issues
> ------------
>
>   Here are the changes found in Patchwork_15728 that come from known issues:
>
> ### IGT changes ###
>
> #### Issues hit ####
>
>   * igt@kms_chamelium@hdmi-hpd-fast:
>     - fi-kbl-7500u:       [PASS][48] -> [FAIL][49] ([fdo#111407])
>    [48]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html
>    [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html
>
>
> #### Possible fixes ####
>
>   * igt@i915_selftest@live_blt:
>     - fi-bsw-n3050:       [DMESG-FAIL][50] ([i915#723]) -> [PASS][51]
>    [50]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-bsw-n3050/igt@i915_selftest@live_blt.html
>    [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-bsw-n3050/igt@i915_selftest@live_blt.html
>     - fi-ivb-3770:        [DMESG-FAIL][52] ([i915#725]) -> [PASS][53]
>    [52]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-ivb-3770/igt@i915_selftest@live_blt.html
>    [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-ivb-3770/igt@i915_selftest@live_blt.html
>     - fi-hsw-4770r:       [DMESG-FAIL][54] ([i915#725]) -> [PASS][55]
>    [54]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-hsw-4770r/igt@i915_selftest@live_blt.html
>    [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-hsw-4770r/igt@i915_selftest@live_blt.html
>
>
> #### Warnings ####
>
>   * igt@gem_exec_suspend@basic-s0:
>     - fi-kbl-x1275:       [DMESG-WARN][56] ([i915#62] / [i915#92]) -> [DMESG-WARN][57] ([i915#62] / [i915#92] / [i915#95]) +6 similar issues
>    [56]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-kbl-x1275/igt@gem_exec_suspend@basic-s0.html
>    [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-kbl-x1275/igt@gem_exec_suspend@basic-s0.html
>
>   * igt@i915_module_load@reload:
>     - fi-icl-u2:          [DMESG-WARN][58] ([i915#289]) -> [DMESG-WARN][59] ([i915#109] / [i915#289])
>    [58]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-icl-u2/igt@i915_module_load@reload.html
>    [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-icl-u2/igt@i915_module_load@reload.html
>
>   * igt@i915_selftest@live_gem_contexts:
>     - fi-hsw-peppy:       [INCOMPLETE][60] ([i915#694]) -> [DMESG-FAIL][61] ([i915#722])
>    [60]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-hsw-peppy/igt@i915_selftest@live_gem_contexts.html
>    [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-hsw-peppy/igt@i915_selftest@live_gem_contexts.html
>
>   * igt@kms_flip@basic-flip-vs-modeset:
>     - fi-kbl-x1275:       [DMESG-WARN][62] ([i915#62] / [i915#92] / [i915#95]) -> [DMESG-WARN][63] ([i915#62] / [i915#92]) +4 similar issues
>    [62]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-modeset.html
>    [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-modeset.html
>
>   * igt@runner@aborted:
>     - fi-icl-guc:         [FAIL][64] ([fdo#110943] / [fdo#111093]) -> [FAIL][65] ([fdo#111093])
>    [64]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-icl-guc/igt@runner@aborted.html
>    [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-icl-guc/igt@runner@aborted.html
>
>
>   {name}: This element is suppressed. This means it is ignored when computing
>           the status of the difference (SUCCESS, WARNING, or FAILURE).
>
>   [fdo#110943]: https://bugs.freedesktop.org/show_bug.cgi?id=110943
>   [fdo#111093]: https://bugs.freedesktop.org/show_bug.cgi?id=111093
>   [fdo#111407]: https://bugs.freedesktop.org/show_bug.cgi?id=111407
>   [fdo#111593]: https://bugs.freedesktop.org/show_bug.cgi?id=111593
>   [i915#109]: https://gitlab.freedesktop.org/drm/intel/issues/109
>   [i915#289]: https://gitlab.freedesktop.org/drm/intel/issues/289
>   [i915#476]: https://gitlab.freedesktop.org/drm/intel/issues/476
>   [i915#62]: https://gitlab.freedesktop.org/drm/intel/issues/62
>   [i915#694]: https://gitlab.freedesktop.org/drm/intel/issues/694
>   [i915#722]: https://gitlab.freedesktop.org/drm/intel/issues/722
>   [i915#723]: https://gitlab.freedesktop.org/drm/intel/issues/723
>   [i915#725]: https://gitlab.freedesktop.org/drm/intel/issues/725
>   [i915#92]: https://gitlab.freedesktop.org/drm/intel/issues/92
>   [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95
>
>
> Participating hosts (52 -> 46)
> ------------------------------
>
>   Additional (1): fi-bsw-nick
>   Missing    (7): fi-icl-1065g7 fi-ilk-m540 fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-byt-clapper fi-bdw-samus
>
>
> Build changes
> -------------
>
>   * CI: CI-20190529 -> None
>   * Linux: CI_DRM_7553 -> Patchwork_15728
>
>   CI-20190529: 20190529
>   CI_DRM_7553: 85e34ee26876ad3d0438ed9cc0d1b727761dcded @ git://anongit.freedesktop.org/gfx-ci/linux
>   IGT_5346: 466b0e6cbcbaccff012b484d1fd7676364b37b93 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
>   Patchwork_15728: 33b2dcba156f572b3107663a3fe393ff1f8ff917 @ git://anongit.freedesktop.org/gfx-ci/linux
>
>
> == Linux commits ==
>
> 33b2dcba156f drm/i915: Add HDCP 1.4 support for MST connectors
> 42978bd3f621 drm/i915: Expose HDCP shim functions from dp for use by dp_mst
> f03715af66e3 drm/i915: Use ddi_update_pipe in intel_dp_mst
> d1165847a339 drm/i915: Support DP MST in enc_to_dig_port() function
> 5cf2459e1ab8 drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
> 46a30f077469 drm/i915: Protect workers against disappearing connectors
> 03cad2db95dc drm/i915: Factor out hdcp->value assignments
> 135b02f35aa2 drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling
> 2ef309e174b5 drm/i915: Intercept Aksv writes in the aux hooks
> b16968ebee0e drm/i915: WARN if HDCP signalling is enabled upon disable
> ab50e164f964 drm/i915: Clear the repeater bit on HDCP disable
> 4f25d7348ece drm/i915: Fix sha_text population code
>
> == Logs ==
>
> For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx]  ✗ Fi.CI.BAT: failure for drm/i915: Add support for HDCP 1.4 over MST connectors (rev2)
  2019-12-12 22:50   ` Sean Paul
@ 2019-12-12 22:55     ` Chris Wilson
  0 siblings, 0 replies; 61+ messages in thread
From: Chris Wilson @ 2019-12-12 22:55 UTC (permalink / raw)
  To: Intel Graphics Development, Sean Paul, Sean Paul

Quoting Sean Paul (2019-12-12 22:50:12)
> On Thu, Dec 12, 2019 at 4:34 PM Patchwork
> > #### Possible regressions ####
> >
> >   * igt@gem_close_race@basic-threads:
> >     - fi-byt-j1900:       [PASS][1] -> [TIMEOUT][2]
> >    [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-byt-j1900/igt@gem_close_race@basic-threads.html
> >    [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-byt-j1900/igt@gem_close_race@basic-threads.html
> >     - fi-byt-n2820:       [PASS][3] -> [TIMEOUT][4]
> >    [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7553/fi-byt-n2820/igt@gem_close_race@basic-threads.html
> >    [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15728/fi-byt-n2820/igt@gem_close_race@basic-threads.html
> >
> 
> Not sure what's happening here.

Nothing to see here, perfectly normal behaviour. Please move along.

If that fails, please look into this red dot.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 01/12] drm/i915: Fix sha_text population code
  2019-12-12 19:02   ` Sean Paul
  (?)
@ 2019-12-13 10:20     ` Ramalingam C
  -1 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 10:20 UTC (permalink / raw)
  To: Sean Paul
  Cc: dri-devel, intel-gfx, ville.syrjala, jani.nikula,
	joonas.lahtinen, rodrigo.vivi, daniel.vetter, Sean Paul,
	Chris Wilson, stable

On 2019-12-12 at 14:02:19 -0500, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> This patch fixes a few bugs:
> 
> 1- We weren't taking into account sha_leftovers when adding multiple
>    ksvs to sha_text. As such, we were or'ing the end of ksv[j - 1] with
>    the beginning of ksv[j]
> 
> 2- In the sha_leftovers == 2 and sha_leftovers == 3 case, bstatus was
>    being placed on the wrong half of sha_text, overlapping the leftover
>    ksv value
> 
> 3- In the sha_leftovers == 2 case, we need to manually terminate the
>    byte stream with 0x80 since the hardware doesn't have enough room to
>    add it after writing M0
> 
> The upside is that all of the "HDCP supported" HDMI repeaters I could
> find on Amazon just strip HDCP anyways, so it turns out to be _really_
> hard to hit any of these cases without an MST hub, which is not (yet)
> supported. Oh, and the sha_leftovers == 1 case works perfectly!

Yes. The repeaters tested at our side too with sha_leftovers = 1 with
mostly ksv count of 1. non availability of the repeaters is killer here.
> 
> 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+
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-2-sean@poorly.run #v1
> 
> Changes in v2:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 25 +++++++++++++++++------
>  include/drm/drm_hdcp.h                    |  3 +++
>  2 files changed, 22 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 0fdbd39f6641..eaab9008feef 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -335,8 +335,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);
Didn't hit this as ksv count was 1 mostly with sha_leftovers = 1.
Thanks for fixing it.
> +			sha_text |= ksv[j] << off;
> +		}
>  
>  		ret = intel_write_sha_text(dev_priv, sha_text);
>  		if (ret < 0)
> @@ -426,7 +428,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
>  	} else if (sha_leftovers == 2) {
>  		/* Write 32 bits of text */
>  		I915_WRITE(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;
> @@ -440,16 +442,27 @@ 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.
> +		 */
> +		I915_WRITE(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) */
>  		I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32);
> -		sha_text |= bstatus[0] << 24;
> +		sha_text |= bstatus[0];

Looks good to me though this path never been exercised. Hopefully MST
will do it.

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

>  		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 */
>  		I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_8);
>  		ret = intel_write_sha_text(dev_priv, bstatus[1]);
>  		if (ret < 0)
> diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> index 06a11202a097..20498c822204 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	[flat|nested] 61+ messages in thread

* Re: [PATCH v2 01/12] drm/i915: Fix sha_text population code
@ 2019-12-13 10:20     ` Ramalingam C
  0 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 10:20 UTC (permalink / raw)
  To: Sean Paul
  Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, rodrigo.vivi, stable

On 2019-12-12 at 14:02:19 -0500, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> This patch fixes a few bugs:
> 
> 1- We weren't taking into account sha_leftovers when adding multiple
>    ksvs to sha_text. As such, we were or'ing the end of ksv[j - 1] with
>    the beginning of ksv[j]
> 
> 2- In the sha_leftovers == 2 and sha_leftovers == 3 case, bstatus was
>    being placed on the wrong half of sha_text, overlapping the leftover
>    ksv value
> 
> 3- In the sha_leftovers == 2 case, we need to manually terminate the
>    byte stream with 0x80 since the hardware doesn't have enough room to
>    add it after writing M0
> 
> The upside is that all of the "HDCP supported" HDMI repeaters I could
> find on Amazon just strip HDCP anyways, so it turns out to be _really_
> hard to hit any of these cases without an MST hub, which is not (yet)
> supported. Oh, and the sha_leftovers == 1 case works perfectly!

Yes. The repeaters tested at our side too with sha_leftovers = 1 with
mostly ksv count of 1. non availability of the repeaters is killer here.
> 
> 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+
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-2-sean@poorly.run #v1
> 
> Changes in v2:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 25 +++++++++++++++++------
>  include/drm/drm_hdcp.h                    |  3 +++
>  2 files changed, 22 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 0fdbd39f6641..eaab9008feef 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -335,8 +335,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);
Didn't hit this as ksv count was 1 mostly with sha_leftovers = 1.
Thanks for fixing it.
> +			sha_text |= ksv[j] << off;
> +		}
>  
>  		ret = intel_write_sha_text(dev_priv, sha_text);
>  		if (ret < 0)
> @@ -426,7 +428,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
>  	} else if (sha_leftovers == 2) {
>  		/* Write 32 bits of text */
>  		I915_WRITE(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;
> @@ -440,16 +442,27 @@ 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.
> +		 */
> +		I915_WRITE(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) */
>  		I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32);
> -		sha_text |= bstatus[0] << 24;
> +		sha_text |= bstatus[0];

Looks good to me though this path never been exercised. Hopefully MST
will do it.

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

>  		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 */
>  		I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_8);
>  		ret = intel_write_sha_text(dev_priv, bstatus[1]);
>  		if (ret < 0)
> diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> index 06a11202a097..20498c822204 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	[flat|nested] 61+ messages in thread

* Re: [Intel-gfx] [PATCH v2 01/12] drm/i915: Fix sha_text population code
@ 2019-12-13 10:20     ` Ramalingam C
  0 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 10:20 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, stable

On 2019-12-12 at 14:02:19 -0500, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> This patch fixes a few bugs:
> 
> 1- We weren't taking into account sha_leftovers when adding multiple
>    ksvs to sha_text. As such, we were or'ing the end of ksv[j - 1] with
>    the beginning of ksv[j]
> 
> 2- In the sha_leftovers == 2 and sha_leftovers == 3 case, bstatus was
>    being placed on the wrong half of sha_text, overlapping the leftover
>    ksv value
> 
> 3- In the sha_leftovers == 2 case, we need to manually terminate the
>    byte stream with 0x80 since the hardware doesn't have enough room to
>    add it after writing M0
> 
> The upside is that all of the "HDCP supported" HDMI repeaters I could
> find on Amazon just strip HDCP anyways, so it turns out to be _really_
> hard to hit any of these cases without an MST hub, which is not (yet)
> supported. Oh, and the sha_leftovers == 1 case works perfectly!

Yes. The repeaters tested at our side too with sha_leftovers = 1 with
mostly ksv count of 1. non availability of the repeaters is killer here.
> 
> 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+
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-2-sean@poorly.run #v1
> 
> Changes in v2:
> -None
> ---
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 25 +++++++++++++++++------
>  include/drm/drm_hdcp.h                    |  3 +++
>  2 files changed, 22 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 0fdbd39f6641..eaab9008feef 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -335,8 +335,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);
Didn't hit this as ksv count was 1 mostly with sha_leftovers = 1.
Thanks for fixing it.
> +			sha_text |= ksv[j] << off;
> +		}
>  
>  		ret = intel_write_sha_text(dev_priv, sha_text);
>  		if (ret < 0)
> @@ -426,7 +428,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
>  	} else if (sha_leftovers == 2) {
>  		/* Write 32 bits of text */
>  		I915_WRITE(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;
> @@ -440,16 +442,27 @@ 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.
> +		 */
> +		I915_WRITE(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) */
>  		I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_32);
> -		sha_text |= bstatus[0] << 24;
> +		sha_text |= bstatus[0];

Looks good to me though this path never been exercised. Hopefully MST
will do it.

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

>  		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 */
>  		I915_WRITE(HDCP_REP_CTL, rep_ctl | HDCP_SHA1_TEXT_8);
>  		ret = intel_write_sha_text(dev_priv, bstatus[1]);
>  		if (ret < 0)
> diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> index 06a11202a097..20498c822204 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	[flat|nested] 61+ messages in thread

* Re: [PATCH v2 02/12] drm/i915: Clear the repeater bit on HDCP disable
  2019-12-12 19:02   ` Sean Paul
  (?)
@ 2019-12-13 10:29     ` Ramalingam C
  -1 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 10:29 UTC (permalink / raw)
  To: Sean Paul
  Cc: dri-devel, intel-gfx, ville.syrjala, jani.nikula,
	joonas.lahtinen, rodrigo.vivi, daniel.vetter, Sean Paul,
	Chris Wilson, stable

On 2019-12-12 at 14:02:20 -0500, Sean Paul wrote:
> 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+
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> 
> Changes in v2:
> -Added to the set
> ---
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index eaab9008feef..c4394c8e10eb 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -773,6 +773,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
>  	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
>  	enum port port = intel_dig_port->base.port;
>  	enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
> +	u32 repeater_ctl;
>  	int ret;
>  
>  	DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
> @@ -787,6 +788,10 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
>  		return -ETIMEDOUT;
>  	}
>  
> +	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
> +						   port);
> +	I915_WRITE(HDCP_REP_CTL, I915_READ(HDCP_REP_CTL) & ~repeater_ctl);
Do you think it will help to (double) clear HDCP_REP_CTL when detect a
sink which is non repeater!? But yes disable will be executed on all
HDCP exits.

> +
LGTM

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

>  	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
>  	if (ret) {
>  		DRM_ERROR("Failed to disable HDCP signalling\n");
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS
> 

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

* Re: [PATCH v2 02/12] drm/i915: Clear the repeater bit on HDCP disable
@ 2019-12-13 10:29     ` Ramalingam C
  0 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 10:29 UTC (permalink / raw)
  To: Sean Paul
  Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, rodrigo.vivi, stable

On 2019-12-12 at 14:02:20 -0500, Sean Paul wrote:
> 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+
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> 
> Changes in v2:
> -Added to the set
> ---
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index eaab9008feef..c4394c8e10eb 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -773,6 +773,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
>  	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
>  	enum port port = intel_dig_port->base.port;
>  	enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
> +	u32 repeater_ctl;
>  	int ret;
>  
>  	DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
> @@ -787,6 +788,10 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
>  		return -ETIMEDOUT;
>  	}
>  
> +	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
> +						   port);
> +	I915_WRITE(HDCP_REP_CTL, I915_READ(HDCP_REP_CTL) & ~repeater_ctl);
Do you think it will help to (double) clear HDCP_REP_CTL when detect a
sink which is non repeater!? But yes disable will be executed on all
HDCP exits.

> +
LGTM

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

>  	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
>  	if (ret) {
>  		DRM_ERROR("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	[flat|nested] 61+ messages in thread

* Re: [Intel-gfx] [PATCH v2 02/12] drm/i915: Clear the repeater bit on HDCP disable
@ 2019-12-13 10:29     ` Ramalingam C
  0 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 10:29 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, stable

On 2019-12-12 at 14:02:20 -0500, Sean Paul wrote:
> 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+
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> 
> Changes in v2:
> -Added to the set
> ---
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index eaab9008feef..c4394c8e10eb 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -773,6 +773,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
>  	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
>  	enum port port = intel_dig_port->base.port;
>  	enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
> +	u32 repeater_ctl;
>  	int ret;
>  
>  	DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
> @@ -787,6 +788,10 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
>  		return -ETIMEDOUT;
>  	}
>  
> +	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
> +						   port);
> +	I915_WRITE(HDCP_REP_CTL, I915_READ(HDCP_REP_CTL) & ~repeater_ctl);
Do you think it will help to (double) clear HDCP_REP_CTL when detect a
sink which is non repeater!? But yes disable will be executed on all
HDCP exits.

> +
LGTM

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

>  	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
>  	if (ret) {
>  		DRM_ERROR("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	[flat|nested] 61+ messages in thread

* Re: [PATCH v2 03/12] drm/i915: WARN if HDCP signalling is enabled upon disable
  2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
@ 2019-12-13 10:37     ` Ramalingam C
  -1 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 10:37 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, rodrigo.vivi

On 2019-12-12 at 14:02:21 -0500, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> HDCP signalling should not be left on, WARN if it is
LGTM

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> 
> Changes in v2:
> - Added to the set in lieu of just clearing the bit
> ---
>  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 5b6f32517c75..4a5bdf3ef51d 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1951,6 +1951,8 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
>  	i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
>  	u32 val = I915_READ(reg);
>  
> +	WARN_ON(val & TRANS_DDI_HDCP_SIGNALLING);
> +
>  	if (INTEL_GEN(dev_priv) >= 12) {
>  		val &= ~(TRANS_DDI_FUNC_ENABLE | TGL_TRANS_DDI_PORT_MASK |
>  			 TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
> -- 
> 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] 61+ messages in thread

* Re: [Intel-gfx] [PATCH v2 03/12] drm/i915: WARN if HDCP signalling is enabled upon disable
@ 2019-12-13 10:37     ` Ramalingam C
  0 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 10:37 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2019-12-12 at 14:02:21 -0500, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> HDCP signalling should not be left on, WARN if it is
LGTM

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> 
> Changes in v2:
> - Added to the set in lieu of just clearing the bit
> ---
>  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 5b6f32517c75..4a5bdf3ef51d 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1951,6 +1951,8 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
>  	i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
>  	u32 val = I915_READ(reg);
>  
> +	WARN_ON(val & TRANS_DDI_HDCP_SIGNALLING);
> +
>  	if (INTEL_GEN(dev_priv) >= 12) {
>  		val &= ~(TRANS_DDI_FUNC_ENABLE | TGL_TRANS_DDI_PORT_MASK |
>  			 TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
> -- 
> 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] 61+ messages in thread

* Re: [PATCH v2 05/12] drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling
  2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
@ 2019-12-13 10:43     ` Ramalingam C
  -1 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 10:43 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, rodrigo.vivi

On 2019-12-12 at 14:02:23 -0500, Sean Paul wrote:
> 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.
you mean intel_hdcp

LGTM.

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> 
> This is particularly important for MST.
> 
> Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> 
> Changes in v2:
> - Added to the set
> ---
>  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        | 11 +++++++----
>  drivers/gpu/drm/i915/display/intel_hdmi.c        | 16 +++++++++++-----
>  6 files changed, 26 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 4a5bdf3ef51d..bbdaa6d1deec 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1971,12 +1971,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;
>  
> @@ -1985,18 +1985,13 @@ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
>  	if (WARN_ON(!wakeref))
>  		return -ENXIO;
>  
> -	if (WARN_ON(!intel_encoder->get_hw_state(intel_encoder, &pipe))) {
> -		ret = -EIO;
> -		goto out;
> -	}
> -
> -	tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe));
> +	tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
>  	if (enable)
>  		tmp |= TRANS_DDI_HDCP_SIGNALLING;
>  	else
>  		tmp &= ~TRANS_DDI_HDCP_SIGNALLING;
> -	I915_WRITE(TRANS_DDI_FUNC_CTL(pipe), tmp);
> -out:
> +	I915_WRITE(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 19aeab1246ee..0644edaa7542 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.h
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.h
> @@ -18,6 +18,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_encoder *intel_encoder,
>  				const struct intel_crtc_state *old_crtc_state,
> @@ -45,6 +46,7 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
>  u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder,
>  				 u8 voltage_swing);
>  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);
>  int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 83ea04149b77..687768a913f6 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -301,6 +301,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 5576193b4fed..c1a228b5f879 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -6083,6 +6083,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 c4394c8e10eb..f8d56d3b2ddb 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -693,7 +693,7 @@ static int intel_hdcp_auth(struct intel_connector *connector)
>  			   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;
>  
> @@ -792,7 +792,8 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
>  						   port);
>  	I915_WRITE(HDCP_REP_CTL, I915_READ(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_ERROR("Failed to disable HDCP signalling\n");
>  		return ret;
> @@ -1552,7 +1553,8 @@ static int hdcp2_enable_encryption(struct intel_connector *connector)
>  	WARN_ON(I915_READ(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_ERROR("Failed to enable HDCP signalling. %d\n",
>  				  ret);
> @@ -1603,7 +1605,8 @@ static int hdcp2_disable_encryption(struct intel_connector *connector)
>  		DRM_DEBUG_KMS("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_ERROR("Failed to disable HDCP signalling. %d\n",
>  				  ret);
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index a89a09b25260..5066efadca85 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -1443,7 +1443,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 = conn_to_dig_port(connector);
> @@ -1460,12 +1461,14 @@ 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_ERROR("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_ERROR("Enable HDCP signalling failed (%d)\n", ret);
>  		return ret;
> @@ -1476,6 +1479,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;
> @@ -1486,7 +1490,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_ERROR("%s HDCP signalling failed (%d)\n",
>  			  enable ? "Enable" : "Disable", ret);
> @@ -1498,7 +1503,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	[flat|nested] 61+ messages in thread

* Re: [Intel-gfx] [PATCH v2 05/12] drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling
@ 2019-12-13 10:43     ` Ramalingam C
  0 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 10:43 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2019-12-12 at 14:02:23 -0500, Sean Paul wrote:
> 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.
you mean intel_hdcp

LGTM.

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> 
> This is particularly important for MST.
> 
> Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> 
> Changes in v2:
> - Added to the set
> ---
>  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        | 11 +++++++----
>  drivers/gpu/drm/i915/display/intel_hdmi.c        | 16 +++++++++++-----
>  6 files changed, 26 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 4a5bdf3ef51d..bbdaa6d1deec 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1971,12 +1971,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;
>  
> @@ -1985,18 +1985,13 @@ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
>  	if (WARN_ON(!wakeref))
>  		return -ENXIO;
>  
> -	if (WARN_ON(!intel_encoder->get_hw_state(intel_encoder, &pipe))) {
> -		ret = -EIO;
> -		goto out;
> -	}
> -
> -	tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe));
> +	tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
>  	if (enable)
>  		tmp |= TRANS_DDI_HDCP_SIGNALLING;
>  	else
>  		tmp &= ~TRANS_DDI_HDCP_SIGNALLING;
> -	I915_WRITE(TRANS_DDI_FUNC_CTL(pipe), tmp);
> -out:
> +	I915_WRITE(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 19aeab1246ee..0644edaa7542 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.h
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.h
> @@ -18,6 +18,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_encoder *intel_encoder,
>  				const struct intel_crtc_state *old_crtc_state,
> @@ -45,6 +46,7 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder);
>  u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder,
>  				 u8 voltage_swing);
>  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);
>  int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 83ea04149b77..687768a913f6 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -301,6 +301,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 5576193b4fed..c1a228b5f879 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -6083,6 +6083,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 c4394c8e10eb..f8d56d3b2ddb 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -693,7 +693,7 @@ static int intel_hdcp_auth(struct intel_connector *connector)
>  			   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;
>  
> @@ -792,7 +792,8 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
>  						   port);
>  	I915_WRITE(HDCP_REP_CTL, I915_READ(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_ERROR("Failed to disable HDCP signalling\n");
>  		return ret;
> @@ -1552,7 +1553,8 @@ static int hdcp2_enable_encryption(struct intel_connector *connector)
>  	WARN_ON(I915_READ(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_ERROR("Failed to enable HDCP signalling. %d\n",
>  				  ret);
> @@ -1603,7 +1605,8 @@ static int hdcp2_disable_encryption(struct intel_connector *connector)
>  		DRM_DEBUG_KMS("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_ERROR("Failed to disable HDCP signalling. %d\n",
>  				  ret);
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index a89a09b25260..5066efadca85 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -1443,7 +1443,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 = conn_to_dig_port(connector);
> @@ -1460,12 +1461,14 @@ 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_ERROR("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_ERROR("Enable HDCP signalling failed (%d)\n", ret);
>  		return ret;
> @@ -1476,6 +1479,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;
> @@ -1486,7 +1490,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_ERROR("%s HDCP signalling failed (%d)\n",
>  			  enable ? "Enable" : "Disable", ret);
> @@ -1498,7 +1503,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	[flat|nested] 61+ messages in thread

* Re: [PATCH v2 04/12] drm/i915: Intercept Aksv writes in the aux hooks
  2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
@ 2019-12-13 10:52     ` Ramalingam C
  -1 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 10:52 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, rodrigo.vivi

On 2019-12-12 at 14:02:22 -0500, Sean Paul wrote:
> 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>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-3-sean@poorly.run #v1
> 
> 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)

LGTM

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 62 ++++++++++++-------------
>  1 file changed, 29 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index fe31bbfd6c62..5576193b4fed 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1515,12 +1515,27 @@ 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)
>  {
>  	struct intel_dp *intel_dp = container_of(aux, struct intel_dp, aux);
>  	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);
> @@ -1541,7 +1556,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;
>  
> @@ -1564,7 +1579,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;
>  			/*
> @@ -5904,17 +5919,9 @@ static
>  int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
>  				u8 *an)
>  {
> -	struct intel_dp *intel_dp = enc_to_intel_dp(&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) {
> @@ -5924,29 +5931,18 @@ 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_DEBUG_KMS("Write Aksv over DP/AUX failed (%d)\n", ret);
> -		return ret;
> -	} else if (ret == 0) {
> -		DRM_DEBUG_KMS("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) {
> -		DRM_DEBUG_KMS("Aksv write: no DP_AUX_NATIVE_REPLY_ACK %x\n",
> -			      reply);
> -		return -EIO;
> +	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_DEBUG_KMS("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	[flat|nested] 61+ messages in thread

* Re: [Intel-gfx] [PATCH v2 04/12] drm/i915: Intercept Aksv writes in the aux hooks
@ 2019-12-13 10:52     ` Ramalingam C
  0 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 10:52 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2019-12-12 at 14:02:22 -0500, Sean Paul wrote:
> 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>
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-3-sean@poorly.run #v1
> 
> 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)

LGTM

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 62 ++++++++++++-------------
>  1 file changed, 29 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index fe31bbfd6c62..5576193b4fed 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1515,12 +1515,27 @@ 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)
>  {
>  	struct intel_dp *intel_dp = container_of(aux, struct intel_dp, aux);
>  	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);
> @@ -1541,7 +1556,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;
>  
> @@ -1564,7 +1579,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;
>  			/*
> @@ -5904,17 +5919,9 @@ static
>  int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
>  				u8 *an)
>  {
> -	struct intel_dp *intel_dp = enc_to_intel_dp(&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) {
> @@ -5924,29 +5931,18 @@ 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_DEBUG_KMS("Write Aksv over DP/AUX failed (%d)\n", ret);
> -		return ret;
> -	} else if (ret == 0) {
> -		DRM_DEBUG_KMS("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) {
> -		DRM_DEBUG_KMS("Aksv write: no DP_AUX_NATIVE_REPLY_ACK %x\n",
> -			      reply);
> -		return -EIO;
> +	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_DEBUG_KMS("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	[flat|nested] 61+ messages in thread

* Re: [PATCH v2 07/12] drm/i915: Protect workers against disappearing connectors
  2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
@ 2019-12-13 11:10     ` Ramalingam C
  -1 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 11:10 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, rodrigo.vivi

On 2019-12-12 at 14:02:25 -0500, Sean Paul wrote:
> 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.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Will there be an instance where prop_work is scheduled but before
execution cancelled from the queue itself? This will leak the connector
reference.

Atleast hdcp stack is not requesting for such action. So Looks good to me.

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> 
> Changes in v2:
> - Added to the set
> ---
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 38 ++++++++++++++++++++---
>  1 file changed, 33 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 798e7e1a19fc..c79dca2c74d1 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -863,8 +863,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 */
> @@ -954,6 +956,8 @@ static void intel_hdcp_prop_work(struct work_struct *work)
>  
>  	mutex_unlock(&hdcp->mutex);
>  	drm_modeset_unlock(&dev->mode_config.connection_mutex);
> +
> +	drm_connector_put(&connector->base);
>  }
>  
>  bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
> @@ -1802,6 +1806,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);
> @@ -2076,12 +2083,33 @@ 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);
> +	WARN_ON(!drm_connector_is_unregistered(&connector->base));
> +
> +	/*
> +	 * Now that the connector is unregistered, 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).
> +	 */
> +	WARN_ON(work_pending(&hdcp->prop_work));
> +
> +	mutex_lock(&hdcp->mutex);
> +	kfree(hdcp->port_data.streams);
> +	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	[flat|nested] 61+ messages in thread

* Re: [Intel-gfx] [PATCH v2 07/12] drm/i915: Protect workers against disappearing connectors
@ 2019-12-13 11:10     ` Ramalingam C
  0 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 11:10 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2019-12-12 at 14:02:25 -0500, Sean Paul wrote:
> 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.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
Will there be an instance where prop_work is scheduled but before
execution cancelled from the queue itself? This will leak the connector
reference.

Atleast hdcp stack is not requesting for such action. So Looks good to me.

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> 
> Changes in v2:
> - Added to the set
> ---
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 38 ++++++++++++++++++++---
>  1 file changed, 33 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> index 798e7e1a19fc..c79dca2c74d1 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -863,8 +863,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 */
> @@ -954,6 +956,8 @@ static void intel_hdcp_prop_work(struct work_struct *work)
>  
>  	mutex_unlock(&hdcp->mutex);
>  	drm_modeset_unlock(&dev->mode_config.connection_mutex);
> +
> +	drm_connector_put(&connector->base);
>  }
>  
>  bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
> @@ -1802,6 +1806,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);
> @@ -2076,12 +2083,33 @@ 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);
> +	WARN_ON(!drm_connector_is_unregistered(&connector->base));
> +
> +	/*
> +	 * Now that the connector is unregistered, 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).
> +	 */
> +	WARN_ON(work_pending(&hdcp->prop_work));
> +
> +	mutex_lock(&hdcp->mutex);
> +	kfree(hdcp->port_data.streams);
> +	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	[flat|nested] 61+ messages in thread

* Re: [PATCH v2 06/12] drm/i915: Factor out hdcp->value assignments
  2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
@ 2019-12-13 11:11     ` Ramalingam C
  -1 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 11:11 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, rodrigo.vivi

On 2019-12-12 at 14:02:24 -0500, Sean Paul wrote:
> 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.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-7-sean@poorly.run #v1
LGTM.

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> 
> Changes in v2:
> -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 f8d56d3b2ddb..798e7e1a19fc 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -852,6 +852,21 @@ 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;
> +
> +	WARN_ON(!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)
>  {
> @@ -878,15 +893,16 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
>  			  I915_READ(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;
>  	}
> @@ -897,16 +913,18 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
>  	ret = _intel_hdcp_disable(connector);
>  	if (ret) {
>  		DRM_ERROR("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_ERROR("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;
>  	}
>  
> @@ -1716,16 +1734,18 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
>  			  I915_READ(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;
>  	}
> @@ -1737,8 +1757,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
>  		DRM_DEBUG_KMS("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_DEBUG_KMS("[%s:%d] Repeater topology auth failed.(%d)\n",
> @@ -1753,8 +1774,8 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
>  	if (ret) {
>  		DRM_ERROR("[%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;
>  	}
>  
> @@ -1763,8 +1784,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
>  		DRM_DEBUG_KMS("[%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;
>  	}
>  
> @@ -2004,8 +2026,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);
> @@ -2023,7 +2046,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	[flat|nested] 61+ messages in thread

* Re: [Intel-gfx] [PATCH v2 06/12] drm/i915: Factor out hdcp->value assignments
@ 2019-12-13 11:11     ` Ramalingam C
  0 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 11:11 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2019-12-12 at 14:02:24 -0500, Sean Paul wrote:
> 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.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-7-sean@poorly.run #v1
LGTM.

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> 
> Changes in v2:
> -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 f8d56d3b2ddb..798e7e1a19fc 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -852,6 +852,21 @@ 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;
> +
> +	WARN_ON(!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)
>  {
> @@ -878,15 +893,16 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
>  			  I915_READ(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;
>  	}
> @@ -897,16 +913,18 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
>  	ret = _intel_hdcp_disable(connector);
>  	if (ret) {
>  		DRM_ERROR("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_ERROR("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;
>  	}
>  
> @@ -1716,16 +1734,18 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
>  			  I915_READ(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;
>  	}
> @@ -1737,8 +1757,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
>  		DRM_DEBUG_KMS("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_DEBUG_KMS("[%s:%d] Repeater topology auth failed.(%d)\n",
> @@ -1753,8 +1774,8 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
>  	if (ret) {
>  		DRM_ERROR("[%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;
>  	}
>  
> @@ -1763,8 +1784,9 @@ static int intel_hdcp2_check_link(struct intel_connector *connector)
>  		DRM_DEBUG_KMS("[%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;
>  	}
>  
> @@ -2004,8 +2026,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);
> @@ -2023,7 +2046,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	[flat|nested] 61+ messages in thread

* Re: [PATCH v2 11/12] drm/i915: Expose HDCP shim functions from dp for use by dp_mst
  2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
@ 2019-12-13 11:25     ` Ville Syrjälä
  -1 siblings, 0 replies; 61+ messages in thread
From: Ville Syrjälä @ 2019-12-13 11:25 UTC (permalink / raw)
  To: Sean Paul; +Cc: intel-gfx, daniel.vetter, Sean Paul, dri-devel, rodrigo.vivi

On Thu, Dec 12, 2019 at 02:02:29PM -0500, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> These functions are all the same for dp and dp_mst, so expose them for
> use by the dp_mst hdcp implementation.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-11-sean@poorly.run #v1
> 
> Changes in v2:
> -none
> ---
>  .../drm/i915/display/intel_display_types.h    | 22 +++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_dp.c       | 14 ++----------
>  2 files changed, 24 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index ac5af925e403..b9e1f4638ff2 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h

Don't we have have intel_dp.h these days?

In fact might be nice to lift all the DP hdcp stuff into its own file.
But not sure if that's doable or not.

> @@ -1636,4 +1636,26 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
>  	return i915_ggtt_offset(state->vma);
>  }
>  
> +int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
> +				u8 *an);
> +int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
> +			    u8 *bksv);
> +int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
> +				      u8 *bstatus);
> +int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
> +			     u8 *bcaps);
> +int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
> +				   bool *repeater_present);
> +int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
> +				u8 *ri_prime);
> +int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
> +				 bool *ksv_ready);
> +int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
> +				int num_downstream, u8 *ksv_fifo);
> +int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
> +				    int i, u32 *part);
> +bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port);
> +int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
> +			  bool *hdcp_capable);
> +
>  #endif /*  __INTEL_DISPLAY_TYPES_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 155067657e23..3d62b1b7224e 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -5915,7 +5915,6 @@ static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
>  		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)
>  {
> @@ -5947,8 +5946,7 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
> -				   u8 *bksv)
> +int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port, u8 *bksv)
>  {
>  	ssize_t ret;
>  	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
> @@ -5960,7 +5958,7 @@ static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
> +int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
>  				      u8 *bstatus)
>  {
>  	ssize_t ret;
> @@ -5978,7 +5976,6 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
>  			     u8 *bcaps)
>  {
> @@ -5994,7 +5991,6 @@ int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
>  				   bool *repeater_present)
>  {
> @@ -6009,7 +6005,6 @@ int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
>  				u8 *ri_prime)
>  {
> @@ -6023,7 +6018,6 @@ int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
>  				 bool *ksv_ready)
>  {
> @@ -6039,7 +6033,6 @@ int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
>  				int num_downstream, u8 *ksv_fifo)
>  {
> @@ -6062,7 +6055,6 @@ int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
>  				    int i, u32 *part)
>  {
> @@ -6090,7 +6082,6 @@ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
>  {
>  	ssize_t ret;
> @@ -6106,7 +6097,6 @@ bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
>  	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)
>  {
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS

-- 
Ville Syrjälä
Intel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH v2 11/12] drm/i915: Expose HDCP shim functions from dp for use by dp_mst
@ 2019-12-13 11:25     ` Ville Syrjälä
  0 siblings, 0 replies; 61+ messages in thread
From: Ville Syrjälä @ 2019-12-13 11:25 UTC (permalink / raw)
  To: Sean Paul; +Cc: intel-gfx, daniel.vetter, Sean Paul, dri-devel

On Thu, Dec 12, 2019 at 02:02:29PM -0500, Sean Paul wrote:
> From: Sean Paul <seanpaul@chromium.org>
> 
> These functions are all the same for dp and dp_mst, so expose them for
> use by the dp_mst hdcp implementation.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-11-sean@poorly.run #v1
> 
> Changes in v2:
> -none
> ---
>  .../drm/i915/display/intel_display_types.h    | 22 +++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_dp.c       | 14 ++----------
>  2 files changed, 24 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index ac5af925e403..b9e1f4638ff2 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h

Don't we have have intel_dp.h these days?

In fact might be nice to lift all the DP hdcp stuff into its own file.
But not sure if that's doable or not.

> @@ -1636,4 +1636,26 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
>  	return i915_ggtt_offset(state->vma);
>  }
>  
> +int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
> +				u8 *an);
> +int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
> +			    u8 *bksv);
> +int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
> +				      u8 *bstatus);
> +int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
> +			     u8 *bcaps);
> +int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
> +				   bool *repeater_present);
> +int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
> +				u8 *ri_prime);
> +int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
> +				 bool *ksv_ready);
> +int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
> +				int num_downstream, u8 *ksv_fifo);
> +int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
> +				    int i, u32 *part);
> +bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port);
> +int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
> +			  bool *hdcp_capable);
> +
>  #endif /*  __INTEL_DISPLAY_TYPES_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 155067657e23..3d62b1b7224e 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -5915,7 +5915,6 @@ static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
>  		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)
>  {
> @@ -5947,8 +5946,7 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
> -				   u8 *bksv)
> +int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port, u8 *bksv)
>  {
>  	ssize_t ret;
>  	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
> @@ -5960,7 +5958,7 @@ static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
> +int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
>  				      u8 *bstatus)
>  {
>  	ssize_t ret;
> @@ -5978,7 +5976,6 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
>  			     u8 *bcaps)
>  {
> @@ -5994,7 +5991,6 @@ int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
>  				   bool *repeater_present)
>  {
> @@ -6009,7 +6005,6 @@ int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
>  				u8 *ri_prime)
>  {
> @@ -6023,7 +6018,6 @@ int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
>  				 bool *ksv_ready)
>  {
> @@ -6039,7 +6033,6 @@ int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
>  				int num_downstream, u8 *ksv_fifo)
>  {
> @@ -6062,7 +6055,6 @@ int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
>  				    int i, u32 *part)
>  {
> @@ -6090,7 +6082,6 @@ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
>  	return 0;
>  }
>  
> -static
>  bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
>  {
>  	ssize_t ret;
> @@ -6106,7 +6097,6 @@ bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
>  	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)
>  {
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS

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

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

* Re: [PATCH v2 08/12] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
  2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
@ 2019-12-13 11:58     ` Ramalingam C
  -1 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 11:58 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, rodrigo.vivi

On 2019-12-12 at 14:02:26 -0500, 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.
Sean,

We have a complication here. till ICL this will work as the HDCP
instance is port based. But from TGL, HDCP is transcoder based.

We need to handle MST HDCP enable and disable differently for <=gen11 and >gen11.
> 
> In order to achieve this, we need to keep a refcount in intel_digital_port
> and protect it using a new hdcp_mutex.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-8-sean@poorly.run #v1
> 
> Changes in v2:
> - Move the toggle_signalling call into _intel_hdcp_disable so it's called from check_work
> ---
>  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     | 52 +++++++++++++++----
>  drivers/gpu/drm/i915/display/intel_hdmi.c     |  2 +
>  5 files changed, 55 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index bbdaa6d1deec..ea8dd8dbc445 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4788,6 +4788,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
>  
>  	encoder = &intel_dig_port->base;
>  
> +	mutex_init(&intel_dig_port->hdcp_mutex);
> +	intel_dig_port->num_hdcp_streams = 0;
> +
>  	drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
>  			 DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port));
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 687768a913f6..8e98840fc597 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1354,6 +1354,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 c1a228b5f879..155067657e23 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -7580,6 +7580,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);
its initialized at ddi_init itself.
> +
>  	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 c79dca2c74d1..fbbd4da7c491 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -779,6 +779,19 @@ static int _intel_
hdcp_disable(struct intel_connector *connector)
>  	DRM_DEBUG_KMS("[%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;
> +	}
This wont work for TGL+, where HDCP instance is transcoder based. we
need to disable the HDCP per stream for TGL+
> +
>  	hdcp->hdcp_encrypted = false;
>  	I915_WRITE(HDCP_CONF(dev_priv, cpu_transcoder, port), 0);
>  	if (intel_de_wait_for_clear(dev_priv,
> @@ -855,6 +868,7 @@ 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 intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  
>  	WARN_ON(!mutex_is_locked(&hdcp->mutex));
> @@ -862,6 +876,15 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
>  	if (hdcp->value == value)
>  		return;
>  
> +	WARN_ON(!mutex_is_locked(&intel_dig_port->hdcp_mutex));
> +
> +	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
> +		if (!WARN_ON(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);
> @@ -880,6 +903,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 */
> @@ -931,6 +956,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;
>  }
> @@ -1996,6 +2022,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 = conn_to_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
>  	int ret = -EINVAL;
> @@ -2004,6 +2031,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
>  		return -ENOENT;
>  
>  	mutex_lock(&hdcp->mutex);
> +	mutex_lock(&intel_dig_port->hdcp_mutex);
>  	WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
>  	hdcp->content_type = content_type;
>  
> @@ -2038,12 +2066,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 = conn_to_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	int ret = 0;
>  
> @@ -2051,17 +2081,21 @@ 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) {
> -		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(&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 5066efadca85..905b188782ed 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -3247,6 +3247,8 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
>  
>  	intel_encoder = &intel_dig_port->base;
>  
> +	mutex_init(&intel_dig_port->hdcp_mutex);
its initialized at ddi_init itself.

-Ram
> +
>  	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] 61+ messages in thread

* Re: [Intel-gfx] [PATCH v2 08/12] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
@ 2019-12-13 11:58     ` Ramalingam C
  0 siblings, 0 replies; 61+ messages in thread
From: Ramalingam C @ 2019-12-13 11:58 UTC (permalink / raw)
  To: Sean Paul; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On 2019-12-12 at 14:02:26 -0500, 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.
Sean,

We have a complication here. till ICL this will work as the HDCP
instance is port based. But from TGL, HDCP is transcoder based.

We need to handle MST HDCP enable and disable differently for <=gen11 and >gen11.
> 
> In order to achieve this, we need to keep a refcount in intel_digital_port
> and protect it using a new hdcp_mutex.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-8-sean@poorly.run #v1
> 
> Changes in v2:
> - Move the toggle_signalling call into _intel_hdcp_disable so it's called from check_work
> ---
>  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     | 52 +++++++++++++++----
>  drivers/gpu/drm/i915/display/intel_hdmi.c     |  2 +
>  5 files changed, 55 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index bbdaa6d1deec..ea8dd8dbc445 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4788,6 +4788,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
>  
>  	encoder = &intel_dig_port->base;
>  
> +	mutex_init(&intel_dig_port->hdcp_mutex);
> +	intel_dig_port->num_hdcp_streams = 0;
> +
>  	drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
>  			 DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port));
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 687768a913f6..8e98840fc597 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1354,6 +1354,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 c1a228b5f879..155067657e23 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -7580,6 +7580,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);
its initialized at ddi_init itself.
> +
>  	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 c79dca2c74d1..fbbd4da7c491 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> @@ -779,6 +779,19 @@ static int _intel_
hdcp_disable(struct intel_connector *connector)
>  	DRM_DEBUG_KMS("[%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;
> +	}
This wont work for TGL+, where HDCP instance is transcoder based. we
need to disable the HDCP per stream for TGL+
> +
>  	hdcp->hdcp_encrypted = false;
>  	I915_WRITE(HDCP_CONF(dev_priv, cpu_transcoder, port), 0);
>  	if (intel_de_wait_for_clear(dev_priv,
> @@ -855,6 +868,7 @@ 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 intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  
>  	WARN_ON(!mutex_is_locked(&hdcp->mutex));
> @@ -862,6 +876,15 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
>  	if (hdcp->value == value)
>  		return;
>  
> +	WARN_ON(!mutex_is_locked(&intel_dig_port->hdcp_mutex));
> +
> +	if (hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
> +		if (!WARN_ON(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);
> @@ -880,6 +903,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 */
> @@ -931,6 +956,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;
>  }
> @@ -1996,6 +2022,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 = conn_to_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
>  	int ret = -EINVAL;
> @@ -2004,6 +2031,7 @@ int intel_hdcp_enable(struct intel_connector *connector,
>  		return -ENOENT;
>  
>  	mutex_lock(&hdcp->mutex);
> +	mutex_lock(&intel_dig_port->hdcp_mutex);
>  	WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
>  	hdcp->content_type = content_type;
>  
> @@ -2038,12 +2066,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 = conn_to_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	int ret = 0;
>  
> @@ -2051,17 +2081,21 @@ 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) {
> -		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(&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 5066efadca85..905b188782ed 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -3247,6 +3247,8 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
>  
>  	intel_encoder = &intel_dig_port->base;
>  
> +	mutex_init(&intel_dig_port->hdcp_mutex);
its initialized at ddi_init itself.

-Ram
> +
>  	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] 61+ messages in thread

* Re: [PATCH v2 11/12] drm/i915: Expose HDCP shim functions from dp for use by dp_mst
  2019-12-13 11:25     ` [Intel-gfx] " Ville Syrjälä
@ 2019-12-13 11:59       ` Jani Nikula
  -1 siblings, 0 replies; 61+ messages in thread
From: Jani Nikula @ 2019-12-13 11:59 UTC (permalink / raw)
  To: Ville Syrjälä, Sean Paul
  Cc: daniel.vetter, intel-gfx, dri-devel, rodrigo.vivi, Sean Paul

On Fri, 13 Dec 2019, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Thu, Dec 12, 2019 at 02:02:29PM -0500, Sean Paul wrote:
>> From: Sean Paul <seanpaul@chromium.org>
>> 
>> These functions are all the same for dp and dp_mst, so expose them for
>> use by the dp_mst hdcp implementation.
>> 
>> Signed-off-by: Sean Paul <seanpaul@chromium.org>
>> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-11-sean@poorly.run #v1
>> 
>> Changes in v2:
>> -none
>> ---
>>  .../drm/i915/display/intel_display_types.h    | 22 +++++++++++++++++++
>>  drivers/gpu/drm/i915/display/intel_dp.c       | 14 ++----------
>>  2 files changed, 24 insertions(+), 12 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index ac5af925e403..b9e1f4638ff2 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>
> Don't we have have intel_dp.h these days?
>
> In fact might be nice to lift all the DP hdcp stuff into its own file.

Agreed.

> But not sure if that's doable or not.

I think it's in fact patch 4 in this series that makes it doable. Maybe
you could keep the functions static in the new file, and have the struct
intel_hdcp_shim there too?

BR,
Jani.


>
>> @@ -1636,4 +1636,26 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
>>  	return i915_ggtt_offset(state->vma);
>>  }
>>  
>> +int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
>> +				u8 *an);
>> +int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
>> +			    u8 *bksv);
>> +int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
>> +				      u8 *bstatus);
>> +int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
>> +			     u8 *bcaps);
>> +int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
>> +				   bool *repeater_present);
>> +int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
>> +				u8 *ri_prime);
>> +int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
>> +				 bool *ksv_ready);
>> +int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
>> +				int num_downstream, u8 *ksv_fifo);
>> +int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
>> +				    int i, u32 *part);
>> +bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port);
>> +int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
>> +			  bool *hdcp_capable);
>> +
>>  #endif /*  __INTEL_DISPLAY_TYPES_H__ */
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
>> index 155067657e23..3d62b1b7224e 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
>> @@ -5915,7 +5915,6 @@ static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
>>  		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)
>>  {
>> @@ -5947,8 +5946,7 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
>> -				   u8 *bksv)
>> +int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port, u8 *bksv)
>>  {
>>  	ssize_t ret;
>>  	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
>> @@ -5960,7 +5958,7 @@ static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
>> +int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
>>  				      u8 *bstatus)
>>  {
>>  	ssize_t ret;
>> @@ -5978,7 +5976,6 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
>>  			     u8 *bcaps)
>>  {
>> @@ -5994,7 +5991,6 @@ int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
>>  				   bool *repeater_present)
>>  {
>> @@ -6009,7 +6005,6 @@ int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
>>  				u8 *ri_prime)
>>  {
>> @@ -6023,7 +6018,6 @@ int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
>>  				 bool *ksv_ready)
>>  {
>> @@ -6039,7 +6033,6 @@ int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
>>  				int num_downstream, u8 *ksv_fifo)
>>  {
>> @@ -6062,7 +6055,6 @@ int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
>>  				    int i, u32 *part)
>>  {
>> @@ -6090,7 +6082,6 @@ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
>>  {
>>  	ssize_t ret;
>> @@ -6106,7 +6097,6 @@ bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
>>  	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)
>>  {
>> -- 
>> Sean Paul, Software Engineer, Google / Chromium OS

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH v2 11/12] drm/i915: Expose HDCP shim functions from dp for use by dp_mst
@ 2019-12-13 11:59       ` Jani Nikula
  0 siblings, 0 replies; 61+ messages in thread
From: Jani Nikula @ 2019-12-13 11:59 UTC (permalink / raw)
  To: Ville Syrjälä, Sean Paul
  Cc: daniel.vetter, intel-gfx, dri-devel, Sean Paul

On Fri, 13 Dec 2019, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Thu, Dec 12, 2019 at 02:02:29PM -0500, Sean Paul wrote:
>> From: Sean Paul <seanpaul@chromium.org>
>> 
>> These functions are all the same for dp and dp_mst, so expose them for
>> use by the dp_mst hdcp implementation.
>> 
>> Signed-off-by: Sean Paul <seanpaul@chromium.org>
>> Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-11-sean@poorly.run #v1
>> 
>> Changes in v2:
>> -none
>> ---
>>  .../drm/i915/display/intel_display_types.h    | 22 +++++++++++++++++++
>>  drivers/gpu/drm/i915/display/intel_dp.c       | 14 ++----------
>>  2 files changed, 24 insertions(+), 12 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index ac5af925e403..b9e1f4638ff2 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>
> Don't we have have intel_dp.h these days?
>
> In fact might be nice to lift all the DP hdcp stuff into its own file.

Agreed.

> But not sure if that's doable or not.

I think it's in fact patch 4 in this series that makes it doable. Maybe
you could keep the functions static in the new file, and have the struct
intel_hdcp_shim there too?

BR,
Jani.


>
>> @@ -1636,4 +1636,26 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
>>  	return i915_ggtt_offset(state->vma);
>>  }
>>  
>> +int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
>> +				u8 *an);
>> +int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
>> +			    u8 *bksv);
>> +int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
>> +				      u8 *bstatus);
>> +int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
>> +			     u8 *bcaps);
>> +int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
>> +				   bool *repeater_present);
>> +int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
>> +				u8 *ri_prime);
>> +int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
>> +				 bool *ksv_ready);
>> +int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
>> +				int num_downstream, u8 *ksv_fifo);
>> +int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
>> +				    int i, u32 *part);
>> +bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port);
>> +int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
>> +			  bool *hdcp_capable);
>> +
>>  #endif /*  __INTEL_DISPLAY_TYPES_H__ */
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
>> index 155067657e23..3d62b1b7224e 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
>> @@ -5915,7 +5915,6 @@ static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
>>  		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)
>>  {
>> @@ -5947,8 +5946,7 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
>> -				   u8 *bksv)
>> +int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port, u8 *bksv)
>>  {
>>  	ssize_t ret;
>>  	ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
>> @@ -5960,7 +5958,7 @@ static int intel_dp_hdcp_read_bksv(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
>> +int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
>>  				      u8 *bstatus)
>>  {
>>  	ssize_t ret;
>> @@ -5978,7 +5976,6 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
>>  			     u8 *bcaps)
>>  {
>> @@ -5994,7 +5991,6 @@ int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
>>  				   bool *repeater_present)
>>  {
>> @@ -6009,7 +6005,6 @@ int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
>>  				u8 *ri_prime)
>>  {
>> @@ -6023,7 +6018,6 @@ int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
>>  				 bool *ksv_ready)
>>  {
>> @@ -6039,7 +6033,6 @@ int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
>>  				int num_downstream, u8 *ksv_fifo)
>>  {
>> @@ -6062,7 +6055,6 @@ int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *intel_dig_port,
>>  				    int i, u32 *part)
>>  {
>> @@ -6090,7 +6082,6 @@ int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *intel_dig_port,
>>  	return 0;
>>  }
>>  
>> -static
>>  bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
>>  {
>>  	ssize_t ret;
>> @@ -6106,7 +6097,6 @@ bool intel_dp_hdcp_check_link(struct intel_digital_port *intel_dig_port)
>>  	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)
>>  {
>> -- 
>> Sean Paul, Software Engineer, Google / Chromium OS

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 08/12] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
  2019-12-13 11:58     ` [Intel-gfx] " Ramalingam C
@ 2019-12-13 19:03       ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-13 19:03 UTC (permalink / raw)
  To: Ramalingam C
  Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, rodrigo.vivi, Sean Paul

On Fri, Dec 13, 2019 at 05:28:25PM +0530, Ramalingam C wrote:
> On 2019-12-12 at 14:02:26 -0500, 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.
> Sean,

Hey Ram,
Thanks for the quick reviews!

> 
> We have a complication here. till ICL this will work as the HDCP
> instance is port based. But from TGL, HDCP is transcoder based.
> 
> We need to handle MST HDCP enable and disable differently for <=gen11 and >gen11.
> > 
> > In order to achieve this, we need to keep a refcount in intel_digital_port
> > and protect it using a new hdcp_mutex.
> > 
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-8-sean@poorly.run #v1
> > 
> > Changes in v2:
> > - Move the toggle_signalling call into _intel_hdcp_disable so it's called from check_work
> > ---

/snip

> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -7580,6 +7580,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);
> its initialized at ddi_init itself.

I thought it would be safer to initialize the mutex for non-ddi based DP and
HDMI encoders as well.

> > +
> >  	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 c79dca2c74d1..fbbd4da7c491 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > @@ -779,6 +779,19 @@ static int _intel_
> hdcp_disable(struct intel_connector *connector)
> >  	DRM_DEBUG_KMS("[%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;
> > +	}
> This wont work for TGL+, where HDCP instance is transcoder based. we
> need to disable the HDCP per stream for TGL+

Hmm, I'm not sure how that would work for MST. Presumably you would still have
one port, but multiple transcoders feeding into it? Any chance you could send
me a bspec for HDMI on TGL+ so I can make adjustments? :-)

I also don't have any TGL hardware at my disposal, but hopefully soon.

Sean

> > +

/snip

> > diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> > index 5066efadca85..905b188782ed 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> > @@ -3247,6 +3247,8 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
> >  
> >  	intel_encoder = &intel_dig_port->base;
> >  
> > +	mutex_init(&intel_dig_port->hdcp_mutex);
> its initialized at ddi_init itself.
> 
> -Ram
> > +
> >  	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
> > 

-- 
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] 61+ messages in thread

* Re: [Intel-gfx] [PATCH v2 08/12] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it
@ 2019-12-13 19:03       ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-13 19:03 UTC (permalink / raw)
  To: Ramalingam C; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On Fri, Dec 13, 2019 at 05:28:25PM +0530, Ramalingam C wrote:
> On 2019-12-12 at 14:02:26 -0500, 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.
> Sean,

Hey Ram,
Thanks for the quick reviews!

> 
> We have a complication here. till ICL this will work as the HDCP
> instance is port based. But from TGL, HDCP is transcoder based.
> 
> We need to handle MST HDCP enable and disable differently for <=gen11 and >gen11.
> > 
> > In order to achieve this, we need to keep a refcount in intel_digital_port
> > and protect it using a new hdcp_mutex.
> > 
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > Link: https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-8-sean@poorly.run #v1
> > 
> > Changes in v2:
> > - Move the toggle_signalling call into _intel_hdcp_disable so it's called from check_work
> > ---

/snip

> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -7580,6 +7580,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);
> its initialized at ddi_init itself.

I thought it would be safer to initialize the mutex for non-ddi based DP and
HDMI encoders as well.

> > +
> >  	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 c79dca2c74d1..fbbd4da7c491 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > @@ -779,6 +779,19 @@ static int _intel_
> hdcp_disable(struct intel_connector *connector)
> >  	DRM_DEBUG_KMS("[%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;
> > +	}
> This wont work for TGL+, where HDCP instance is transcoder based. we
> need to disable the HDCP per stream for TGL+

Hmm, I'm not sure how that would work for MST. Presumably you would still have
one port, but multiple transcoders feeding into it? Any chance you could send
me a bspec for HDMI on TGL+ so I can make adjustments? :-)

I also don't have any TGL hardware at my disposal, but hopefully soon.

Sean

> > +

/snip

> > diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> > index 5066efadca85..905b188782ed 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> > @@ -3247,6 +3247,8 @@ void intel_hdmi_init(struct drm_i915_private *dev_priv,
> >  
> >  	intel_encoder = &intel_dig_port->base;
> >  
> > +	mutex_init(&intel_dig_port->hdcp_mutex);
> its initialized at ddi_init itself.
> 
> -Ram
> > +
> >  	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
> > 

-- 
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] 61+ messages in thread

* Re: [PATCH v2 07/12] drm/i915: Protect workers against disappearing connectors
  2019-12-13 11:10     ` [Intel-gfx] " Ramalingam C
@ 2019-12-13 19:04       ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-13 19:04 UTC (permalink / raw)
  To: Ramalingam C
  Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, rodrigo.vivi, Sean Paul

On Fri, Dec 13, 2019 at 04:40:33PM +0530, Ramalingam C wrote:
> On 2019-12-12 at 14:02:25 -0500, Sean Paul wrote:
> > 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.
> > 
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Will there be an instance where prop_work is scheduled but before
> execution cancelled from the queue itself? This will leak the connector
> reference.

No, prop_work is really quite simple, it just grabs some locks and updates the
property value. 

> 
> Atleast hdcp stack is not requesting for such action. So Looks good to me.
> 
> Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

Thanks, I'm going to dig into what we should do when hdcp_cleanup is called from
connector_init failure paths and revise this patch.

> > 
> > Changes in v2:
> > - Added to the set
> > ---
> >  drivers/gpu/drm/i915/display/intel_hdcp.c | 38 ++++++++++++++++++++---
> >  1 file changed, 33 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > index 798e7e1a19fc..c79dca2c74d1 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > @@ -863,8 +863,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 */
> > @@ -954,6 +956,8 @@ static void intel_hdcp_prop_work(struct work_struct *work)
> >  
> >  	mutex_unlock(&hdcp->mutex);
> >  	drm_modeset_unlock(&dev->mode_config.connection_mutex);
> > +
> > +	drm_connector_put(&connector->base);
> >  }
> >  
> >  bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
> > @@ -1802,6 +1806,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);
> > @@ -2076,12 +2083,33 @@ 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);
> > +	WARN_ON(!drm_connector_is_unregistered(&connector->base));
> > +
> > +	/*
> > +	 * Now that the connector is unregistered, 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).
> > +	 */
> > +	WARN_ON(work_pending(&hdcp->prop_work));
> > +
> > +	mutex_lock(&hdcp->mutex);
> > +	kfree(hdcp->port_data.streams);
> > +	mutex_unlock(&hdcp->mutex);
> >  }
> >  
> >  void intel_hdcp_atomic_check(struct drm_connector *connector,
> > -- 
> > Sean Paul, Software Engineer, Google / Chromium OS
> > 

-- 
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] 61+ messages in thread

* Re: [Intel-gfx] [PATCH v2 07/12] drm/i915: Protect workers against disappearing connectors
@ 2019-12-13 19:04       ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-13 19:04 UTC (permalink / raw)
  To: Ramalingam C; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel

On Fri, Dec 13, 2019 at 04:40:33PM +0530, Ramalingam C wrote:
> On 2019-12-12 at 14:02:25 -0500, Sean Paul wrote:
> > 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.
> > 
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> Will there be an instance where prop_work is scheduled but before
> execution cancelled from the queue itself? This will leak the connector
> reference.

No, prop_work is really quite simple, it just grabs some locks and updates the
property value. 

> 
> Atleast hdcp stack is not requesting for such action. So Looks good to me.
> 
> Reviewed-by: Ramalingam C <ramalingam.c@intel.com>

Thanks, I'm going to dig into what we should do when hdcp_cleanup is called from
connector_init failure paths and revise this patch.

> > 
> > Changes in v2:
> > - Added to the set
> > ---
> >  drivers/gpu/drm/i915/display/intel_hdcp.c | 38 ++++++++++++++++++++---
> >  1 file changed, 33 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > index 798e7e1a19fc..c79dca2c74d1 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > @@ -863,8 +863,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 */
> > @@ -954,6 +956,8 @@ static void intel_hdcp_prop_work(struct work_struct *work)
> >  
> >  	mutex_unlock(&hdcp->mutex);
> >  	drm_modeset_unlock(&dev->mode_config.connection_mutex);
> > +
> > +	drm_connector_put(&connector->base);
> >  }
> >  
> >  bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
> > @@ -1802,6 +1806,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);
> > @@ -2076,12 +2083,33 @@ 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);
> > +	WARN_ON(!drm_connector_is_unregistered(&connector->base));
> > +
> > +	/*
> > +	 * Now that the connector is unregistered, 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).
> > +	 */
> > +	WARN_ON(work_pending(&hdcp->prop_work));
> > +
> > +	mutex_lock(&hdcp->mutex);
> > +	kfree(hdcp->port_data.streams);
> > +	mutex_unlock(&hdcp->mutex);
> >  }
> >  
> >  void intel_hdcp_atomic_check(struct drm_connector *connector,
> > -- 
> > Sean Paul, Software Engineer, Google / Chromium OS
> > 

-- 
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] 61+ messages in thread

* Re: [PATCH v2 02/12] drm/i915: Clear the repeater bit on HDCP disable
  2019-12-13 10:29     ` Ramalingam C
  (?)
@ 2019-12-13 19:07       ` Sean Paul
  -1 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-13 19:07 UTC (permalink / raw)
  To: Ramalingam C
  Cc: Sean Paul, dri-devel, intel-gfx, ville.syrjala, jani.nikula,
	joonas.lahtinen, rodrigo.vivi, daniel.vetter, Sean Paul,
	Chris Wilson, stable

On Fri, Dec 13, 2019 at 03:59:02PM +0530, Ramalingam C wrote:
> On 2019-12-12 at 14:02:20 -0500, Sean Paul wrote:
> > 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+
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > 
> > Changes in v2:
> > -Added to the set
> > ---
> >  drivers/gpu/drm/i915/display/intel_hdcp.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > index eaab9008feef..c4394c8e10eb 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > @@ -773,6 +773,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
> >  	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
> >  	enum port port = intel_dig_port->base.port;
> >  	enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
> > +	u32 repeater_ctl;
> >  	int ret;
> >  
> >  	DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
> > @@ -787,6 +788,10 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
> >  		return -ETIMEDOUT;
> >  	}
> >  
> > +	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
> > +						   port);
> > +	I915_WRITE(HDCP_REP_CTL, I915_READ(HDCP_REP_CTL) & ~repeater_ctl);
> Do you think it will help to (double) clear HDCP_REP_CTL when detect a
> sink which is non repeater!? But yes disable will be executed on all
> HDCP exits.
> 

Yeah, that's probably a better idea. I was a little undecided on where to put it
and I think I settled on the disable path since that matches the way we handle
HDCP signalling. However if we always write REP_CTL, that cuts our callsites
back down to 1, which seems like a Good Thing.

Will revise.

Sean

> > +
> LGTM
> 
> Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> 
> >  	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
> >  	if (ret) {
> >  		DRM_ERROR("Failed to disable HDCP signalling\n");
> > -- 
> > Sean Paul, Software Engineer, Google / Chromium OS
> > 

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

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

* Re: [PATCH v2 02/12] drm/i915: Clear the repeater bit on HDCP disable
@ 2019-12-13 19:07       ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-13 19:07 UTC (permalink / raw)
  To: Ramalingam C
  Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, rodrigo.vivi,
	stable, Sean Paul

On Fri, Dec 13, 2019 at 03:59:02PM +0530, Ramalingam C wrote:
> On 2019-12-12 at 14:02:20 -0500, Sean Paul wrote:
> > 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+
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > 
> > Changes in v2:
> > -Added to the set
> > ---
> >  drivers/gpu/drm/i915/display/intel_hdcp.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > index eaab9008feef..c4394c8e10eb 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > @@ -773,6 +773,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
> >  	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
> >  	enum port port = intel_dig_port->base.port;
> >  	enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
> > +	u32 repeater_ctl;
> >  	int ret;
> >  
> >  	DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
> > @@ -787,6 +788,10 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
> >  		return -ETIMEDOUT;
> >  	}
> >  
> > +	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
> > +						   port);
> > +	I915_WRITE(HDCP_REP_CTL, I915_READ(HDCP_REP_CTL) & ~repeater_ctl);
> Do you think it will help to (double) clear HDCP_REP_CTL when detect a
> sink which is non repeater!? But yes disable will be executed on all
> HDCP exits.
> 

Yeah, that's probably a better idea. I was a little undecided on where to put it
and I think I settled on the disable path since that matches the way we handle
HDCP signalling. However if we always write REP_CTL, that cuts our callsites
back down to 1, which seems like a Good Thing.

Will revise.

Sean

> > +
> LGTM
> 
> Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> 
> >  	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
> >  	if (ret) {
> >  		DRM_ERROR("Failed to disable HDCP signalling\n");
> > -- 
> > Sean Paul, Software Engineer, Google / Chromium OS
> > 

-- 
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] 61+ messages in thread

* Re: [Intel-gfx] [PATCH v2 02/12] drm/i915: Clear the repeater bit on HDCP disable
@ 2019-12-13 19:07       ` Sean Paul
  0 siblings, 0 replies; 61+ messages in thread
From: Sean Paul @ 2019-12-13 19:07 UTC (permalink / raw)
  To: Ramalingam C; +Cc: daniel.vetter, intel-gfx, Sean Paul, dri-devel, stable

On Fri, Dec 13, 2019 at 03:59:02PM +0530, Ramalingam C wrote:
> On 2019-12-12 at 14:02:20 -0500, Sean Paul wrote:
> > 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+
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > 
> > Changes in v2:
> > -Added to the set
> > ---
> >  drivers/gpu/drm/i915/display/intel_hdcp.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > index eaab9008feef..c4394c8e10eb 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
> > @@ -773,6 +773,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
> >  	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
> >  	enum port port = intel_dig_port->base.port;
> >  	enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
> > +	u32 repeater_ctl;
> >  	int ret;
> >  
> >  	DRM_DEBUG_KMS("[%s:%d] HDCP is being disabled...\n",
> > @@ -787,6 +788,10 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
> >  		return -ETIMEDOUT;
> >  	}
> >  
> > +	repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
> > +						   port);
> > +	I915_WRITE(HDCP_REP_CTL, I915_READ(HDCP_REP_CTL) & ~repeater_ctl);
> Do you think it will help to (double) clear HDCP_REP_CTL when detect a
> sink which is non repeater!? But yes disable will be executed on all
> HDCP exits.
> 

Yeah, that's probably a better idea. I was a little undecided on where to put it
and I think I settled on the disable path since that matches the way we handle
HDCP signalling. However if we always write REP_CTL, that cuts our callsites
back down to 1, which seems like a Good Thing.

Will revise.

Sean

> > +
> LGTM
> 
> Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
> 
> >  	ret = hdcp->shim->toggle_signalling(intel_dig_port, false);
> >  	if (ret) {
> >  		DRM_ERROR("Failed to disable HDCP signalling\n");
> > -- 
> > Sean Paul, Software Engineer, Google / Chromium OS
> > 

-- 
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] 61+ messages in thread

end of thread, other threads:[~2019-12-13 21:34 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-12 19:02 [PATCH v2 00/12] drm/i915: Add support for HDCP 1.4 over MST connectors Sean Paul
2019-12-12 19:02 ` [Intel-gfx] " Sean Paul
2019-12-12 19:02 ` [PATCH v2 01/12] drm/i915: Fix sha_text population code Sean Paul
2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
2019-12-12 19:02   ` Sean Paul
2019-12-13 10:20   ` Ramalingam C
2019-12-13 10:20     ` [Intel-gfx] " Ramalingam C
2019-12-13 10:20     ` Ramalingam C
2019-12-12 19:02 ` [PATCH v2 02/12] drm/i915: Clear the repeater bit on HDCP disable Sean Paul
2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
2019-12-12 19:02   ` Sean Paul
2019-12-13 10:29   ` Ramalingam C
2019-12-13 10:29     ` [Intel-gfx] " Ramalingam C
2019-12-13 10:29     ` Ramalingam C
2019-12-13 19:07     ` Sean Paul
2019-12-13 19:07       ` [Intel-gfx] " Sean Paul
2019-12-13 19:07       ` Sean Paul
2019-12-12 19:02 ` [PATCH v2 03/12] drm/i915: WARN if HDCP signalling is enabled upon disable Sean Paul
2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
2019-12-13 10:37   ` Ramalingam C
2019-12-13 10:37     ` [Intel-gfx] " Ramalingam C
2019-12-12 19:02 ` [PATCH v2 04/12] drm/i915: Intercept Aksv writes in the aux hooks Sean Paul
2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
2019-12-13 10:52   ` Ramalingam C
2019-12-13 10:52     ` [Intel-gfx] " Ramalingam C
2019-12-12 19:02 ` [PATCH v2 05/12] drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling Sean Paul
2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
2019-12-13 10:43   ` Ramalingam C
2019-12-13 10:43     ` [Intel-gfx] " Ramalingam C
2019-12-12 19:02 ` [PATCH v2 06/12] drm/i915: Factor out hdcp->value assignments Sean Paul
2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
2019-12-13 11:11   ` Ramalingam C
2019-12-13 11:11     ` [Intel-gfx] " Ramalingam C
2019-12-12 19:02 ` [PATCH v2 07/12] drm/i915: Protect workers against disappearing connectors Sean Paul
2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
2019-12-13 11:10   ` Ramalingam C
2019-12-13 11:10     ` [Intel-gfx] " Ramalingam C
2019-12-13 19:04     ` Sean Paul
2019-12-13 19:04       ` [Intel-gfx] " Sean Paul
2019-12-12 19:02 ` [PATCH v2 08/12] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it Sean Paul
2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
2019-12-13 11:58   ` Ramalingam C
2019-12-13 11:58     ` [Intel-gfx] " Ramalingam C
2019-12-13 19:03     ` Sean Paul
2019-12-13 19:03       ` [Intel-gfx] " Sean Paul
2019-12-12 19:02 ` [PATCH v2 09/12] drm/i915: Support DP MST in enc_to_dig_port() function Sean Paul
2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
2019-12-12 19:02 ` [PATCH v2 10/12] drm/i915: Use ddi_update_pipe in intel_dp_mst Sean Paul
2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
2019-12-12 19:02 ` [PATCH v2 11/12] drm/i915: Expose HDCP shim functions from dp for use by dp_mst Sean Paul
2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
2019-12-13 11:25   ` Ville Syrjälä
2019-12-13 11:25     ` [Intel-gfx] " Ville Syrjälä
2019-12-13 11:59     ` Jani Nikula
2019-12-13 11:59       ` [Intel-gfx] " Jani Nikula
2019-12-12 19:02 ` [PATCH v2 12/12] drm/i915: Add HDCP 1.4 support for MST connectors Sean Paul
2019-12-12 19:02   ` [Intel-gfx] " Sean Paul
2019-12-12 21:12 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add support for HDCP 1.4 over MST connectors (rev2) Patchwork
2019-12-12 21:34 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2019-12-12 22:50   ` Sean Paul
2019-12-12 22:55     ` Chris Wilson

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.