OSDN Git Service

drm/i915/icl: implement the display init/uninit sequences
authorPaulo Zanoni <paulo.r.zanoni@intel.com>
Mon, 5 Feb 2018 15:40:43 +0000 (13:40 -0200)
committerPaulo Zanoni <paulo.r.zanoni@intel.com>
Tue, 13 Feb 2018 12:17:10 +0000 (10:17 -0200)
This code is similar enough to the CNL code that I considered just
adding ICL support to the CNL function, but I think it's still
different enough, and having a function specific to ICL allows us to
more easily adapt code in case the spec changes more later.

We're still missing the power wells and the mbus code, so leave those
pieces with a FIXME comment while they're not here yet.

v2: Don't use _PICK, don't WARN_ON(1), don't forget the chicken bits.
v3: Use _MMIO_PORT() (Ville).

Reviewed-by: James Ausmus <james.ausmus@intel.com> (v2)
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180205154046.11485-4-paulo.r.zanoni@intel.com
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_runtime_pm.c

index 76542f7..f503743 100644 (file)
@@ -1906,6 +1906,11 @@ enum i915_power_well_id {
 #define   CL_POWER_DOWN_ENABLE         (1 << 4)
 #define   SUS_CLOCK_CONFIG             (3 << 0)
 
+#define _ICL_PORT_CL_DW5_A     0x162014
+#define _ICL_PORT_CL_DW5_B     0x6C014
+#define ICL_PORT_CL_DW5(port)  _MMIO_PORT(port, _ICL_PORT_CL_DW5_A, \
+                                                _ICL_PORT_CL_DW5_B)
+
 #define _PORT_CL1CM_DW9_A              0x162024
 #define _PORT_CL1CM_DW9_BC             0x6C024
 #define   IREF0RC_OFFSET_SHIFT         8
@@ -7168,8 +7173,9 @@ enum {
 #define  RESET_PCH_HANDSHAKE_ENABLE    (1<<4)
 
 #define GEN8_CHICKEN_DCPR_1            _MMIO(0x46430)
-#define   SKL_SELECT_ALTERNATE_DC_EXIT (1<<30)
-#define   MASK_WAKEMEM                 (1<<13)
+#define   SKL_SELECT_ALTERNATE_DC_EXIT (1 << 30)
+#define   MASK_WAKEMEM                 (1 << 13)
+#define   CNL_DDI_CLOCK_REG_ACCESS_ON  (1 << 7)
 
 #define SKL_DFSM                       _MMIO(0x51000)
 #define SKL_DFSM_CDCLK_LIMIT_MASK      (3 << 23)
@@ -9658,4 +9664,10 @@ enum skl_power_gate {
 #define  MMCD_PCLA             (1 << 31)
 #define  MMCD_HOTSPOT_EN       (1 << 27)
 
+#define _ICL_PHY_MISC_A                0x64C00
+#define _ICL_PHY_MISC_B                0x64C04
+#define ICL_PHY_MISC(port)     _MMIO_PORT(port, _ICL_PHY_MISC_A, \
+                                                _ICL_PHY_MISC_B)
+#define  ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN      (1 << 23)
+
 #endif /* _I915_REG_H_ */
index b4ef787..c432a66 100644 (file)
@@ -2919,6 +2919,80 @@ static void cnl_display_core_uninit(struct drm_i915_private *dev_priv)
        I915_WRITE(CHICKEN_MISC_2, val);
 }
 
+static void icl_display_core_init(struct drm_i915_private *dev_priv,
+                                 bool resume)
+{
+       enum port port;
+       u32 val;
+
+       gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+
+       /* 1. Enable PCH reset handshake. */
+       val = I915_READ(HSW_NDE_RSTWRN_OPT);
+       val |= RESET_PCH_HANDSHAKE_ENABLE;
+       I915_WRITE(HSW_NDE_RSTWRN_OPT, val);
+
+       for (port = PORT_A; port <= PORT_B; port++) {
+               /* 2. Enable DDI combo PHY comp. */
+               val = I915_READ(ICL_PHY_MISC(port));
+               val &= ~ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
+               I915_WRITE(ICL_PHY_MISC(port), val);
+
+               cnl_set_procmon_ref_values(dev_priv, port);
+
+               val = I915_READ(ICL_PORT_COMP_DW0(port));
+               val |= COMP_INIT;
+               I915_WRITE(ICL_PORT_COMP_DW0(port), val);
+
+               /* 3. Set power down enable. */
+               val = I915_READ(ICL_PORT_CL_DW5(port));
+               val |= CL_POWER_DOWN_ENABLE;
+               I915_WRITE(ICL_PORT_CL_DW5(port), val);
+       }
+
+       /* 4. Enable power well 1 (PG1) and aux IO power. */
+       /* FIXME: ICL power wells code not here yet. */
+
+       /* 5. Enable CDCLK. */
+       icl_init_cdclk(dev_priv);
+
+       /* 6. Enable DBUF. */
+       gen9_dbuf_enable(dev_priv);
+
+       /* 7. Setup MBUS. */
+       /* FIXME: MBUS code not here yet. */
+
+       /* 8. CHICKEN_DCPR_1 */
+       I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) |
+                                       CNL_DDI_CLOCK_REG_ACCESS_ON);
+}
+
+static void icl_display_core_uninit(struct drm_i915_private *dev_priv)
+{
+       enum port port;
+       u32 val;
+
+       gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+
+       /* 1. Disable all display engine functions -> aready done */
+
+       /* 2. Disable DBUF */
+       gen9_dbuf_disable(dev_priv);
+
+       /* 3. Disable CD clock */
+       icl_uninit_cdclk(dev_priv);
+
+       /* 4. Disable Power Well 1 (PG1) and Aux IO Power */
+       /* FIXME: ICL power wells code not here yet. */
+
+       /* 5. Disable Comp */
+       for (port = PORT_A; port <= PORT_B; port++) {
+               val = I915_READ(ICL_PHY_MISC(port));
+               val |= ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
+               I915_WRITE(ICL_PHY_MISC(port), val);
+       }
+}
+
 static void chv_phy_control_init(struct drm_i915_private *dev_priv)
 {
        struct i915_power_well *cmn_bc =
@@ -3051,7 +3125,9 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume)
 
        power_domains->initializing = true;
 
-       if (IS_CANNONLAKE(dev_priv)) {
+       if (IS_ICELAKE(dev_priv)) {
+               icl_display_core_init(dev_priv, resume);
+       } else if (IS_CANNONLAKE(dev_priv)) {
                cnl_display_core_init(dev_priv, resume);
        } else if (IS_GEN9_BC(dev_priv)) {
                skl_display_core_init(dev_priv, resume);
@@ -3092,7 +3168,9 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv)
        if (!i915_modparams.disable_power_well)
                intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
 
-       if (IS_CANNONLAKE(dev_priv))
+       if (IS_ICELAKE(dev_priv))
+               icl_display_core_uninit(dev_priv);
+       else if (IS_CANNONLAKE(dev_priv))
                cnl_display_core_uninit(dev_priv);
        else if (IS_GEN9_BC(dev_priv))
                skl_display_core_uninit(dev_priv);