Skip to contentSkip to conversation

drm/i915: Fix LSPCON TMDS output buffer enabling from low-power state

PATCH Applied Imre Deak 5 participants 6 messages Apr 16, 2018 – Apr 18, 2018

Subsystems (2)
lore
Share & tools
lore

Imre Deak

author
#0 lore raw

PATCH 1/1 drm/i915: Fix LSPCON TMDS output buffer enabling from low-power state

LSPCON adapters in low-power state may ignore the first I2C write during TMDS output buffer enabling, resulting in a blank screen even with an otherwise enabled pipe. Fix this by reading back and validating the written value a few times.

The problem was noticed on GLK machines with an onboard LSPCON adapter after entering/exiting DC5 power state. Doing an I2C read of the adapter ID as the first transaction - instead of the I2C write to enable the TMDS buffers - returns the correct value. Based on this we assume that the transaction itself is sent properly, it's only the adapter that is not ready for some reason to accept this first write after waking from low-power state. In my case the second I2C write attempt always succeeded.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105854

Cc Clinton Taylor <[email protected]>
Cc Ville Syrjälä <[email protected]>
---
 drivers/gpu/drm/drm_dp_dual_mode_helper.c | 39 +++++++++++++++++++++++++------
 1 file changed, 32 insertions(+), 7 deletions(-)
drivers/gpu/drm/drm_dp_dual_mode_helper.c +32 -7
index 02a50929af67..e7f4fe2848a5 100644
@@ -350,19 +350,44 @@ int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
 {
 	uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE;
 	ssize_t ret;
+	int retry;
 
 	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
 		return 0;
 
-	ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
-				     &tmds_oen, sizeof(tmds_oen));
-	if (ret) {
-		DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n",
-			      enable ? "enable" : "disable");
-		return ret;
+	/*
+	 * LSPCON adapters in low-power state may ignore the first write, so
+	 * read back and verify the written value a few times.
+	 */
+	for (retry = 0; retry < 3; retry++) {
+		uint8_t tmp;
+
+		ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
+					     &tmds_oen, sizeof(tmds_oen));
+		if (ret) {
+			DRM_DEBUG_KMS("Failed to %s TMDS output buffers (%d attempts)\n",
+				      enable ? "enable" : "disable",
+				      retry + 1);
+			return ret;
+		}
+
+		ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN,
+					    &tmp, sizeof(tmp));
+		if (ret) {
+			DRM_DEBUG_KMS("I2C read failed during TMDS output buffer %s (%d attempts)\n",
+				      enable ? "enabling" : "disabling",
+				      retry + 1);
+			return ret;
+		}
+
+		if (tmp == tmds_oen)
+			return 0;
 	}
 
-	return 0;
+	DRM_DEBUG_KMS("I2C write value mismatch during TMDS output buffer %s\n",
+		      enable ? "enabling" : "disabling");
+
+	return -EIO;
 }
 EXPORT_SYMBOL(drm_dp_dual_mode_set_tmds_output);
 
Signature · 6 lines
2.13.2

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
#1 lore raw

✓ Fi.CI.BAT: success for drm/i915: Fix LSPCON TMDS output buffer enabling from low-power state

== Series Details ==

== Series Details ==

Series: drm/i915: Fix LSPCON TMDS output buffer enabling from low-power state
URL : https://patchwork.freedesktop.org/series/41759/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_4057 -> Patchwork_8697 =

== Summary - WARNING ==

Minor unknown changes coming with Patchwork_8697 need to be verified manually.

If you think the reported changes have nothing to do with the changes introduced in Patchwork_8697, 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/41759/revisions/1/mbox/

== Possible new issues ==

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

=== IGT changes ===

    ==== Warnings ====

    igt@gem_exec_gttfill@basic:
      fi-pnv-d510:        SKIP -> PASS

== Known issues ==

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

=== IGT changes ===

    ==== Issues hit ====

    igt@debugfs_test@read_all_entries:
      fi-snb-2520m:       PASS -> INCOMPLETE (fdo#103713)

    igt@gem_mmap_gtt@basic-small-bo-tiledx:
      fi-gdg-551:         PASS -> FAIL (fdo#102575)

    
    ==== Possible fixes ====

    igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b:
      fi-ivb-3520m:       DMESG-WARN (fdo#106084) -> PASS +1

fdo#102575 https://bugs.freedesktop.org/show_bug.cgi?id=102575
fdo#103713 https://bugs.freedesktop.org/show_bug.cgi?id=103713
fdo#106084 https://bugs.freedesktop.org/show_bug.cgi?id=106084

== Participating hosts (36 -> 33) ==

Missing (3): fi-ctg-p8600 fi-ilk-m540 fi-skl-6700hq

== Build changes ==

* Linux: CI_DRM_4057 -> Patchwork_8697

CI_DRM_4057: ac35105865ed2d4d9676fdb4752798b047fb126a @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_4432: 8b77704db49167f7ebfd1c470d9c129d3b862cb6 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
Patchwork_8697: 5c78b9dc05bc38b3d767abc50a33b889e7cfd29d @ git://anongit.freedesktop.org/gfx-ci/linux
piglit_4432: 93b35926a150e318439d2505901288594b3548f5 @ git://anongit.freedesktop.org/piglit

== Linux commits ==

5c78b9dc05bc drm/i915: Fix LSPCON TMDS output buffer enabling from low-power state

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8697/issues.html
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

#2 lore raw

✓ Fi.CI.IGT: success for drm/i915: Fix LSPCON TMDS output buffer enabling from low-power state

In reply to Imre Deak
== Series Details ==

== Series Details ==

Series: drm/i915: Fix LSPCON TMDS output buffer enabling from low-power state
URL : https://patchwork.freedesktop.org/series/41759/
State : success

== Summary ==

= CI Bug Log - changes from CI_DRM_4057_full -> Patchwork_8697_full =

== Summary - WARNING ==

Minor unknown changes coming with Patchwork_8697_full need to be verified manually.

If you think the reported changes have nothing to do with the changes introduced in Patchwork_8697_full, 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/41759/revisions/1/mbox/

== Possible new issues ==

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

=== IGT changes ===

    ==== Warnings ====

    igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-mmap-cpu:
      shard-snb:          SKIP -> PASS +1

== Known issues ==

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

=== IGT changes ===

    ==== Issues hit ====

    igt@kms_flip@2x-blocking-wf_vblank:
      shard-hsw:          PASS -> FAIL (fdo#103928)

    igt@kms_flip@2x-plain-flip-ts-check-interruptible:
      shard-hsw:          PASS -> FAIL (fdo#100368)

    igt@kms_flip@modeset-vs-vblank-race-interruptible:
      shard-hsw:          PASS -> FAIL (fdo#103060)

    igt@kms_plane_lowres@pipe-c-tiling-yf:
      shard-apl:          PASS -> FAIL (fdo#103166)

    igt@perf_pmu@rc6-runtime-pm-long:
      shard-apl:          PASS -> FAIL (fdo#105010)

    
    ==== Possible fixes ====

    igt@kms_mmio_vs_cs_flip@setcrtc_vs_cs_flip:
      shard-kbl:          DMESG-WARN (fdo#105602, fdo#103558) -> PASS +10

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

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#103166 https://bugs.freedesktop.org/show_bug.cgi?id=103166
fdo#103558 https://bugs.freedesktop.org/show_bug.cgi?id=103558
fdo#103928 https://bugs.freedesktop.org/show_bug.cgi?id=103928
fdo#105010 https://bugs.freedesktop.org/show_bug.cgi?id=105010
fdo#105602 https://bugs.freedesktop.org/show_bug.cgi?id=105602

== Participating hosts (6 -> 4) ==

Missing (2): shard-glk shard-glkb

== Build changes ==

* Linux: CI_DRM_4057 -> Patchwork_8697

CI_DRM_4057: ac35105865ed2d4d9676fdb4752798b047fb126a @ git://anongit.freedesktop.org/gfx-ci/linux
IGT_4432: 8b77704db49167f7ebfd1c470d9c129d3b862cb6 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
Patchwork_8697: 5c78b9dc05bc38b3d767abc50a33b889e7cfd29d @ git://anongit.freedesktop.org/gfx-ci/linux
piglit_4432: 93b35926a150e318439d2505901288594b3548f5 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8697/shards.html
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reviewed-by Tested-by on v1 1/1
#3 lore raw
In reply to Imre Deak
Quoted 68 lines · Imre Deak

LSPCON adapters in low-power state may ignore the first I2C write during TMDS output buffer enabling, resulting in a blank screen even with an otherwise enabled pipe. Fix this by reading back and validating the written value a few times.

The problem was noticed on GLK machines with an onboard LSPCON adapter after entering/exiting DC5 power state. Doing an I2C read of the adapter ID as the first transaction - instead of the I2C write to enable the TMDS buffers - returns the correct value. Based on this we assume that the transaction itself is sent properly, it's only the adapter that is not ready for some reason to accept this first write after waking from low-power state. In my case the second I2C write attempt always succeeded.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105854

Cc Clinton Taylor <[email protected]>
Cc Ville Syrjälä <[email protected]>
---
  drivers/gpu/drm/drm_dp_dual_mode_helper.c | 39 +++++++++++++++++++++++++------
  1 file changed, 32 insertions(+), 7 deletions(-)
drivers/gpu/drm/drm_dp_dual_mode_helper.c +28 -6
index 02a50929af67..e7f4fe2848a5 100644
@@ -350,19 +350,44 @@ int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
  {
  	uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE;
  	ssize_t ret;
+	int retry;
 
  	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
  		return 0;
 
-	ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
-				     &tmds_oen, sizeof(tmds_oen));
-	if (ret) {
-		DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n",
-			      enable ? "enable" : "disable");
-		return ret;
+	/*
+	 * LSPCON adapters in low-power state may ignore the first write, so
+	 * read back and verify the written value a few times.
+	 */
+	for (retry = 0; retry < 3; retry++) {
+		uint8_t tmp;
+
+		ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
+					     &tmds_oen, sizeof(tmds_oen));
+		if (ret) {
+			DRM_DEBUG_KMS("Failed to %s TMDS output buffers (%d attempts)\n",
+				      enable ? "enable" : "disable",
+				      retry + 1);
+			return ret;
+		}
+
+		ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN,
+					    &tmp, sizeof(tmp));
+		if (ret) {
+			DRM_DEBUG_KMS("I2C read failed during TMDS output buffer %s (%d attempts)\n",
+				      enable ? "enabling" : "disabling",
+				      retry + 1);
+			return ret;
+		}
+
+		if (tmp == tmds_oen)
+			return 0;

drivers/gpu/drm/drm_dp_dual_mode_helper.c int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type, · line 393

Quoted 10 lines
drivers/gpu/drm/drm_dp_dual_mode_helper.c +4 -1
  	}
 
-	return 0;
+	DRM_DEBUG_KMS("I2C write value mismatch during TMDS output buffer %s\n",
+		      enable ? "enabling" : "disabling");
+
+	return -EIO;
  }
  EXPORT_SYMBOL(drm_dp_dual_mode_set_tmds_output);
 

Appears to fix the issue seen on GLK with LSPCON and DMC firmware loaded. Customer was concerned about the fix being in DRM instead of i915. However, there are no other SOCs that use this DRM function.

-Clint

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Applied
#4 lore raw
Quoted 84 lines · Clint Taylor
Quoted 68 lines · Imre Deak

LSPCON adapters in low-power state may ignore the first I2C write during TMDS output buffer enabling, resulting in a blank screen even with an otherwise enabled pipe. Fix this by reading back and validating the written value a few times.

The problem was noticed on GLK machines with an onboard LSPCON adapter after entering/exiting DC5 power state. Doing an I2C read of the adapter ID as the first transaction - instead of the I2C write to enable the TMDS buffers - returns the correct value. Based on this we assume that the transaction itself is sent properly, it's only the adapter that is not ready for some reason to accept this first write after waking from low-power state. In my case the second I2C write attempt always succeeded.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105854

Cc Clinton Taylor <[email protected]>
Cc Ville Syrjälä <[email protected]>
---
  drivers/gpu/drm/drm_dp_dual_mode_helper.c | 39 +++++++++++++++++++++++++------
  1 file changed, 32 insertions(+), 7 deletions(-)
drivers/gpu/drm/drm_dp_dual_mode_helper.c +28 -6
index 02a50929af67..e7f4fe2848a5 100644
@@ -350,19 +350,44 @@ int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
  {
  	uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE;
  	ssize_t ret;
+	int retry;
 
  	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
  		return 0;
 
-	ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
-				     &tmds_oen, sizeof(tmds_oen));
-	if (ret) {
-		DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n",
-			      enable ? "enable" : "disable");
-		return ret;
+	/*
+	 * LSPCON adapters in low-power state may ignore the first write, so
+	 * read back and verify the written value a few times.
+	 */
+	for (retry = 0; retry < 3; retry++) {
+		uint8_t tmp;
+
+		ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
+					     &tmds_oen, sizeof(tmds_oen));
+		if (ret) {
+			DRM_DEBUG_KMS("Failed to %s TMDS output buffers (%d attempts)\n",
+				      enable ? "enable" : "disable",
+				      retry + 1);
+			return ret;
+		}
+
+		ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN,
+					    &tmp, sizeof(tmp));
+		if (ret) {
+			DRM_DEBUG_KMS("I2C read failed during TMDS output buffer %s (%d attempts)\n",
+				      enable ? "enabling" : "disabling",
+				      retry + 1);
+			return ret;
+		}
+
+		if (tmp == tmds_oen)
+			return 0;

drivers/gpu/drm/drm_dp_dual_mode_helper.c int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type, · line 393

Quoted 10 lines
drivers/gpu/drm/drm_dp_dual_mode_helper.c +4 -1
  	}
 
-	return 0;
+	DRM_DEBUG_KMS("I2C write value mismatch during TMDS output buffer %s\n",
+		      enable ? "enabling" : "disabling");
+
+	return -EIO;
  }
  EXPORT_SYMBOL(drm_dp_dual_mode_set_tmds_output);
 

Appears to fix the issue seen on GLK with LSPCON and DMC firmware loaded. Customer was concerned about the fix being in DRM instead of i915. However, there are no other SOCs that use this DRM function.

Quoted 2 lines

Pushed to drm-misc-fixes, thanks for the patch.

Clint and Ville, many thanks for your testing and review, alas I screwed up and pushed this without the tags added to the commit. I'm sorry. I expect better from myself. :(

BR,
Jani.

Quoted 8 lines

-Clint

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Signature · 5 lines
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Reviewed-by on v1 1/1
#5 lore raw
In reply to Imre Deak
Quoted 5 lines · Imre Deak

LSPCON adapters in low-power state may ignore the first I2C write during TMDS output buffer enabling, resulting in a blank screen even with an otherwise enabled pipe. Fix this by reading back and validating the written value a few times.

Quoted 8 lines

The problem was noticed on GLK machines with an onboard LSPCON adapter after entering/exiting DC5 power state. Doing an I2C read of the adapter ID as the first transaction - instead of the I2C write to enable the TMDS buffers - returns the correct value. Based on this we assume that the transaction itself is sent properly, it's only the adapter that is not ready for some reason to accept this first write after waking from low-power state. In my case the second I2C write attempt always succeeded.

Yeah, I guess this is an OK approach. Probably not much point in optimizing the non-LSPCON case since this is modeset stuff, although we do have the adaptor type passed in so we could if we wanted to.

Quoted 67 lines

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105854

Cc Clinton Taylor <[email protected]>
Cc Ville Syrjälä <[email protected]>
---
 drivers/gpu/drm/drm_dp_dual_mode_helper.c | 39 +++++++++++++++++++++++++------
 1 file changed, 32 insertions(+), 7 deletions(-)
drivers/gpu/drm/drm_dp_dual_mode_helper.c +32 -7
index 02a50929af67..e7f4fe2848a5 100644
@@ -350,19 +350,44 @@ int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
 {
 	uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE;
 	ssize_t ret;
+	int retry;
 
 	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
 		return 0;
 
-	ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
-				     &tmds_oen, sizeof(tmds_oen));
-	if (ret) {
-		DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n",
-			      enable ? "enable" : "disable");
-		return ret;
+	/*
+	 * LSPCON adapters in low-power state may ignore the first write, so
+	 * read back and verify the written value a few times.
+	 */
+	for (retry = 0; retry < 3; retry++) {
+		uint8_t tmp;
+
+		ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
+					     &tmds_oen, sizeof(tmds_oen));
+		if (ret) {
+			DRM_DEBUG_KMS("Failed to %s TMDS output buffers (%d attempts)\n",
+				      enable ? "enable" : "disable",
+				      retry + 1);
+			return ret;
+		}
+
+		ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN,
+					    &tmp, sizeof(tmp));
+		if (ret) {
+			DRM_DEBUG_KMS("I2C read failed during TMDS output buffer %s (%d attempts)\n",
+				      enable ? "enabling" : "disabling",
+				      retry + 1);
+			return ret;
+		}
+
+		if (tmp == tmds_oen)
+			return 0;
 	}
 
-	return 0;
+	DRM_DEBUG_KMS("I2C write value mismatch during TMDS output buffer %s\n",
+		      enable ? "enabling" : "disabling");
+
+	return -EIO;
 }
 EXPORT_SYMBOL(drm_dp_dual_mode_set_tmds_output);
 
Signature · 1 line
2.13.2
Signature · 6 lines
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx