drm/i915/cnl: apply Display WA #1178 to fix type C dongles
authorLucas De Marchi <lucas.demarchi@intel.com>
Tue, 28 Nov 2017 22:05:53 +0000 (14:05 -0800)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 18 Jan 2018 19:45:08 +0000 (11:45 -0800)
Display WA #1178 is meant to fix Aux channel voltage swing too low with
some type C dongles. Although it is for type C, HW engineers reported
that it can be applied to all external ports even if they are not going
to type C.

For CNL we apply the workaround every time Aux B, C and D are powering
up since they will lose the configuration when powered down.

v2: Use common tag for WA

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Arthur J Runyan <arthur.j.runyan@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171128220553.22435-1-lucas.demarchi@intel.com
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_runtime_pm.c

index a2108e35c599982831cab1eab39c6b6721af1d80..3ed5d49aa46d4e3f109e405358065930bc487b7e 100644 (file)
@@ -8350,6 +8350,17 @@ enum skl_power_gate {
 #define  SKL_PW_TO_PG(pw)                      ((pw) - SKL_DISP_PW_1 + SKL_PG1)
 #define  SKL_FUSE_PG_DIST_STATUS(pg)           (1 << (27 - (pg)))
 
+#define _CNL_AUX_REG_IDX(pw)           ((pw - 1) >> 4)
+#define _CNL_AUX_ANAOVRD1_B            0x162250
+#define _CNL_AUX_ANAOVRD1_C            0x162210
+#define _CNL_AUX_ANAOVRD1_D            0x1622D0
+#define CNL_AUX_ANAOVRD1(pw)           _MMIO(_PICK(_CNL_AUX_REG_IDX(pw), \
+                                                   _CNL_AUX_ANAOVRD1_B, \
+                                                   _CNL_AUX_ANAOVRD1_C, \
+                                                   _CNL_AUX_ANAOVRD1_D))
+#define   CNL_AUX_ANAOVRD1_ENABLE      (1<<16)
+#define   CNL_AUX_ANAOVRD1_LDO_BYPASS  (1<<23)
+
 /* Per-pipe DDI Function Control */
 #define _TRANS_DDI_FUNC_CTL_A          0x60400
 #define _TRANS_DDI_FUNC_CTL_B          0x61400
index 4996c4ea8a80cbed07360490940d036e787607ed..5b1aa4b9c72c61ab860fba22554392c69ab33d6e 100644 (file)
@@ -390,6 +390,15 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
        I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), val | HSW_PWR_WELL_CTL_REQ(id));
        hsw_wait_for_power_well_enable(dev_priv, power_well);
 
+       /* Display WA #1178: cnl */
+       if (IS_CANNONLAKE(dev_priv) &&
+           (id == CNL_DISP_PW_AUX_B || id == CNL_DISP_PW_AUX_C ||
+            id == CNL_DISP_PW_AUX_D)) {
+               val = I915_READ(CNL_AUX_ANAOVRD1(id));
+               val |= CNL_AUX_ANAOVRD1_ENABLE | CNL_AUX_ANAOVRD1_LDO_BYPASS;
+               I915_WRITE(CNL_AUX_ANAOVRD1(id), val);
+       }
+
        if (wait_fuses)
                gen9_wait_for_power_well_fuses(dev_priv, pg);