aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2017-12-21 15:24:32 -0500
committerVille Syrjälä <ville.syrjala@linux.intel.com>2017-12-22 07:23:14 -0500
commit6481d5ed076e69db83ca75e751ad492a6fb669a7 (patch)
tree36f3bcdb8b12ab730302e4ac1fccbd0b4b2bc872 /drivers
parentad8059cf2e33042be31b09d44fd3e61ac9c50219 (diff)
drm/i915: Disable GMBUS clock gating around GMBUS transfers on gen9+
Gen9+ need to disable GMBUS clock gating when doing multi part transfers. Otherwise clock gating will kick in when GMBUS is in the WAIT state and presumably that will corrupt the transfer. This is documented as Display WA #0868. Apparently older hardware doesn't allow clock gating in the WAIT state and thus are unaffected by this problem. v2: Limit the PCH w/a to gen9 and gen10 only (DK) Actually change it to check the PCH type instead since it's the PCH that actually contains the GMBUS hardware Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com> #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20171221202432.17373-1-ville.syrjala@linux.intel.com
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h4
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c40
2 files changed, 44 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index fb05849eabab..41285bec8fc0 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3859,6 +3859,9 @@ enum {
3859#define PWM2_GATING_DIS (1 << 14) 3859#define PWM2_GATING_DIS (1 << 14)
3860#define PWM1_GATING_DIS (1 << 13) 3860#define PWM1_GATING_DIS (1 << 13)
3861 3861
3862#define GEN9_CLKGATE_DIS_4 _MMIO(0x4653C)
3863#define BXT_GMBUS_GATING_DIS (1 << 14)
3864
3862#define _CLKGATE_DIS_PSL_A 0x46520 3865#define _CLKGATE_DIS_PSL_A 0x46520
3863#define _CLKGATE_DIS_PSL_B 0x46524 3866#define _CLKGATE_DIS_PSL_B 0x46524
3864#define _CLKGATE_DIS_PSL_C 0x46528 3867#define _CLKGATE_DIS_PSL_C 0x46528
@@ -7557,6 +7560,7 @@ enum {
7557#define FDI_RX_CHICKEN(pipe) _MMIO_PIPE(pipe, _FDI_RXA_CHICKEN, _FDI_RXB_CHICKEN) 7560#define FDI_RX_CHICKEN(pipe) _MMIO_PIPE(pipe, _FDI_RXA_CHICKEN, _FDI_RXB_CHICKEN)
7558 7561
7559#define SOUTH_DSPCLK_GATE_D _MMIO(0xc2020) 7562#define SOUTH_DSPCLK_GATE_D _MMIO(0xc2020)
7563#define PCH_GMBUSUNIT_CLOCK_GATE_DISABLE (1<<31)
7560#define PCH_DPLUNIT_CLOCK_GATE_DISABLE (1<<30) 7564#define PCH_DPLUNIT_CLOCK_GATE_DISABLE (1<<30)
7561#define PCH_DPLSUNIT_CLOCK_GATE_DISABLE (1<<29) 7565#define PCH_DPLSUNIT_CLOCK_GATE_DISABLE (1<<29)
7562#define PCH_CPUNIT_CLOCK_GATE_DISABLE (1<<14) 7566#define PCH_CPUNIT_CLOCK_GATE_DISABLE (1<<14)
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index a8c08994f505..ef9f91a0b0c9 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -142,6 +142,32 @@ static void pnv_gmbus_clock_gating(struct drm_i915_private *dev_priv,
142 I915_WRITE(DSPCLK_GATE_D, val); 142 I915_WRITE(DSPCLK_GATE_D, val);
143} 143}
144 144
145static void pch_gmbus_clock_gating(struct drm_i915_private *dev_priv,
146 bool enable)
147{
148 u32 val;
149
150 val = I915_READ(SOUTH_DSPCLK_GATE_D);
151 if (!enable)
152 val |= PCH_GMBUSUNIT_CLOCK_GATE_DISABLE;
153 else
154 val &= ~PCH_GMBUSUNIT_CLOCK_GATE_DISABLE;
155 I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
156}
157
158static void bxt_gmbus_clock_gating(struct drm_i915_private *dev_priv,
159 bool enable)
160{
161 u32 val;
162
163 val = I915_READ(GEN9_CLKGATE_DIS_4);
164 if (!enable)
165 val |= BXT_GMBUS_GATING_DIS;
166 else
167 val &= ~BXT_GMBUS_GATING_DIS;
168 I915_WRITE(GEN9_CLKGATE_DIS_4, val);
169}
170
145static u32 get_reserved(struct intel_gmbus *bus) 171static u32 get_reserved(struct intel_gmbus *bus)
146{ 172{
147 struct drm_i915_private *dev_priv = bus->dev_priv; 173 struct drm_i915_private *dev_priv = bus->dev_priv;
@@ -484,6 +510,13 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
484 int i = 0, inc, try = 0; 510 int i = 0, inc, try = 0;
485 int ret = 0; 511 int ret = 0;
486 512
513 /* Display WA #0868: skl,bxt,kbl,cfl,glk,cnl */
514 if (IS_GEN9_LP(dev_priv))
515 bxt_gmbus_clock_gating(dev_priv, false);
516 else if (HAS_PCH_SPT(dev_priv) ||
517 HAS_PCH_KBP(dev_priv) || HAS_PCH_CNP(dev_priv))
518 pch_gmbus_clock_gating(dev_priv, false);
519
487retry: 520retry:
488 I915_WRITE_FW(GMBUS0, bus->reg0); 521 I915_WRITE_FW(GMBUS0, bus->reg0);
489 522
@@ -585,6 +618,13 @@ timeout:
585 ret = -EAGAIN; 618 ret = -EAGAIN;
586 619
587out: 620out:
621 /* Display WA #0868: skl,bxt,kbl,cfl,glk,cnl */
622 if (IS_GEN9_LP(dev_priv))
623 bxt_gmbus_clock_gating(dev_priv, true);
624 else if (HAS_PCH_SPT(dev_priv) ||
625 HAS_PCH_KBP(dev_priv) || HAS_PCH_CNP(dev_priv))
626 pch_gmbus_clock_gating(dev_priv, true);
627
588 return ret; 628 return ret;
589} 629}
590 630