All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows
@ 2018-07-31 23:45 Paulo Zanoni
  2018-08-01  0:21 ` ✓ Fi.CI.BAT: success for " Patchwork
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Paulo Zanoni @ 2018-07-31 23:45 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni, Rodrigo Vivi

Unlike the other ports, TC ports are not available to use as soon as
we get a hotplug. The TC PHYs can be shared between multiple
controllers: display, USB, etc. As a result, handshaking through FIA
is required around connect and disconnect to cleanly transfer
ownership with the controller and set the type-C power state.

This patch implements the flow sequences described by our
specification. We opt to grab ownership of the ports as soon as we get
the hotplugs in order to simplify the interactions and avoid surprises
in the user space side. We may consider changing this in the future,
once we improve our testing capabilities on this area.

v2:
 * This unifies the DP and HDMI patches so we can discuss everything
   at once so people looking at random single patches can actually
   understand the direction.
 * I found out the spec was updated a while ago. There's a small
   difference in the connect flow and the patch was updated for that.
 * Our spec also now gives a good explanation on what is really
   happening. As a result, comments were added.
 * Add some more comments as requested by Rodrigo (Rodrigo).

BSpec: 21750, 4250.
Cc: Animesh Manna <animesh.manna@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h   |   6 +++
 drivers/gpu/drm/i915/intel_dp.c   | 110 +++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_hdmi.c |  11 ++--
 3 files changed, 123 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 079c89da8831..bcf6ef75cffe 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -10753,4 +10753,10 @@ enum skl_power_gate {
 #define   DP_LANE_ASSIGNMENT_MASK(tc_port)	(0xf << ((tc_port) * 8))
 #define   DP_LANE_ASSIGNMENT(tc_port, x)	((x) << ((tc_port) * 8))
 
+#define PORT_TX_DFLEXDPPMS				_MMIO(0x163890)
+#define   DP_PHY_MODE_STATUS_COMPLETED(tc_port)		(1 << (tc_port))
+
+#define PORT_TX_DFLEXDPCSSS				_MMIO(0x163894)
+#define   DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)		(1 << (tc_port))
+
 #endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index fec21aa3db93..6a6ddc3a71e3 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4818,6 +4818,104 @@ static void icl_update_tc_port_type(struct drm_i915_private *dev_priv,
 			      type_str);
 }
 
+/*
+ * This function implements the first part of the Connect Flow described by our
+ * specification, Gen11 TypeC Programming chapter. The rest of the flow (reading
+ * lanes, EDID, etc) is done as needed in the typical places.
+ *
+ * Unlike the other ports, type-C ports are not available to use as soon as we
+ * get a hotplug. The type-C PHYs can be shared between multiple controllers:
+ * display, USB, etc. As a result, handshaking through FIA is required around
+ * connect and disconnect to cleanly transfer ownership with the controller and
+ * set the type-C power state.
+ *
+ * We could opt to only do the connect flow when we actually try to use the AUX
+ * channels or do a modeset, then immediately run the disconnect flow after
+ * usage, but there are some implications on this for a dynamic environment:
+ * things may go away or change behind our backs. So for now our driver is
+ * always trying to acquire ownership of the controller as soon as it gets an
+ * interrupt (or polls state and sees a port is connected) and only gives it
+ * back when it sees a disconnect. Implementation of a more fine-grained model
+ * will require a lot of coordination with user space and thorough testing for
+ * the extra possible cases.
+ */
+static bool icl_tc_phy_connect(struct drm_i915_private *dev_priv,
+			       struct intel_digital_port *dig_port)
+{
+	enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
+	u32 val;
+
+	if (dig_port->tc_type != TC_PORT_LEGACY &&
+	    dig_port->tc_type != TC_PORT_TYPEC)
+		return true;
+
+	val = I915_READ(PORT_TX_DFLEXDPPMS);
+	if (!(val & DP_PHY_MODE_STATUS_COMPLETED(tc_port))) {
+		DRM_ERROR("DP PHY for TC port %d not ready\n", tc_port);
+		return false;
+	}
+
+	/*
+	 * This function may be called many times in a row without an HPD event
+	 * in between, so try to avoid the write when we can.
+	 */
+	val = I915_READ(PORT_TX_DFLEXDPCSSS);
+	if (!(val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port))) {
+		val |= DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
+		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
+	}
+
+	/*
+	 * Now we have to re-check the live state, in case the port recently
+	 * became disconnected. Not necessary for legacy mode.
+	 */
+	if (dig_port->tc_type == TC_PORT_TYPEC &&
+	    !(I915_READ(PORT_TX_DFLEXDPSP) & TC_LIVE_STATE_TC(tc_port))) {
+		DRM_DEBUG_KMS("TC PHY %d sudden disconnect.\n", tc_port);
+		val = I915_READ(PORT_TX_DFLEXDPCSSS);
+		val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
+		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
+		return false;
+	}
+
+	return true;
+}
+
+/*
+ * See the comment at the connect function. This implements the Disconnect
+ * Flow.
+ */
+static void icl_tc_phy_disconnect(struct drm_i915_private *dev_priv,
+				  struct intel_digital_port *dig_port)
+{
+	enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
+	u32 val;
+
+	if (dig_port->tc_type != TC_PORT_LEGACY &&
+	    dig_port->tc_type != TC_PORT_TYPEC)
+		return;
+
+	/*
+	 * This function may be called many times in a row without an HPD event
+	 * in between, so try to avoid the write when we can.
+	 */
+	val = I915_READ(PORT_TX_DFLEXDPCSSS);
+	if (val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)) {
+		val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
+		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
+	}
+}
+
+/*
+ * The type-C ports are different because even when they are connected, they may
+ * not be available/usable by the graphics driver: see the comment on
+ * icl_tc_phy_connect(). So in our driver instead of adding the additional
+ * concept of "usable" and make everything check for "connected and usable" we
+ * define a port as "connected" when it is not only connected, but also when it
+ * is usable by the rest of the driver. That maintains the old assumption that
+ * connected ports are usable, and avoids exposing to the users objects they
+ * can't really use.
+ */
 static bool icl_tc_port_connected(struct drm_i915_private *dev_priv,
 				  struct intel_digital_port *intel_dig_port)
 {
@@ -4836,12 +4934,17 @@ static bool icl_tc_port_connected(struct drm_i915_private *dev_priv,
 	is_typec = dpsp & TC_LIVE_STATE_TC(tc_port);
 	is_tbt = dpsp & TC_LIVE_STATE_TBT(tc_port);
 
-	if (!is_legacy && !is_typec && !is_tbt)
+	if (!is_legacy && !is_typec && !is_tbt) {
+		icl_tc_phy_disconnect(dev_priv, intel_dig_port);
 		return false;
+	}
 
 	icl_update_tc_port_type(dev_priv, intel_dig_port, is_legacy, is_typec,
 				is_tbt);
 
+	if (!icl_tc_phy_connect(dev_priv, intel_dig_port))
+		return false;
+
 	return true;
 }
 
@@ -4869,6 +4972,11 @@ static bool icl_digital_port_connected(struct intel_encoder *encoder)
  * intel_digital_port_connected - is the specified port connected?
  * @encoder: intel_encoder
  *
+ * In cases where there's a connector physically connected but it can't be used
+ * by our hardware we also return false, since the rest of the driver should
+ * pretty much treat the port as disconnected. This is relevant for type-C
+ * (starting on ICL) where there's ownership involved.
+ *
  * Return %true if port is connected, %false otherwise.
  */
 bool intel_digital_port_connected(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 8363fbd18ee8..548199e59b6c 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1905,21 +1905,26 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector, bool force)
 {
-	enum drm_connector_status status;
+	enum drm_connector_status status = connector_status_disconnected;
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+	struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 		      connector->base.id, connector->name);
 
 	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
 
+	if (IS_ICELAKE(dev_priv) &&
+	    !intel_digital_port_connected(encoder))
+		goto out;
+
 	intel_hdmi_unset_edid(connector);
 
 	if (intel_hdmi_set_edid(connector))
 		status = connector_status_connected;
-	else
-		status = connector_status_disconnected;
 
+out:
 	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
 	return status;
-- 
2.14.4

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

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

* ✓ Fi.CI.BAT: success for drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows
  2018-07-31 23:45 [PATCH] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows Paulo Zanoni
@ 2018-08-01  0:21 ` Patchwork
  2018-08-01  1:15 ` ✓ Fi.CI.IGT: " Patchwork
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Patchwork @ 2018-08-01  0:21 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows
URL   : https://patchwork.freedesktop.org/series/47518/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_4600 -> Patchwork_9826 =

== Summary - SUCCESS ==

  No regressions found.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/47518/revisions/1/mbox/

== Known issues ==

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

  === IGT changes ===

    ==== Issues hit ====

    igt@drv_selftest@live_guc:
      fi-skl-guc:         NOTRUN -> DMESG-WARN (fdo#107175, fdo#107258)

    igt@drv_selftest@live_hangcheck:
      fi-skl-6600u:       PASS -> DMESG-FAIL (fdo#107174, fdo#106560)

    igt@drv_selftest@live_workarounds:
      fi-cnl-psr:         PASS -> DMESG-FAIL (fdo#107292)

    igt@gem_exec_suspend@basic-s3:
      fi-snb-2600:        PASS -> DMESG-WARN (fdo#102365)

    igt@gem_exec_suspend@basic-s4-devices:
      fi-kbl-7500u:       PASS -> DMESG-WARN (fdo#105128, fdo#107139)

    igt@kms_busy@basic-flip-b:
      fi-kbl-r:           PASS -> DMESG-WARN (fdo#105602)

    igt@prime_vgem@basic-fence-flip:
      fi-ilk-650:         PASS -> FAIL (fdo#104008)

    
    ==== Possible fixes ====

    igt@drv_selftest@live_hangcheck:
      fi-kbl-guc:         DMESG-FAIL (fdo#106947) -> PASS
      fi-skl-6260u:       DMESG-FAIL (fdo#107174, fdo#106560) -> PASS

    igt@drv_selftest@live_workarounds:
      {fi-cfl-8109u}:     DMESG-FAIL (fdo#107292) -> PASS

    igt@kms_frontbuffer_tracking@basic:
      fi-hsw-peppy:       DMESG-FAIL (fdo#106103, fdo#102614) -> PASS

    igt@kms_pipe_crc_basic@nonblocking-crc-pipe-a:
      fi-skl-6700k2:      FAIL (fdo#103191) -> PASS

    
    ==== Warnings ====

    {igt@kms_psr@primary_page_flip}:
      fi-cnl-psr:         DMESG-FAIL (fdo#107372) -> DMESG-WARN (fdo#107372)

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

  fdo#102365 https://bugs.freedesktop.org/show_bug.cgi?id=102365
  fdo#102614 https://bugs.freedesktop.org/show_bug.cgi?id=102614
  fdo#103191 https://bugs.freedesktop.org/show_bug.cgi?id=103191
  fdo#104008 https://bugs.freedesktop.org/show_bug.cgi?id=104008
  fdo#105128 https://bugs.freedesktop.org/show_bug.cgi?id=105128
  fdo#105602 https://bugs.freedesktop.org/show_bug.cgi?id=105602
  fdo#106103 https://bugs.freedesktop.org/show_bug.cgi?id=106103
  fdo#106560 https://bugs.freedesktop.org/show_bug.cgi?id=106560
  fdo#106947 https://bugs.freedesktop.org/show_bug.cgi?id=106947
  fdo#107139 https://bugs.freedesktop.org/show_bug.cgi?id=107139
  fdo#107174 https://bugs.freedesktop.org/show_bug.cgi?id=107174
  fdo#107175 https://bugs.freedesktop.org/show_bug.cgi?id=107175
  fdo#107258 https://bugs.freedesktop.org/show_bug.cgi?id=107258
  fdo#107292 https://bugs.freedesktop.org/show_bug.cgi?id=107292
  fdo#107372 https://bugs.freedesktop.org/show_bug.cgi?id=107372


== Participating hosts (48 -> 45) ==

  Additional (2): fi-skl-guc fi-glk-j4005 
  Missing    (5): fi-ctg-p8600 fi-ilk-m540 fi-byt-squawks fi-byt-clapper fi-hsw-4200u 


== Build changes ==

    * Linux: CI_DRM_4600 -> Patchwork_9826

  CI_DRM_4600: 308427119c70d0aaa90433b05969a0317165b122 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4581: f1c868dae24056ebc27e4f3c197724ce9b956a8a @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_9826: b12d368538105a81cc71815aeff6197064ae8a9c @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

b12d36853810 drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows

== Logs ==

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

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

* ✓ Fi.CI.IGT: success for drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows
  2018-07-31 23:45 [PATCH] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows Paulo Zanoni
  2018-08-01  0:21 ` ✓ Fi.CI.BAT: success for " Patchwork
@ 2018-08-01  1:15 ` Patchwork
  2018-08-01  8:22 ` [PATCH] " Chris Wilson
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Patchwork @ 2018-08-01  1:15 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows
URL   : https://patchwork.freedesktop.org/series/47518/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_4600_full -> Patchwork_9826_full =

== Summary - WARNING ==

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

  

== Possible new issues ==

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

  === IGT changes ===

    ==== Warnings ====

    igt@kms_atomic_transition@plane-all-transition-nonblocking:
      shard-snb:          PASS -> SKIP +2

    
== Known issues ==

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

  === IGT changes ===

    ==== Issues hit ====

    igt@gem_ctx_isolation@vcs0-s3:
      shard-kbl:          PASS -> INCOMPLETE (fdo#103665)

    igt@kms_rotation_crc@sprite-rotation-90-pos-100-0:
      shard-kbl:          PASS -> FAIL (fdo#103925)

    igt@perf@polling:
      shard-hsw:          PASS -> FAIL (fdo#102252)

    
    ==== Possible fixes ====

    igt@gem_ppgtt@blt-vs-render-ctxn:
      shard-kbl:          INCOMPLETE (fdo#106023, fdo#103665) -> PASS

    igt@kms_flip@basic-flip-vs-wf_vblank:
      shard-glk:          FAIL (fdo#105312) -> PASS

    igt@kms_flip@dpms-vs-vblank-race:
      shard-glk:          FAIL (fdo#103060) -> PASS

    igt@kms_flip@wf_vblank-ts-check-interruptible:
      shard-glk:          FAIL (fdo#100368) -> PASS

    igt@kms_setmode@basic:
      shard-apl:          FAIL (fdo#99912) -> PASS
      shard-kbl:          FAIL (fdo#99912) -> PASS

    
    ==== Warnings ====

    igt@drv_suspend@shrink:
      shard-glk:          FAIL (fdo#106886) -> INCOMPLETE (fdo#103359, fdo#106886, k.org#198133)

    
  fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368
  fdo#102252 https://bugs.freedesktop.org/show_bug.cgi?id=102252
  fdo#103060 https://bugs.freedesktop.org/show_bug.cgi?id=103060
  fdo#103359 https://bugs.freedesktop.org/show_bug.cgi?id=103359
  fdo#103665 https://bugs.freedesktop.org/show_bug.cgi?id=103665
  fdo#103925 https://bugs.freedesktop.org/show_bug.cgi?id=103925
  fdo#105312 https://bugs.freedesktop.org/show_bug.cgi?id=105312
  fdo#106023 https://bugs.freedesktop.org/show_bug.cgi?id=106023
  fdo#106886 https://bugs.freedesktop.org/show_bug.cgi?id=106886
  fdo#99912 https://bugs.freedesktop.org/show_bug.cgi?id=99912
  k.org#198133 https://bugzilla.kernel.org/show_bug.cgi?id=198133


== Participating hosts (5 -> 5) ==

  No changes in participating hosts


== Build changes ==

    * Linux: CI_DRM_4600 -> Patchwork_9826

  CI_DRM_4600: 308427119c70d0aaa90433b05969a0317165b122 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4581: f1c868dae24056ebc27e4f3c197724ce9b956a8a @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_9826: b12d368538105a81cc71815aeff6197064ae8a9c @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

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

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

* Re: [PATCH] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows
  2018-07-31 23:45 [PATCH] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows Paulo Zanoni
  2018-08-01  0:21 ` ✓ Fi.CI.BAT: success for " Patchwork
  2018-08-01  1:15 ` ✓ Fi.CI.IGT: " Patchwork
@ 2018-08-01  8:22 ` Chris Wilson
  2018-08-01 17:05   ` Paulo Zanoni
  2018-08-01 17:34 ` [PATCH v3] " Paulo Zanoni
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Chris Wilson @ 2018-08-01  8:22 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni, Rodrigo Vivi

Quoting Paulo Zanoni (2018-08-01 00:45:04)
> +static bool icl_tc_phy_connect(struct drm_i915_private *dev_priv,
> +                              struct intel_digital_port *dig_port)
> +{
> +       enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
> +       u32 val;
> +
> +       if (dig_port->tc_type != TC_PORT_LEGACY &&
> +           dig_port->tc_type != TC_PORT_TYPEC)
> +               return true;
> +
> +       val = I915_READ(PORT_TX_DFLEXDPPMS);
> +       if (!(val & DP_PHY_MODE_STATUS_COMPLETED(tc_port))) {
> +               DRM_ERROR("DP PHY for TC port %d not ready\n", tc_port);
> +               return false;

This is going to be hit as soon as someone manages to plug&unplug the
cable rapidly enough, The callers all handle the bool return so why
proclaim error on their behalf?
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows
  2018-08-01  8:22 ` [PATCH] " Chris Wilson
@ 2018-08-01 17:05   ` Paulo Zanoni
  0 siblings, 0 replies; 12+ messages in thread
From: Paulo Zanoni @ 2018-08-01 17:05 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx; +Cc: Rodrigo Vivi

Em Qua, 2018-08-01 às 09:22 +0100, Chris Wilson escreveu:
> Quoting Paulo Zanoni (2018-08-01 00:45:04)
> > +static bool icl_tc_phy_connect(struct drm_i915_private *dev_priv,
> > +                              struct intel_digital_port *dig_port)
> > +{
> > +       enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port-
> > >base.port);
> > +       u32 val;
> > +
> > +       if (dig_port->tc_type != TC_PORT_LEGACY &&
> > +           dig_port->tc_type != TC_PORT_TYPEC)
> > +               return true;
> > +
> > +       val = I915_READ(PORT_TX_DFLEXDPPMS);
> > +       if (!(val & DP_PHY_MODE_STATUS_COMPLETED(tc_port))) {
> > +               DRM_ERROR("DP PHY for TC port %d not ready\n",
> > tc_port);
> > +               return false;
> 
> This is going to be hit as soon as someone manages to plug&unplug the
> cable rapidly enough, The callers all handle the bool return so why
> proclaim error on their behalf?

This error message is not supposed to happen since the spec says we
only get the interrupt after the PHY is actually ready. So my plan was
to have a way to find out in case the spec is wrong, which sometimes
happen.

OTOH there's actually nothing we can do here, and the callers will
indeed handle the return. I'll change it to DRM_DEBUG_KMS.

Thanks,
Paulo

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

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

* [PATCH v3] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows
  2018-07-31 23:45 [PATCH] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows Paulo Zanoni
                   ` (2 preceding siblings ...)
  2018-08-01  8:22 ` [PATCH] " Chris Wilson
@ 2018-08-01 17:34 ` Paulo Zanoni
  2018-08-17 16:25   ` Srivatsa, Anusha
  2018-08-23  1:07   ` Rodrigo Vivi
  2018-08-01 18:34 ` ✗ Fi.CI.BAT: failure for drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows (rev2) Patchwork
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 12+ messages in thread
From: Paulo Zanoni @ 2018-08-01 17:34 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni, Rodrigo Vivi

Unlike the other ports, TC ports are not available to use as soon as
we get a hotplug. The TC PHYs can be shared between multiple
controllers: display, USB, etc. As a result, handshaking through FIA
is required around connect and disconnect to cleanly transfer
ownership with the controller and set the type-C power state.

This patch implements the flow sequences described by our
specification. We opt to grab ownership of the ports as soon as we get
the hotplugs in order to simplify the interactions and avoid surprises
in the user space side. We may consider changing this in the future,
once we improve our testing capabilities on this area.

v2:
 * This unifies the DP and HDMI patches so we can discuss everything
   at once so people looking at random single patches can actually
   understand the direction.
 * I found out the spec was updated a while ago. There's a small
   difference in the connect flow and the patch was updated for that.
 * Our spec also now gives a good explanation on what is really
   happening. As a result, comments were added.
 * Add some more comments as requested by Rodrigo (Rodrigo).
v3:
 * Downgrade a DRM_ERROR that shouldn't ever happen but we can't act
   on in case it does (Chris).

BSpec: 21750, 4250.
Cc: Animesh Manna <animesh.manna@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h   |   6 +++
 drivers/gpu/drm/i915/intel_dp.c   | 110 +++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_hdmi.c |  11 ++--
 3 files changed, 123 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 1da1c7743785..a5f4dfe9ebdf 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -10750,4 +10750,10 @@ enum skl_power_gate {
 #define   DP_LANE_ASSIGNMENT_MASK(tc_port)	(0xf << ((tc_port) * 8))
 #define   DP_LANE_ASSIGNMENT(tc_port, x)	((x) << ((tc_port) * 8))
 
+#define PORT_TX_DFLEXDPPMS				_MMIO(0x163890)
+#define   DP_PHY_MODE_STATUS_COMPLETED(tc_port)		(1 << (tc_port))
+
+#define PORT_TX_DFLEXDPCSSS				_MMIO(0x163894)
+#define   DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)		(1 << (tc_port))
+
 #endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index fec21aa3db93..86eded613456 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4818,6 +4818,104 @@ static void icl_update_tc_port_type(struct drm_i915_private *dev_priv,
 			      type_str);
 }
 
+/*
+ * This function implements the first part of the Connect Flow described by our
+ * specification, Gen11 TypeC Programming chapter. The rest of the flow (reading
+ * lanes, EDID, etc) is done as needed in the typical places.
+ *
+ * Unlike the other ports, type-C ports are not available to use as soon as we
+ * get a hotplug. The type-C PHYs can be shared between multiple controllers:
+ * display, USB, etc. As a result, handshaking through FIA is required around
+ * connect and disconnect to cleanly transfer ownership with the controller and
+ * set the type-C power state.
+ *
+ * We could opt to only do the connect flow when we actually try to use the AUX
+ * channels or do a modeset, then immediately run the disconnect flow after
+ * usage, but there are some implications on this for a dynamic environment:
+ * things may go away or change behind our backs. So for now our driver is
+ * always trying to acquire ownership of the controller as soon as it gets an
+ * interrupt (or polls state and sees a port is connected) and only gives it
+ * back when it sees a disconnect. Implementation of a more fine-grained model
+ * will require a lot of coordination with user space and thorough testing for
+ * the extra possible cases.
+ */
+static bool icl_tc_phy_connect(struct drm_i915_private *dev_priv,
+			       struct intel_digital_port *dig_port)
+{
+	enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
+	u32 val;
+
+	if (dig_port->tc_type != TC_PORT_LEGACY &&
+	    dig_port->tc_type != TC_PORT_TYPEC)
+		return true;
+
+	val = I915_READ(PORT_TX_DFLEXDPPMS);
+	if (!(val & DP_PHY_MODE_STATUS_COMPLETED(tc_port))) {
+		DRM_DEBUG_KMS("DP PHY for TC port %d not ready\n", tc_port);
+		return false;
+	}
+
+	/*
+	 * This function may be called many times in a row without an HPD event
+	 * in between, so try to avoid the write when we can.
+	 */
+	val = I915_READ(PORT_TX_DFLEXDPCSSS);
+	if (!(val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port))) {
+		val |= DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
+		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
+	}
+
+	/*
+	 * Now we have to re-check the live state, in case the port recently
+	 * became disconnected. Not necessary for legacy mode.
+	 */
+	if (dig_port->tc_type == TC_PORT_TYPEC &&
+	    !(I915_READ(PORT_TX_DFLEXDPSP) & TC_LIVE_STATE_TC(tc_port))) {
+		DRM_DEBUG_KMS("TC PHY %d sudden disconnect.\n", tc_port);
+		val = I915_READ(PORT_TX_DFLEXDPCSSS);
+		val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
+		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
+		return false;
+	}
+
+	return true;
+}
+
+/*
+ * See the comment at the connect function. This implements the Disconnect
+ * Flow.
+ */
+static void icl_tc_phy_disconnect(struct drm_i915_private *dev_priv,
+				  struct intel_digital_port *dig_port)
+{
+	enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
+	u32 val;
+
+	if (dig_port->tc_type != TC_PORT_LEGACY &&
+	    dig_port->tc_type != TC_PORT_TYPEC)
+		return;
+
+	/*
+	 * This function may be called many times in a row without an HPD event
+	 * in between, so try to avoid the write when we can.
+	 */
+	val = I915_READ(PORT_TX_DFLEXDPCSSS);
+	if (val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)) {
+		val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
+		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
+	}
+}
+
+/*
+ * The type-C ports are different because even when they are connected, they may
+ * not be available/usable by the graphics driver: see the comment on
+ * icl_tc_phy_connect(). So in our driver instead of adding the additional
+ * concept of "usable" and make everything check for "connected and usable" we
+ * define a port as "connected" when it is not only connected, but also when it
+ * is usable by the rest of the driver. That maintains the old assumption that
+ * connected ports are usable, and avoids exposing to the users objects they
+ * can't really use.
+ */
 static bool icl_tc_port_connected(struct drm_i915_private *dev_priv,
 				  struct intel_digital_port *intel_dig_port)
 {
@@ -4836,12 +4934,17 @@ static bool icl_tc_port_connected(struct drm_i915_private *dev_priv,
 	is_typec = dpsp & TC_LIVE_STATE_TC(tc_port);
 	is_tbt = dpsp & TC_LIVE_STATE_TBT(tc_port);
 
-	if (!is_legacy && !is_typec && !is_tbt)
+	if (!is_legacy && !is_typec && !is_tbt) {
+		icl_tc_phy_disconnect(dev_priv, intel_dig_port);
 		return false;
+	}
 
 	icl_update_tc_port_type(dev_priv, intel_dig_port, is_legacy, is_typec,
 				is_tbt);
 
+	if (!icl_tc_phy_connect(dev_priv, intel_dig_port))
+		return false;
+
 	return true;
 }
 
@@ -4869,6 +4972,11 @@ static bool icl_digital_port_connected(struct intel_encoder *encoder)
  * intel_digital_port_connected - is the specified port connected?
  * @encoder: intel_encoder
  *
+ * In cases where there's a connector physically connected but it can't be used
+ * by our hardware we also return false, since the rest of the driver should
+ * pretty much treat the port as disconnected. This is relevant for type-C
+ * (starting on ICL) where there's ownership involved.
+ *
  * Return %true if port is connected, %false otherwise.
  */
 bool intel_digital_port_connected(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 8363fbd18ee8..548199e59b6c 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1905,21 +1905,26 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector, bool force)
 {
-	enum drm_connector_status status;
+	enum drm_connector_status status = connector_status_disconnected;
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+	struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 		      connector->base.id, connector->name);
 
 	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
 
+	if (IS_ICELAKE(dev_priv) &&
+	    !intel_digital_port_connected(encoder))
+		goto out;
+
 	intel_hdmi_unset_edid(connector);
 
 	if (intel_hdmi_set_edid(connector))
 		status = connector_status_connected;
-	else
-		status = connector_status_disconnected;
 
+out:
 	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
 	return status;
-- 
2.14.4

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

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

* ✗ Fi.CI.BAT: failure for drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows (rev2)
  2018-07-31 23:45 [PATCH] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows Paulo Zanoni
                   ` (3 preceding siblings ...)
  2018-08-01 17:34 ` [PATCH v3] " Paulo Zanoni
@ 2018-08-01 18:34 ` Patchwork
  2018-08-23 22:17 ` ✓ Fi.CI.BAT: success " Patchwork
  2018-08-23 23:30 ` ✗ Fi.CI.IGT: failure " Patchwork
  6 siblings, 0 replies; 12+ messages in thread
From: Patchwork @ 2018-08-01 18:34 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows (rev2)
URL   : https://patchwork.freedesktop.org/series/47518/
State : failure

== Summary ==

= CI Bug Log - changes from CI_DRM_4605 -> Patchwork_9836 =

== Summary - FAILURE ==

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

  External URL: https://patchwork.freedesktop.org/api/1.0/series/47518/revisions/2/mbox/

== Possible new issues ==

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

  === IGT changes ===

    ==== Possible regressions ====

    igt@drv_selftest@live_sanitycheck:
      fi-bxt-j4205:       PASS -> DMESG-FAIL

    
    ==== Warnings ====

    igt@drv_selftest@live_requests:
      fi-bxt-j4205:       PASS -> SKIP +12

    
== Known issues ==

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

  === IGT changes ===

    ==== Issues hit ====

    igt@drv_selftest@live_guc:
      fi-skl-guc:         NOTRUN -> DMESG-WARN (fdo#107258, fdo#107175)

    igt@drv_selftest@live_workarounds:
      fi-cnl-psr:         PASS -> DMESG-FAIL (fdo#107292)

    
    ==== Possible fixes ====

    igt@drv_selftest@live_workarounds:
      {fi-bdw-samus}:     DMESG-FAIL (fdo#107292) -> PASS

    igt@prime_vgem@basic-fence-flip:
      fi-ilk-650:         FAIL (fdo#104008) -> PASS

    
    ==== Warnings ====

    {igt@kms_psr@primary_page_flip}:
      fi-cnl-psr:         DMESG-FAIL (fdo#107372) -> DMESG-WARN (fdo#107372)

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

  fdo#104008 https://bugs.freedesktop.org/show_bug.cgi?id=104008
  fdo#107175 https://bugs.freedesktop.org/show_bug.cgi?id=107175
  fdo#107258 https://bugs.freedesktop.org/show_bug.cgi?id=107258
  fdo#107292 https://bugs.freedesktop.org/show_bug.cgi?id=107292
  fdo#107372 https://bugs.freedesktop.org/show_bug.cgi?id=107372


== Participating hosts (50 -> 44) ==

  Additional (1): fi-skl-guc 
  Missing    (7): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-glk-j4005 fi-byt-clapper 


== Build changes ==

    * Linux: CI_DRM_4605 -> Patchwork_9836

  CI_DRM_4605: 50098198da758bdd54245d511f4f97236c296c72 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4582: 263ca16e4d8909f475d32a28fc0e5972bac214fb @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_9836: 9fd77e93cebead1193a70e604e406a6ef1ea4fbc @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

9fd77e93cebe drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows

== Logs ==

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

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

* Re: [PATCH v3] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows
  2018-08-01 17:34 ` [PATCH v3] " Paulo Zanoni
@ 2018-08-17 16:25   ` Srivatsa, Anusha
  2018-08-17 23:27     ` Paulo Zanoni
  2018-08-23  1:07   ` Rodrigo Vivi
  1 sibling, 1 reply; 12+ messages in thread
From: Srivatsa, Anusha @ 2018-08-17 16:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Zanoni, Paulo R, Vivi, Rodrigo



>-----Original Message-----
>From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of
>Paulo Zanoni
>Sent: Wednesday, August 1, 2018 10:35 AM
>To: intel-gfx@lists.freedesktop.org
>Cc: Zanoni, Paulo R <paulo.r.zanoni@intel.com>; Vivi, Rodrigo
><rodrigo.vivi@intel.com>
>Subject: [Intel-gfx] [PATCH v3] drm/i915/icl: implement the tc/legacy HPD {dis,
>}connect flows
>
>Unlike the other ports, TC ports are not available to use as soon as we get a
>hotplug. The TC PHYs can be shared between multiple
>controllers: display, USB, etc. As a result, handshaking through FIA is required
>around connect and disconnect to cleanly transfer ownership with the controller
>and set the type-C power state.
>
>This patch implements the flow sequences described by our specification. We opt
>to grab ownership of the ports as soon as we get the hotplugs in order to simplify
>the interactions and avoid surprises in the user space side. We may consider
>changing this in the future, once we improve our testing capabilities on this area.
>
>v2:
> * This unifies the DP and HDMI patches so we can discuss everything
>   at once so people looking at random single patches can actually
>   understand the direction.
> * I found out the spec was updated a while ago. There's a small
>   difference in the connect flow and the patch was updated for that.
> * Our spec also now gives a good explanation on what is really
>   happening. As a result, comments were added.
> * Add some more comments as requested by Rodrigo (Rodrigo).
>v3:
> * Downgrade a DRM_ERROR that shouldn't ever happen but we can't act
>   on in case it does (Chris).
>
>BSpec: 21750, 4250.
>Cc: Animesh Manna <animesh.manna@intel.com>
>Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
>Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
>---
> drivers/gpu/drm/i915/i915_reg.h   |   6 +++
> drivers/gpu/drm/i915/intel_dp.c   | 110
>+++++++++++++++++++++++++++++++++++++-
> drivers/gpu/drm/i915/intel_hdmi.c |  11 ++--
> 3 files changed, 123 insertions(+), 4 deletions(-)
>
>diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>index 1da1c7743785..a5f4dfe9ebdf 100644
>--- a/drivers/gpu/drm/i915/i915_reg.h
>+++ b/drivers/gpu/drm/i915/i915_reg.h
>@@ -10750,4 +10750,10 @@ enum skl_power_gate {
> #define   DP_LANE_ASSIGNMENT_MASK(tc_port)	(0xf << ((tc_port) * 8))
> #define   DP_LANE_ASSIGNMENT(tc_port, x)	((x) << ((tc_port) * 8))
>
>+#define PORT_TX_DFLEXDPPMS
>	_MMIO(0x163890)
>+#define   DP_PHY_MODE_STATUS_COMPLETED(tc_port)		(1 <<
>(tc_port))
>+
>+#define PORT_TX_DFLEXDPCSSS
>	_MMIO(0x163894)
>+#define   DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)		(1 << (tc_port))
>+
> #endif /* _I915_REG_H_ */
>diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
>index fec21aa3db93..86eded613456 100644
>--- a/drivers/gpu/drm/i915/intel_dp.c
>+++ b/drivers/gpu/drm/i915/intel_dp.c
>@@ -4818,6 +4818,104 @@ static void icl_update_tc_port_type(struct
>drm_i915_private *dev_priv,
> 			      type_str);
> }
>
>+/*
>+ * This function implements the first part of the Connect Flow
>+described by our
>+ * specification, Gen11 TypeC Programming chapter. The rest of the flow
>+(reading
>+ * lanes, EDID, etc) is done as needed in the typical places.
>+ *
>+ * Unlike the other ports, type-C ports are not available to use as
>+soon as we
>+ * get a hotplug. The type-C PHYs can be shared between multiple controllers:
>+ * display, USB, etc. As a result, handshaking through FIA is required
>+around
>+ * connect and disconnect to cleanly transfer ownership with the
>+controller and
>+ * set the type-C power state.
>+ *
>+ * We could opt to only do the connect flow when we actually try to use
>+the AUX
>+ * channels or do a modeset, then immediately run the disconnect flow
>+after
>+ * usage, but there are some implications on this for a dynamic environment:
>+ * things may go away or change behind our backs. So for now our driver
>+is
>+ * always trying to acquire ownership of the controller as soon as it
>+gets an
>+ * interrupt (or polls state and sees a port is connected) and only
>+gives it
>+ * back when it sees a disconnect. Implementation of a more
>+fine-grained model
>+ * will require a lot of coordination with user space and thorough
>+testing for
>+ * the extra possible cases.
>+ */
>+static bool icl_tc_phy_connect(struct drm_i915_private *dev_priv,
>+			       struct intel_digital_port *dig_port) {
>+	enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
>+	u32 val;
>+
>+	if (dig_port->tc_type != TC_PORT_LEGACY &&
>+	    dig_port->tc_type != TC_PORT_TYPEC)
>+		return true;
>+
>+	val = I915_READ(PORT_TX_DFLEXDPPMS);
>+	if (!(val & DP_PHY_MODE_STATUS_COMPLETED(tc_port))) {
>+		DRM_DEBUG_KMS("DP PHY for TC port %d not ready\n",
>tc_port);
>+		return false;
>+	}
>+
>+	/*
>+	 * This function may be called many times in a row without an HPD event
>+	 * in between, so try to avoid the write when we can.
>+	 */
>+	val = I915_READ(PORT_TX_DFLEXDPCSSS);
>+	if (!(val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port))) {
>+		val |= DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
>+		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
>+	}
>+
>+	/*
>+	 * Now we have to re-check the live state, in case the port recently
>+	 * became disconnected. Not necessary for legacy mode.
>+	 */
>+	if (dig_port->tc_type == TC_PORT_TYPEC &&
>+	    !(I915_READ(PORT_TX_DFLEXDPSP) & TC_LIVE_STATE_TC(tc_port))) {
>+		DRM_DEBUG_KMS("TC PHY %d sudden disconnect.\n", tc_port);
>+		val = I915_READ(PORT_TX_DFLEXDPCSSS);
>+		val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
>+		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
>+		return false;
>+	}
>+
>+	return true;
>+}
>+
>+/*
>+ * See the comment at the connect function. This implements the
>+Disconnect
>+ * Flow.
>+ */
>+static void icl_tc_phy_disconnect(struct drm_i915_private *dev_priv,
>+				  struct intel_digital_port *dig_port) {
>+	enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
>+	u32 val;
>+
>+	if (dig_port->tc_type != TC_PORT_LEGACY &&
>+	    dig_port->tc_type != TC_PORT_TYPEC)

	Don’t we also need to check for dig_port->tc_type != TC_PORT_TBT?
>+		return;
>+
>+	/*
>+	 * This function may be called many times in a row without an HPD event
>+	 * in between, so try to avoid the write when we can.
>+	 */
>+	val = I915_READ(PORT_TX_DFLEXDPCSSS);
>+	if (val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)) {
>+		val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
>+		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
>+	}
>+}
>+
>+/*
>+ * The type-C ports are different because even when they are connected,
>+they may
>+ * not be available/usable by the graphics driver: see the comment on
>+ * icl_tc_phy_connect(). So in our driver instead of adding the
>+additional
>+ * concept of "usable" and make everything check for "connected and
>+usable" we
>+ * define a port as "connected" when it is not only connected, but also
>+when it
>+ * is usable by the rest of the driver. That maintains the old
>+assumption that
>+ * connected ports are usable, and avoids exposing to the users objects
>+they
>+ * can't really use.
>+ */
> static bool icl_tc_port_connected(struct drm_i915_private *dev_priv,
> 				  struct intel_digital_port *intel_dig_port)  { @@
>-4836,12 +4934,17 @@ static bool icl_tc_port_connected(struct
>drm_i915_private *dev_priv,
> 	is_typec = dpsp & TC_LIVE_STATE_TC(tc_port);
> 	is_tbt = dpsp & TC_LIVE_STATE_TBT(tc_port);
>
>-	if (!is_legacy && !is_typec && !is_tbt)
>+	if (!is_legacy && !is_typec && !is_tbt) {

If it is none of the above, then why not just return false?
	
Anusha 
>+		icl_tc_phy_disconnect(dev_priv, intel_dig_port);
> 		return false;
>+	}
>
> 	icl_update_tc_port_type(dev_priv, intel_dig_port, is_legacy, is_typec,
> 				is_tbt);
>
>+	if (!icl_tc_phy_connect(dev_priv, intel_dig_port))
>+		return false;
>+
> 	return true;
> }
>
>@@ -4869,6 +4972,11 @@ static bool icl_digital_port_connected(struct
>intel_encoder *encoder)
>  * intel_digital_port_connected - is the specified port connected?
>  * @encoder: intel_encoder
>  *
>+ * In cases where there's a connector physically connected but it can't
>+ be used
>+ * by our hardware we also return false, since the rest of the driver
>+ should
>+ * pretty much treat the port as disconnected. This is relevant for
>+ type-C
>+ * (starting on ICL) where there's ownership involved.
>+ *
>  * Return %true if port is connected, %false otherwise.
>  */
> bool intel_digital_port_connected(struct intel_encoder *encoder) diff --git
>a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
>index 8363fbd18ee8..548199e59b6c 100644
>--- a/drivers/gpu/drm/i915/intel_hdmi.c
>+++ b/drivers/gpu/drm/i915/intel_hdmi.c
>@@ -1905,21 +1905,26 @@ intel_hdmi_set_edid(struct drm_connector
>*connector)  static enum drm_connector_status  intel_hdmi_detect(struct
>drm_connector *connector, bool force)  {
>-	enum drm_connector_status status;
>+	enum drm_connector_status status = connector_status_disconnected;
> 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
>+	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>+	struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base;
>
> 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> 		      connector->base.id, connector->name);
>
> 	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
>
>+	if (IS_ICELAKE(dev_priv) &&
>+	    !intel_digital_port_connected(encoder))
>+		goto out;
>+
> 	intel_hdmi_unset_edid(connector);
>
> 	if (intel_hdmi_set_edid(connector))
> 		status = connector_status_connected;
>-	else
>-		status = connector_status_disconnected;
>
>+out:
> 	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
>
> 	return status;
>--
>2.14.4
>
>_______________________________________________
>Intel-gfx mailing list
>Intel-gfx@lists.freedesktop.org
>https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows
  2018-08-17 16:25   ` Srivatsa, Anusha
@ 2018-08-17 23:27     ` Paulo Zanoni
  0 siblings, 0 replies; 12+ messages in thread
From: Paulo Zanoni @ 2018-08-17 23:27 UTC (permalink / raw)
  To: Srivatsa, Anusha, intel-gfx; +Cc: Vivi, Rodrigo

Em Sex, 2018-08-17 às 09:25 -0700, Srivatsa, Anusha escreveu:
> > -----Original Message-----
> > From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On
> > Behalf Of
> > Paulo Zanoni
> > Sent: Wednesday, August 1, 2018 10:35 AM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: Zanoni, Paulo R <paulo.r.zanoni@intel.com>; Vivi, Rodrigo
> > <rodrigo.vivi@intel.com>
> > Subject: [Intel-gfx] [PATCH v3] drm/i915/icl: implement the
> > tc/legacy HPD {dis,
> > }connect flows
> > 
> > Unlike the other ports, TC ports are not available to use as soon
> > as we get a
> > hotplug. The TC PHYs can be shared between multiple
> > controllers: display, USB, etc. As a result, handshaking through
> > FIA is required
> > around connect and disconnect to cleanly transfer ownership with
> > the controller
> > and set the type-C power state.
> > 
> > This patch implements the flow sequences described by our
> > specification. We opt
> > to grab ownership of the ports as soon as we get the hotplugs in
> > order to simplify
> > the interactions and avoid surprises in the user space side. We may
> > consider
> > changing this in the future, once we improve our testing
> > capabilities on this area.
> > 
> > v2:
> > * This unifies the DP and HDMI patches so we can discuss everything
> >   at once so people looking at random single patches can actually
> >   understand the direction.
> > * I found out the spec was updated a while ago. There's a small
> >   difference in the connect flow and the patch was updated for
> > that.
> > * Our spec also now gives a good explanation on what is really
> >   happening. As a result, comments were added.
> > * Add some more comments as requested by Rodrigo (Rodrigo).
> > v3:
> > * Downgrade a DRM_ERROR that shouldn't ever happen but we can't act
> >   on in case it does (Chris).
> > 
> > BSpec: 21750, 4250.
> > Cc: Animesh Manna <animesh.manna@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > ---
> > drivers/gpu/drm/i915/i915_reg.h   |   6 +++
> > drivers/gpu/drm/i915/intel_dp.c   | 110
> > +++++++++++++++++++++++++++++++++++++-
> > drivers/gpu/drm/i915/intel_hdmi.c |  11 ++--
> > 3 files changed, 123 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> > b/drivers/gpu/drm/i915/i915_reg.h
> > index 1da1c7743785..a5f4dfe9ebdf 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -10750,4 +10750,10 @@ enum skl_power_gate {
> > #define   DP_LANE_ASSIGNMENT_MASK(tc_port)	(0xf <<
> > ((tc_port) * 8))
> > #define   DP_LANE_ASSIGNMENT(tc_port, x)	((x) << ((tc_port)
> > * 8))
> > 
> > +#define PORT_TX_DFLEXDPPMS
> > 	_MMIO(0x163890)
> > +#define   DP_PHY_MODE_STATUS_COMPLETED(tc_port)		(1
> > <<
> > (tc_port))
> > +
> > +#define PORT_TX_DFLEXDPCSSS
> > 	_MMIO(0x163894)
> > +#define   DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)		(1
> > << (tc_port))
> > +
> > #endif /* _I915_REG_H_ */
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c
> > b/drivers/gpu/drm/i915/intel_dp.c
> > index fec21aa3db93..86eded613456 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -4818,6 +4818,104 @@ static void icl_update_tc_port_type(struct
> > drm_i915_private *dev_priv,
> > 			      type_str);
> > }
> > 
> > +/*
> > + * This function implements the first part of the Connect Flow
> > +described by our
> > + * specification, Gen11 TypeC Programming chapter. The rest of the
> > flow
> > +(reading
> > + * lanes, EDID, etc) is done as needed in the typical places.
> > + *
> > + * Unlike the other ports, type-C ports are not available to use
> > as
> > +soon as we
> > + * get a hotplug. The type-C PHYs can be shared between multiple
> > controllers:
> > + * display, USB, etc. As a result, handshaking through FIA is
> > required
> > +around
> > + * connect and disconnect to cleanly transfer ownership with the
> > +controller and
> > + * set the type-C power state.
> > + *
> > + * We could opt to only do the connect flow when we actually try
> > to use
> > +the AUX
> > + * channels or do a modeset, then immediately run the disconnect
> > flow
> > +after
> > + * usage, but there are some implications on this for a dynamic
> > environment:
> > + * things may go away or change behind our backs. So for now our
> > driver
> > +is
> > + * always trying to acquire ownership of the controller as soon as
> > it
> > +gets an
> > + * interrupt (or polls state and sees a port is connected) and
> > only
> > +gives it
> > + * back when it sees a disconnect. Implementation of a more
> > +fine-grained model
> > + * will require a lot of coordination with user space and thorough
> > +testing for
> > + * the extra possible cases.
> > + */
> > +static bool icl_tc_phy_connect(struct drm_i915_private *dev_priv,
> > +			       struct intel_digital_port
> > *dig_port) {
> > +	enum tc_port tc_port = intel_port_to_tc(dev_priv,
> > dig_port->base.port);
> > +	u32 val;
> > +
> > +	if (dig_port->tc_type != TC_PORT_LEGACY &&
> > +	    dig_port->tc_type != TC_PORT_TYPEC)
> > +		return true;
> > +
> > +	val = I915_READ(PORT_TX_DFLEXDPPMS);
> > +	if (!(val & DP_PHY_MODE_STATUS_COMPLETED(tc_port))) {
> > +		DRM_DEBUG_KMS("DP PHY for TC port %d not ready\n",
> > tc_port);
> > +		return false;
> > +	}
> > +
> > +	/*
> > +	 * This function may be called many times in a row without
> > an HPD event
> > +	 * in between, so try to avoid the write when we can.
> > +	 */
> > +	val = I915_READ(PORT_TX_DFLEXDPCSSS);
> > +	if (!(val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port))) {
> > +		val |= DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
> > +		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
> > +	}
> > +
> > +	/*
> > +	 * Now we have to re-check the live state, in case the
> > port recently
> > +	 * became disconnected. Not necessary for legacy mode.
> > +	 */
> > +	if (dig_port->tc_type == TC_PORT_TYPEC &&
> > +	    !(I915_READ(PORT_TX_DFLEXDPSP) &
> > TC_LIVE_STATE_TC(tc_port))) {
> > +		DRM_DEBUG_KMS("TC PHY %d sudden disconnect.\n",
> > tc_port);
> > +		val = I915_READ(PORT_TX_DFLEXDPCSSS);
> > +		val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
> > +		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
> > +		return false;
> > +	}
> > +
> > +	return true;
> > +}
> > +
> > +/*
> > + * See the comment at the connect function. This implements the
> > +Disconnect
> > + * Flow.
> > + */
> > +static void icl_tc_phy_disconnect(struct drm_i915_private
> > *dev_priv,
> > +				  struct intel_digital_port
> > *dig_port) {
> > +	enum tc_port tc_port = intel_port_to_tc(dev_priv,
> > dig_port->base.port);
> > +	u32 val;
> > +
> > +	if (dig_port->tc_type != TC_PORT_LEGACY &&
> > +	    dig_port->tc_type != TC_PORT_TYPEC)
> 
> 	Don’t we also need to check for dig_port->tc_type !=
> TC_PORT_TBT?

We don't need to run these steps for TBT, the TBT sequence is simpler.
See the spec.


> > +		return;
> > +
> > +	/*
> > +	 * This function may be called many times in a row without
> > an HPD event
> > +	 * in between, so try to avoid the write when we can.
> > +	 */
> > +	val = I915_READ(PORT_TX_DFLEXDPCSSS);
> > +	if (val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)) {
> > +		val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
> > +		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
> > +	}
> > +}
> > +
> > +/*
> > + * The type-C ports are different because even when they are
> > connected,
> > +they may
> > + * not be available/usable by the graphics driver: see the comment
> > on
> > + * icl_tc_phy_connect(). So in our driver instead of adding the
> > +additional
> > + * concept of "usable" and make everything check for "connected
> > and
> > +usable" we
> > + * define a port as "connected" when it is not only connected, but
> > also
> > +when it
> > + * is usable by the rest of the driver. That maintains the old
> > +assumption that
> > + * connected ports are usable, and avoids exposing to the users
> > objects
> > +they
> > + * can't really use.
> > + */
> > static bool icl_tc_port_connected(struct drm_i915_private
> > *dev_priv,
> > 				  struct intel_digital_port
> > *intel_dig_port)  { @@
> > -4836,12 +4934,17 @@ static bool icl_tc_port_connected(struct
> > drm_i915_private *dev_priv,
> > 	is_typec = dpsp & TC_LIVE_STATE_TC(tc_port);
> > 	is_tbt = dpsp & TC_LIVE_STATE_TBT(tc_port);
> > 
> > -	if (!is_legacy && !is_typec && !is_tbt)
> > +	if (!is_legacy && !is_typec && !is_tbt) {
> 
> If it is none of the above, then why not just return false?

Because we need to run the disconnect sequence in case the port was
previously connected so we release ownership of the lanes. That's the
very goal of this patch.

Thanks,
Paulo


> 	
> Anusha 
> > +		icl_tc_phy_disconnect(dev_priv, intel_dig_port);
> > 		return false;
> > +	}
> > 
> > 	icl_update_tc_port_type(dev_priv, intel_dig_port, is_legacy,
> > is_typec,
> > 				is_tbt);
> > 
> > +	if (!icl_tc_phy_connect(dev_priv, intel_dig_port))
> > +		return false;
> > +
> > 	return true;
> > }
> > 
> > @@ -4869,6 +4972,11 @@ static bool
> > icl_digital_port_connected(struct
> > intel_encoder *encoder)
> >  * intel_digital_port_connected - is the specified port connected?
> >  * @encoder: intel_encoder
> >  *
> > + * In cases where there's a connector physically connected but it
> > can't
> > + be used
> > + * by our hardware we also return false, since the rest of the
> > driver
> > + should
> > + * pretty much treat the port as disconnected. This is relevant
> > for
> > + type-C
> > + * (starting on ICL) where there's ownership involved.
> > + *
> >  * Return %true if port is connected, %false otherwise.
> >  */
> > bool intel_digital_port_connected(struct intel_encoder *encoder)
> > diff --git
> > a/drivers/gpu/drm/i915/intel_hdmi.c
> > b/drivers/gpu/drm/i915/intel_hdmi.c
> > index 8363fbd18ee8..548199e59b6c 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -1905,21 +1905,26 @@ intel_hdmi_set_edid(struct drm_connector
> > *connector)  static enum
> > drm_connector_status  intel_hdmi_detect(struct
> > drm_connector *connector, bool force)  {
> > -	enum drm_connector_status status;
> > +	enum drm_connector_status status =
> > connector_status_disconnected;
> > 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> > +	struct intel_hdmi *intel_hdmi =
> > intel_attached_hdmi(connector);
> > +	struct intel_encoder *encoder =
> > &hdmi_to_dig_port(intel_hdmi)->base;
> > 
> > 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
> > 		      connector->base.id, connector->name);
> > 
> > 	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
> > 
> > +	if (IS_ICELAKE(dev_priv) &&
> > +	    !intel_digital_port_connected(encoder))
> > +		goto out;
> > +
> > 	intel_hdmi_unset_edid(connector);
> > 
> > 	if (intel_hdmi_set_edid(connector))
> > 		status = connector_status_connected;
> > -	else
> > -		status = connector_status_disconnected;
> > 
> > +out:
> > 	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
> > 
> > 	return status;
> > --
> > 2.14.4
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows
  2018-08-01 17:34 ` [PATCH v3] " Paulo Zanoni
  2018-08-17 16:25   ` Srivatsa, Anusha
@ 2018-08-23  1:07   ` Rodrigo Vivi
  1 sibling, 0 replies; 12+ messages in thread
From: Rodrigo Vivi @ 2018-08-23  1:07 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

On Wed, Aug 01, 2018 at 10:34:41AM -0700, Paulo Zanoni wrote:
> Unlike the other ports, TC ports are not available to use as soon as
> we get a hotplug. The TC PHYs can be shared between multiple
> controllers: display, USB, etc. As a result, handshaking through FIA
> is required around connect and disconnect to cleanly transfer
> ownership with the controller and set the type-C power state.
> 
> This patch implements the flow sequences described by our
> specification. We opt to grab ownership of the ports as soon as we get
> the hotplugs in order to simplify the interactions and avoid surprises
> in the user space side. We may consider changing this in the future,
> once we improve our testing capabilities on this area.
> 
> v2:
>  * This unifies the DP and HDMI patches so we can discuss everything
>    at once so people looking at random single patches can actually
>    understand the direction.
>  * I found out the spec was updated a while ago. There's a small
>    difference in the connect flow and the patch was updated for that.
>  * Our spec also now gives a good explanation on what is really
>    happening. As a result, comments were added.
>  * Add some more comments as requested by Rodrigo (Rodrigo).
> v3:
>  * Downgrade a DRM_ERROR that shouldn't ever happen but we can't act
>    on in case it does (Chris).
> 
> BSpec: 21750, 4250.
> Cc: Animesh Manna <animesh.manna@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

sorry for taking so long...

thanks for the doc and all other changes.


Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>


> ---
>  drivers/gpu/drm/i915/i915_reg.h   |   6 +++
>  drivers/gpu/drm/i915/intel_dp.c   | 110 +++++++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_hdmi.c |  11 ++--
>  3 files changed, 123 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 1da1c7743785..a5f4dfe9ebdf 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -10750,4 +10750,10 @@ enum skl_power_gate {
>  #define   DP_LANE_ASSIGNMENT_MASK(tc_port)	(0xf << ((tc_port) * 8))
>  #define   DP_LANE_ASSIGNMENT(tc_port, x)	((x) << ((tc_port) * 8))
>  
> +#define PORT_TX_DFLEXDPPMS				_MMIO(0x163890)
> +#define   DP_PHY_MODE_STATUS_COMPLETED(tc_port)		(1 << (tc_port))
> +
> +#define PORT_TX_DFLEXDPCSSS				_MMIO(0x163894)
> +#define   DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)		(1 << (tc_port))
> +
>  #endif /* _I915_REG_H_ */
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index fec21aa3db93..86eded613456 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -4818,6 +4818,104 @@ static void icl_update_tc_port_type(struct drm_i915_private *dev_priv,
>  			      type_str);
>  }
>  
> +/*
> + * This function implements the first part of the Connect Flow described by our
> + * specification, Gen11 TypeC Programming chapter. The rest of the flow (reading
> + * lanes, EDID, etc) is done as needed in the typical places.
> + *
> + * Unlike the other ports, type-C ports are not available to use as soon as we
> + * get a hotplug. The type-C PHYs can be shared between multiple controllers:
> + * display, USB, etc. As a result, handshaking through FIA is required around
> + * connect and disconnect to cleanly transfer ownership with the controller and
> + * set the type-C power state.
> + *
> + * We could opt to only do the connect flow when we actually try to use the AUX
> + * channels or do a modeset, then immediately run the disconnect flow after
> + * usage, but there are some implications on this for a dynamic environment:
> + * things may go away or change behind our backs. So for now our driver is
> + * always trying to acquire ownership of the controller as soon as it gets an
> + * interrupt (or polls state and sees a port is connected) and only gives it
> + * back when it sees a disconnect. Implementation of a more fine-grained model
> + * will require a lot of coordination with user space and thorough testing for
> + * the extra possible cases.
> + */
> +static bool icl_tc_phy_connect(struct drm_i915_private *dev_priv,
> +			       struct intel_digital_port *dig_port)
> +{
> +	enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
> +	u32 val;
> +
> +	if (dig_port->tc_type != TC_PORT_LEGACY &&
> +	    dig_port->tc_type != TC_PORT_TYPEC)
> +		return true;
> +
> +	val = I915_READ(PORT_TX_DFLEXDPPMS);
> +	if (!(val & DP_PHY_MODE_STATUS_COMPLETED(tc_port))) {
> +		DRM_DEBUG_KMS("DP PHY for TC port %d not ready\n", tc_port);
> +		return false;
> +	}
> +
> +	/*
> +	 * This function may be called many times in a row without an HPD event
> +	 * in between, so try to avoid the write when we can.
> +	 */
> +	val = I915_READ(PORT_TX_DFLEXDPCSSS);
> +	if (!(val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port))) {
> +		val |= DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
> +		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
> +	}
> +
> +	/*
> +	 * Now we have to re-check the live state, in case the port recently
> +	 * became disconnected. Not necessary for legacy mode.
> +	 */
> +	if (dig_port->tc_type == TC_PORT_TYPEC &&
> +	    !(I915_READ(PORT_TX_DFLEXDPSP) & TC_LIVE_STATE_TC(tc_port))) {
> +		DRM_DEBUG_KMS("TC PHY %d sudden disconnect.\n", tc_port);
> +		val = I915_READ(PORT_TX_DFLEXDPCSSS);
> +		val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
> +		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
> +		return false;
> +	}
> +
> +	return true;
> +}
> +
> +/*
> + * See the comment at the connect function. This implements the Disconnect
> + * Flow.
> + */
> +static void icl_tc_phy_disconnect(struct drm_i915_private *dev_priv,
> +				  struct intel_digital_port *dig_port)
> +{
> +	enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
> +	u32 val;
> +
> +	if (dig_port->tc_type != TC_PORT_LEGACY &&
> +	    dig_port->tc_type != TC_PORT_TYPEC)
> +		return;
> +
> +	/*
> +	 * This function may be called many times in a row without an HPD event
> +	 * in between, so try to avoid the write when we can.
> +	 */
> +	val = I915_READ(PORT_TX_DFLEXDPCSSS);
> +	if (val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port)) {
> +		val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
> +		I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
> +	}
> +}
> +
> +/*
> + * The type-C ports are different because even when they are connected, they may
> + * not be available/usable by the graphics driver: see the comment on
> + * icl_tc_phy_connect(). So in our driver instead of adding the additional
> + * concept of "usable" and make everything check for "connected and usable" we
> + * define a port as "connected" when it is not only connected, but also when it
> + * is usable by the rest of the driver. That maintains the old assumption that
> + * connected ports are usable, and avoids exposing to the users objects they
> + * can't really use.
> + */
>  static bool icl_tc_port_connected(struct drm_i915_private *dev_priv,
>  				  struct intel_digital_port *intel_dig_port)
>  {
> @@ -4836,12 +4934,17 @@ static bool icl_tc_port_connected(struct drm_i915_private *dev_priv,
>  	is_typec = dpsp & TC_LIVE_STATE_TC(tc_port);
>  	is_tbt = dpsp & TC_LIVE_STATE_TBT(tc_port);
>  
> -	if (!is_legacy && !is_typec && !is_tbt)
> +	if (!is_legacy && !is_typec && !is_tbt) {
> +		icl_tc_phy_disconnect(dev_priv, intel_dig_port);
>  		return false;
> +	}
>  
>  	icl_update_tc_port_type(dev_priv, intel_dig_port, is_legacy, is_typec,
>  				is_tbt);
>  
> +	if (!icl_tc_phy_connect(dev_priv, intel_dig_port))
> +		return false;
> +
>  	return true;
>  }
>  
> @@ -4869,6 +4972,11 @@ static bool icl_digital_port_connected(struct intel_encoder *encoder)
>   * intel_digital_port_connected - is the specified port connected?
>   * @encoder: intel_encoder
>   *
> + * In cases where there's a connector physically connected but it can't be used
> + * by our hardware we also return false, since the rest of the driver should
> + * pretty much treat the port as disconnected. This is relevant for type-C
> + * (starting on ICL) where there's ownership involved.
> + *
>   * Return %true if port is connected, %false otherwise.
>   */
>  bool intel_digital_port_connected(struct intel_encoder *encoder)
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 8363fbd18ee8..548199e59b6c 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1905,21 +1905,26 @@ intel_hdmi_set_edid(struct drm_connector *connector)
>  static enum drm_connector_status
>  intel_hdmi_detect(struct drm_connector *connector, bool force)
>  {
> -	enum drm_connector_status status;
> +	enum drm_connector_status status = connector_status_disconnected;
>  	struct drm_i915_private *dev_priv = to_i915(connector->dev);
> +	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> +	struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base;
>  
>  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
>  		      connector->base.id, connector->name);
>  
>  	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
>  
> +	if (IS_ICELAKE(dev_priv) &&
> +	    !intel_digital_port_connected(encoder))
> +		goto out;
> +
>  	intel_hdmi_unset_edid(connector);
>  
>  	if (intel_hdmi_set_edid(connector))
>  		status = connector_status_connected;
> -	else
> -		status = connector_status_disconnected;
>  
> +out:
>  	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
>  
>  	return status;
> -- 
> 2.14.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✓ Fi.CI.BAT: success for drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows (rev2)
  2018-07-31 23:45 [PATCH] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows Paulo Zanoni
                   ` (4 preceding siblings ...)
  2018-08-01 18:34 ` ✗ Fi.CI.BAT: failure for drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows (rev2) Patchwork
@ 2018-08-23 22:17 ` Patchwork
  2018-08-23 23:30 ` ✗ Fi.CI.IGT: failure " Patchwork
  6 siblings, 0 replies; 12+ messages in thread
From: Patchwork @ 2018-08-23 22:17 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows (rev2)
URL   : https://patchwork.freedesktop.org/series/47518/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_4702 -> Patchwork_10002 =

== Summary - SUCCESS ==

  No regressions found.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/47518/revisions/2/mbox/

== Possible new issues ==

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

  === IGT changes ===

    ==== Warnings ====

    {igt@pm_rpm@module-reload}:
      fi-byt-n2820:       DMESG-FAIL -> DMESG-WARN

    
== Known issues ==

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

  === IGT changes ===

    ==== Issues hit ====

    igt@debugfs_test@read_all_entries:
      fi-kbl-r:           PASS -> DMESG-WARN (fdo#105602)

    igt@kms_frontbuffer_tracking@basic:
      {fi-byt-clapper}:   PASS -> FAIL (fdo#103167)

    igt@kms_pipe_crc_basic@nonblocking-crc-pipe-b:
      {fi-byt-clapper}:   PASS -> FAIL (fdo#107362)

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

  fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
  fdo#105602 https://bugs.freedesktop.org/show_bug.cgi?id=105602
  fdo#107362 https://bugs.freedesktop.org/show_bug.cgi?id=107362


== Participating hosts (53 -> 48) ==

  Missing    (5): fi-ctg-p8600 fi-ilk-m540 fi-byt-squawks fi-bsw-cyan fi-hsw-4200u 


== Build changes ==

    * Linux: CI_DRM_4702 -> Patchwork_10002

  CI_DRM_4702: 0349bfb08204a6b44f16551c2be3b58563ff73d2 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4608: 94ebd21177feedf03e8f6dd1e73dca1a6ec7a0ac @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_10002: 2b4ca525e11918638986e975d28f7f5a5e8b4de2 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

2b4ca525e119 drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows

== Logs ==

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

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

* ✗ Fi.CI.IGT: failure for drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows (rev2)
  2018-07-31 23:45 [PATCH] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows Paulo Zanoni
                   ` (5 preceding siblings ...)
  2018-08-23 22:17 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2018-08-23 23:30 ` Patchwork
  6 siblings, 0 replies; 12+ messages in thread
From: Patchwork @ 2018-08-23 23:30 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows (rev2)
URL   : https://patchwork.freedesktop.org/series/47518/
State : failure

== Summary ==

= CI Bug Log - changes from CI_DRM_4702_full -> Patchwork_10002_full =

== Summary - FAILURE ==

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

  

== Possible new issues ==

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

  === IGT changes ===

    ==== Possible regressions ====

    igt@gem_eio@banned:
      shard-glk:          PASS -> FAIL

    igt@gem_eio@reset-stress:
      shard-apl:          PASS -> FAIL

    
    ==== Warnings ====

    igt@kms_cursor_legacy@cursorb-vs-flipa-toggle:
      shard-hsw:          SKIP -> PASS

    
== Known issues ==

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

  === IGT changes ===

    ==== Issues hit ====

    igt@drv_suspend@shrink:
      shard-hsw:          PASS -> INCOMPLETE (fdo#103540, fdo#106886)

    igt@pm_rpm@system-suspend:
      shard-kbl:          PASS -> INCOMPLETE (fdo#103665, fdo#107556)

    
    ==== Possible fixes ====

    igt@drv_selftest@live_hangcheck:
      shard-apl:          DMESG-FAIL (fdo#106947, fdo#106560) -> PASS

    igt@gem_ppgtt@blt-vs-render-ctx0:
      shard-kbl:          INCOMPLETE (fdo#106023, fdo#103665) -> PASS

    igt@kms_flip@flip-vs-expired-vblank-interruptible:
      shard-glk:          FAIL (fdo#105363) -> PASS

    
  fdo#103540 https://bugs.freedesktop.org/show_bug.cgi?id=103540
  fdo#103665 https://bugs.freedesktop.org/show_bug.cgi?id=103665
  fdo#105363 https://bugs.freedesktop.org/show_bug.cgi?id=105363
  fdo#106023 https://bugs.freedesktop.org/show_bug.cgi?id=106023
  fdo#106560 https://bugs.freedesktop.org/show_bug.cgi?id=106560
  fdo#106886 https://bugs.freedesktop.org/show_bug.cgi?id=106886
  fdo#106947 https://bugs.freedesktop.org/show_bug.cgi?id=106947
  fdo#107556 https://bugs.freedesktop.org/show_bug.cgi?id=107556


== Participating hosts (5 -> 5) ==

  No changes in participating hosts


== Build changes ==

    * Linux: CI_DRM_4702 -> Patchwork_10002

  CI_DRM_4702: 0349bfb08204a6b44f16551c2be3b58563ff73d2 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4608: 94ebd21177feedf03e8f6dd1e73dca1a6ec7a0ac @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_10002: 2b4ca525e11918638986e975d28f7f5a5e8b4de2 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

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

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

end of thread, other threads:[~2018-08-23 23:30 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-31 23:45 [PATCH] drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows Paulo Zanoni
2018-08-01  0:21 ` ✓ Fi.CI.BAT: success for " Patchwork
2018-08-01  1:15 ` ✓ Fi.CI.IGT: " Patchwork
2018-08-01  8:22 ` [PATCH] " Chris Wilson
2018-08-01 17:05   ` Paulo Zanoni
2018-08-01 17:34 ` [PATCH v3] " Paulo Zanoni
2018-08-17 16:25   ` Srivatsa, Anusha
2018-08-17 23:27     ` Paulo Zanoni
2018-08-23  1:07   ` Rodrigo Vivi
2018-08-01 18:34 ` ✗ Fi.CI.BAT: failure for drm/i915/icl: implement the tc/legacy HPD {dis, }connect flows (rev2) Patchwork
2018-08-23 22:17 ` ✓ Fi.CI.BAT: success " Patchwork
2018-08-23 23:30 ` ✗ Fi.CI.IGT: failure " Patchwork

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