Skip to contentSkip to conversation

drm/i915/bxt,glk: Increase PCODE timeouts during CDCLK freq changing

PATCH In review Imre Deak 4 participants 7 messages Jan 30, 2018 – Feb 1, 2018

Subsystems (3)
lore
Share & tools
lore

Imre Deak

author
#0 lore raw

PATCH v2 1/2 drm/i915/bxt,glk: Increase PCODE timeouts during CDCLK freq changing

Currently we see sporadic timeouts during CDCLK changing both on BXT and GLK as reported by the Bugzilla: ticket. It's easy to reproduce this by changing the frequency in a tight loop after blanking the display. The upper bound for the completion time is 800us based on my tests, so increase it from the current 500us to 2ms; with that I couldn't trigger the problem either on BXT or GLK.

Note that timeouts happened during both the change notification and the voltage level setting PCODE request. (For the latter one BSpec doesn't require us to wait for completion before further HW programming.)

This issue is similar to
2c7d0602c815 ("drm/i915/gen9: Fix PCODE polling during CDCLK change notification")
but there the PCODE request does complete (as shown by the mbox busy flag), only the reply we get from PCODE indicates a failure. So there we keep resending the request until a success reply, here we just have to increase the timeout for the one PCODE request we send.

v2:
- s/snb_pcode_request/sandybridge_pcode_write_timeout/ (Ville)

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

---
 drivers/gpu/drm/i915/i915_drv.h    |  6 +++++-
 drivers/gpu/drm/i915/intel_cdclk.c | 22 +++++++++++++++++-----
 drivers/gpu/drm/i915/intel_pm.c    |  6 +++---
 3 files changed, 25 insertions(+), 9 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +5 -1
index 454d8f937fae..7e83d0d3e632 100644
@@ -3723,7 +3723,11 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
 					    struct intel_display_error_state *error);
 
 int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
-int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
+int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv, u32 mbox,
+				    u32 val, int timeout_us);
+#define sandybridge_pcode_write(dev_priv, mbox, val)	\
+	sandybridge_pcode_write_timeout(dev_priv, mbox, val, 500)
+
 int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
 		      u32 reply_mask, u32 reply, int timeout_base_ms);
 
drivers/gpu/drm/i915/intel_cdclk.c +17 -5
index c4392ea34a3d..a423b674fcec 100644
@@ -1370,10 +1370,15 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 		break;
 	}
 
-	/* Inform power controller of upcoming frequency change */
+	/*
+	 * Inform power controller of upcoming frequency change. BSpec
+	 * requires us to wait up to 150usec, but that leads to timeouts;
+	 * the 2ms used here is based on experiment.
+	 */
 	mutex_lock(&dev_priv->pcu_lock);
-	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
-				      0x80000000);
+	ret = sandybridge_pcode_write_timeout(dev_priv,
+					      HSW_PCODE_DE_WRITE_FREQ_REQ,
+					      0x80000000, 2000);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	if (ret) {
@@ -1404,8 +1409,15 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 	I915_WRITE(CDCLK_CTL, val);
 
 	mutex_lock(&dev_priv->pcu_lock);
-	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
-				      cdclk_state->voltage_level);
+	/*
+	 * The timeout isn't specified, the 2ms used here is based on
+	 * experiment.
+	 * FIXME: Waiting for the request completion could be delayed until
+	 * the next PCODE request based on BSpec.
+	 */
+	ret = sandybridge_pcode_write_timeout(dev_priv,
+					      HSW_PCODE_DE_WRITE_FREQ_REQ,
+					      cdclk_state->voltage_level, 2000);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	if (ret) {
drivers/gpu/drm/i915/intel_pm.c +3 -3
index 0b92ea1dbd40..a6098932be5a 100644
@@ -9169,8 +9169,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
 	return 0;
 }
 
-int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
-			    u32 mbox, u32 val)
+int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv,
+				    u32 mbox, u32 val, int timeout_us)
 {
 	int status;
 
@@ -9193,7 +9193,7 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
 
 	if (__intel_wait_for_register_fw(dev_priv,
 					 GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
-					 500, 0, NULL)) {
+					 timeout_us, 0, NULL)) {
 		DRM_ERROR("timeout waiting for pcode write of 0x%08x to mbox %x to finish for %ps\n",
 			  val, mbox, __builtin_return_address(0));
 		return -ETIMEDOUT;
Signature · 1 line
2.13.2
author
#1 lore raw

PATCH v2 2/2 drm/i915/bxt, glk: Avoid long atomic poll during CDCLK change

There is no requirement for doing the PCODE request polling atomically, so do that only for a short time switching to sleeping poll afterwards. The specification requires a 150usec timeout for the change notification, so let's use that for the atomic poll. Do the extra 2ms poll - needed as a workaround on BXT/GLK - in sleeping mode.

v2:
- rebase on v2 of patchset dropping the sandybridge_pcode_read/write refactoring (Chris)

Cc Chris Wilson <[email protected]>
Cc Ville Syrjälä <[email protected]>
---
 drivers/gpu/drm/i915/i915_drv.h    | 5 +++--
 drivers/gpu/drm/i915/intel_cdclk.c | 4 ++--
 drivers/gpu/drm/i915/intel_pm.c    | 6 ++++--
 3 files changed, 9 insertions(+), 6 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +3 -2
index 7e83d0d3e632..08c6c824d7f8 100644
@@ -3724,9 +3724,10 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
 
 int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
 int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv, u32 mbox,
-				    u32 val, int timeout_us);
+				    u32 val, int fast_timeout_us,
+				    int slow_timeout_ms);
 #define sandybridge_pcode_write(dev_priv, mbox, val)	\
-	sandybridge_pcode_write_timeout(dev_priv, mbox, val, 500)
+	sandybridge_pcode_write_timeout(dev_priv, mbox, val, 500, 0)
 
 int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
 		      u32 reply_mask, u32 reply, int timeout_base_ms);
drivers/gpu/drm/i915/intel_cdclk.c +2 -2
index a423b674fcec..ee788d5be5e3 100644
@@ -1378,7 +1378,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 	mutex_lock(&dev_priv->pcu_lock);
 	ret = sandybridge_pcode_write_timeout(dev_priv,
 					      HSW_PCODE_DE_WRITE_FREQ_REQ,
-					      0x80000000, 2000);
+					      0x80000000, 150, 2);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	if (ret) {
@@ -1417,7 +1417,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 	 */
 	ret = sandybridge_pcode_write_timeout(dev_priv,
 					      HSW_PCODE_DE_WRITE_FREQ_REQ,
-					      cdclk_state->voltage_level, 2000);
+					      cdclk_state->voltage_level, 150, 2);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	if (ret) {
drivers/gpu/drm/i915/intel_pm.c +4 -2
index a6098932be5a..19f00f7c7868 100644
@@ -9170,7 +9170,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
 }
 
 int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv,
-				    u32 mbox, u32 val, int timeout_us)
+				    u32 mbox, u32 val,
+				    int fast_timeout_us, int slow_timeout_ms)
 {
 	int status;
 
@@ -9193,7 +9194,8 @@ int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv,
 
 	if (__intel_wait_for_register_fw(dev_priv,
 					 GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
-					 timeout_us, 0, NULL)) {
+					 fast_timeout_us, slow_timeout_ms,
+					 NULL)) {
 		DRM_ERROR("timeout waiting for pcode write of 0x%08x to mbox %x to finish for %ps\n",
 			  val, mbox, __builtin_return_address(0));
 		return -ETIMEDOUT;
Signature · 6 lines
2.13.2

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Reviewed-by on v2 2/2
#2 lore raw

Re: [PATCH v2 2/2] drm/i915/bxt, glk: Avoid long atomic poll during CDCLK change

Quoting Imre Deak (2018-01-30 14:29:39)

Quoted 6 lines

There is no requirement for doing the PCODE request polling atomically, so do that only for a short time switching to sleeping poll afterwards. The specification requires a 150usec timeout for the change notification, so let's use that for the atomic poll. Do the extra 2ms poll - needed as a workaround on BXT/GLK - in sleeping mode.

Quoted 7 lines

v2:
- rebase on v2 of patchset dropping the sandybridge_pcode_read/write refactoring (Chris)

Cc Chris Wilson <[email protected]>
Cc Ville Syrjälä <[email protected]>

Likewise, I'm also happier with _timeout.

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

#3 lore raw

✓ Fi.CI.BAT: success for series starting with [v2,1/2] drm/i915/bxt, glk: Increase PCODE timeouts during CDCLK freq changing

In reply to Imre Deak
== Series Details ==

== Series Details ==

Series: series starting with [v2,1/2] drm/i915/bxt, glk: Increase PCODE timeouts during CDCLK freq changing
URL : https://patchwork.freedesktop.org/series/37344/
State : success

== Summary ==

Series 37344v1 series starting with [v2,1/2] drm/i915/bxt, glk: Increase PCODE timeouts during CDCLK freq changing
https://patchwork.freedesktop.org/api/1.0/series/37344/revisions/1/mbox/

Test kms_pipe_crc_basic:

        Subgroup suspend-read-crc-pipe-b:
                incomplete -> PASS       (fi-snb-2520m) fdo#103713

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

fi-bdw-5557u     total:288  pass:267  dwarn:0   dfail:0   fail:0   skip:21  time:420s
fi-bdw-gvtdvm    total:288  pass:264  dwarn:0   dfail:0   fail:0   skip:24  time:424s
fi-blb-e6850     total:288  pass:223  dwarn:1   dfail:0   fail:0   skip:64  time:372s
fi-bsw-n3050     total:288  pass:242  dwarn:0   dfail:0   fail:0   skip:46  time:486s
fi-bwr-2160      total:288  pass:183  dwarn:0   dfail:0   fail:0   skip:105 time:283s
fi-bxt-dsi       total:288  pass:258  dwarn:0   dfail:0   fail:0   skip:30  time:487s
fi-bxt-j4205     total:288  pass:259  dwarn:0   dfail:0   fail:0   skip:29  time:483s
fi-byt-j1900     total:288  pass:253  dwarn:0   dfail:0   fail:0   skip:35  time:479s
fi-byt-n2820     total:288  pass:249  dwarn:0   dfail:0   fail:0   skip:39  time:455s
fi-cfl-s2        total:288  pass:262  dwarn:0   dfail:0   fail:0   skip:26  time:567s
fi-elk-e7500     total:224  pass:168  dwarn:10  dfail:0   fail:0   skip:45 
fi-gdg-551       total:288  pass:179  dwarn:0   dfail:0   fail:1   skip:108 time:278s
fi-glk-1         total:288  pass:260  dwarn:0   dfail:0   fail:0   skip:28  time:512s
fi-hsw-4770      total:288  pass:261  dwarn:0   dfail:0   fail:0   skip:27  time:389s
fi-hsw-4770r     total:288  pass:261  dwarn:0   dfail:0   fail:0   skip:27  time:401s
fi-ilk-650       total:288  pass:228  dwarn:0   dfail:0   fail:0   skip:60  time:414s
fi-ivb-3520m     total:288  pass:259  dwarn:0   dfail:0   fail:0   skip:29  time:463s
fi-ivb-3770      total:288  pass:255  dwarn:0   dfail:0   fail:0   skip:33  time:419s
fi-kbl-7500u     total:288  pass:263  dwarn:1   dfail:0   fail:0   skip:24  time:456s
fi-kbl-7560u     total:288  pass:269  dwarn:0   dfail:0   fail:0   skip:19  time:500s
fi-kbl-7567u     total:288  pass:268  dwarn:0   dfail:0   fail:0   skip:20  time:453s
fi-kbl-r         total:288  pass:261  dwarn:0   dfail:0   fail:0   skip:27  time:503s
fi-pnv-d510      total:288  pass:222  dwarn:1   dfail:0   fail:0   skip:65  time:574s
fi-skl-6260u     total:288  pass:268  dwarn:0   dfail:0   fail:0   skip:20  time:432s
fi-skl-6600u     total:288  pass:261  dwarn:0   dfail:0   fail:0   skip:27  time:515s
fi-skl-6700hq    total:288  pass:262  dwarn:0   dfail:0   fail:0   skip:26  time:526s
fi-skl-6700k2    total:288  pass:264  dwarn:0   dfail:0   fail:0   skip:24  time:486s
fi-skl-6770hq    total:288  pass:268  dwarn:0   dfail:0   fail:0   skip:20  time:486s
fi-skl-guc       total:288  pass:260  dwarn:0   dfail:0   fail:0   skip:28  time:419s
fi-skl-gvtdvm    total:288  pass:265  dwarn:0   dfail:0   fail:0   skip:23  time:429s
fi-snb-2520m     total:288  pass:248  dwarn:0   dfail:0   fail:0   skip:40  time:533s
fi-snb-2600      total:288  pass:248  dwarn:0   dfail:0   fail:0   skip:40  time:403s

Blacklisted hosts:
fi-glk-dsi total:288 pass:258 dwarn:0 dfail:0 fail:0 skip:30 time:472s

9b156ad76b2e755bf527297486646cf27bbf1abd drm-tip: 2018y-01m-30d-17h-06m-58s UTC integration manifest ccef7ccc962b drm/i915/bxt, glk: Avoid long atomic poll during CDCLK change fc99e33b8ee3 drm/i915/bxt, glk: Increase PCODE timeouts during CDCLK freq changing

== Logs ==

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

#4 lore raw

✗ Fi.CI.IGT: failure for series starting with [v2,1/2] drm/i915/bxt, glk: Increase PCODE timeouts during CDCLK freq changing

In reply to Imre Deak
== Series Details ==

== Series Details ==

Series: series starting with [v2,1/2] drm/i915/bxt, glk: Increase PCODE timeouts during CDCLK freq changing
URL : https://patchwork.freedesktop.org/series/37344/
State : failure

== Summary ==

Test kms_rotation_crc:

        Subgroup sprite-rotation-180:
                pass       -> FAIL       (shard-apl)
Test kms_vblank:
        Subgroup pipe-b-ts-continuation-dpms-suspend:
                pass       -> INCOMPLETE (shard-hsw)
Test perf:
        Subgroup oa-exponents:
                fail       -> PASS       (shard-apl) fdo#102254
        Subgroup polling:
                fail       -> PASS       (shard-hsw) fdo#102252
Test kms_flip:
        Subgroup 2x-plain-flip-fb-recreate:
                fail       -> PASS       (shard-hsw) fdo#100368 +1
        Subgroup 2x-flip-vs-expired-vblank-interruptible:
                pass       -> FAIL       (shard-hsw) fdo#102887
Test kms_plane:
        Subgroup plane-panning-bottom-right-suspend-pipe-b-planes:
                dmesg-warn -> PASS       (shard-snb)
Test kms_cursor_legacy:
        Subgroup cursorb-vs-flipa-atomic:
                pass       -> SKIP       (shard-hsw)

fdo#102254 https://bugs.freedesktop.org/show_bug.cgi?id=102254
fdo#102252 https://bugs.freedesktop.org/show_bug.cgi?id=102252
fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368
fdo#102887 https://bugs.freedesktop.org/show_bug.cgi?id=102887

shard-apl        total:2838 pass:1750 dwarn:1   dfail:0   fail:23  skip:1064 time:12657s
shard-hsw        total:2826 pass:1726 dwarn:1   dfail:0   fail:11  skip:1086 time:11649s
shard-snb        total:2838 pass:1330 dwarn:1   dfail:0   fail:10  skip:1497 time:6619s

== Logs ==

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

author
#5 lore raw

Re: ✗ Fi.CI.IGT: failure for series starting with [v2,1/2] drm/i915/bxt, glk: Increase PCODE timeouts during CDCLK freq changing

Quoted 11 lines · Patchwork

== Series Details ==

Series: series starting with [v2,1/2] drm/i915/bxt, glk: Increase PCODE timeouts during CDCLK freq changing
URL : https://patchwork.freedesktop.org/series/37344/
State : failure

== Summary ==

Test kms_rotation_crc:

        Subgroup sprite-rotation-180:
                pass       -> FAIL       (shard-apl)

This is a CRC error, but without any pcode timeout, so not related. The rest of failures below are on unrelated platforms.

Thanks for the reviews, pushed both patches to -dinq.

Quoted 25 lines

Test kms_vblank:

        Subgroup pipe-b-ts-continuation-dpms-suspend:
                pass       -> INCOMPLETE (shard-hsw)
Test perf:
        Subgroup oa-exponents:
                fail       -> PASS       (shard-apl) fdo#102254
        Subgroup polling:
                fail       -> PASS       (shard-hsw) fdo#102252
Test kms_flip:
        Subgroup 2x-plain-flip-fb-recreate:
                fail       -> PASS       (shard-hsw) fdo#100368 +1
        Subgroup 2x-flip-vs-expired-vblank-interruptible:
                pass       -> FAIL       (shard-hsw) fdo#102887
Test kms_plane:
        Subgroup plane-panning-bottom-right-suspend-pipe-b-planes:
                dmesg-warn -> PASS       (shard-snb)
Test kms_cursor_legacy:
        Subgroup cursorb-vs-flipa-atomic:
                pass       -> SKIP       (shard-hsw)

fdo#102254 https://bugs.freedesktop.org/show_bug.cgi?id=102254
fdo#102252 https://bugs.freedesktop.org/show_bug.cgi?id=102252
fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368
fdo#102887 https://bugs.freedesktop.org/show_bug.cgi?id=102887

Quoted 7 lines
shard-apl        total:2838 pass:1750 dwarn:1   dfail:0   fail:23  skip:1064 time:12657s
shard-hsw        total:2826 pass:1726 dwarn:1   dfail:0   fail:11  skip:1086 time:11649s
shard-snb        total:2838 pass:1330 dwarn:1   dfail:0   fail:10  skip:1497 time:6619s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7823/shards.html

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

Reviewed-by on v2 1/2
#6 lore raw
In reply to Imre Deak
Quoted 22 lines · Imre Deak

Currently we see sporadic timeouts during CDCLK changing both on BXT and GLK as reported by the Bugzilla: ticket. It's easy to reproduce this by changing the frequency in a tight loop after blanking the display. The upper bound for the completion time is 800us based on my tests, so increase it from the current 500us to 2ms; with that I couldn't trigger the problem either on BXT or GLK.

Note that timeouts happened during both the change notification and the voltage level setting PCODE request. (For the latter one BSpec doesn't require us to wait for completion before further HW programming.)

This issue is similar to
2c7d0602c815 ("drm/i915/gen9: Fix PCODE polling during CDCLK change notification")
but there the PCODE request does complete (as shown by the mbox busy flag), only the reply we get from PCODE indicates a failure. So there we keep resending the request until a success reply, here we just have to increase the timeout for the one PCODE request we send.

v2:
- s/snb_pcode_request/sandybridge_pcode_write_timeout/ (Ville)

Quoted 6 lines

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

Quoted 90 lines
---
 drivers/gpu/drm/i915/i915_drv.h    |  6 +++++-
 drivers/gpu/drm/i915/intel_cdclk.c | 22 +++++++++++++++++-----
 drivers/gpu/drm/i915/intel_pm.c    |  6 +++---
 3 files changed, 25 insertions(+), 9 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +5 -1
index 454d8f937fae..7e83d0d3e632 100644
@@ -3723,7 +3723,11 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
 					    struct intel_display_error_state *error);
 
 int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
-int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
+int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv, u32 mbox,
+				    u32 val, int timeout_us);
+#define sandybridge_pcode_write(dev_priv, mbox, val)	\
+	sandybridge_pcode_write_timeout(dev_priv, mbox, val, 500)
+
 int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
 		      u32 reply_mask, u32 reply, int timeout_base_ms);
 
drivers/gpu/drm/i915/intel_cdclk.c +17 -5
index c4392ea34a3d..a423b674fcec 100644
@@ -1370,10 +1370,15 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 		break;
 	}
 
-	/* Inform power controller of upcoming frequency change */
+	/*
+	 * Inform power controller of upcoming frequency change. BSpec
+	 * requires us to wait up to 150usec, but that leads to timeouts;
+	 * the 2ms used here is based on experiment.
+	 */
 	mutex_lock(&dev_priv->pcu_lock);
-	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
-				      0x80000000);
+	ret = sandybridge_pcode_write_timeout(dev_priv,
+					      HSW_PCODE_DE_WRITE_FREQ_REQ,
+					      0x80000000, 2000);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	if (ret) {
@@ -1404,8 +1409,15 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 	I915_WRITE(CDCLK_CTL, val);
 
 	mutex_lock(&dev_priv->pcu_lock);
-	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
-				      cdclk_state->voltage_level);
+	/*
+	 * The timeout isn't specified, the 2ms used here is based on
+	 * experiment.
+	 * FIXME: Waiting for the request completion could be delayed until
+	 * the next PCODE request based on BSpec.
+	 */
+	ret = sandybridge_pcode_write_timeout(dev_priv,
+					      HSW_PCODE_DE_WRITE_FREQ_REQ,
+					      cdclk_state->voltage_level, 2000);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	if (ret) {
drivers/gpu/drm/i915/intel_pm.c +3 -3
index 0b92ea1dbd40..a6098932be5a 100644
@@ -9169,8 +9169,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
 	return 0;
 }
 
-int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
-			    u32 mbox, u32 val)
+int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv,
+				    u32 mbox, u32 val, int timeout_us)
 {
 	int status;
 
@@ -9193,7 +9193,7 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
 
 	if (__intel_wait_for_register_fw(dev_priv,
 					 GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
-					 500, 0, NULL)) {
+					 timeout_us, 0, NULL)) {
 		DRM_ERROR("timeout waiting for pcode write of 0x%08x to mbox %x to finish for %ps\n",
 			  val, mbox, __builtin_return_address(0));
 		return -ETIMEDOUT;
Signature · 1 line
2.13.2
Signature · 2 lines
Ville Syrjälä
Intel OTC