drm/i915: Assert that VED and ISP are power gated
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 29 Nov 2018 17:55:04 +0000 (19:55 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 13 Feb 2019 16:43:50 +0000 (18:43 +0200)
As there are no upstream drivers for VED or ISP let's just
assert that they are power gated. Otherwise they would
prevent s0ix entry.

For ISP this is only relevant when it is not exposed as a
PCI device and instead is a subordinate of the gunit. When
exposed as a PCI device it will be handled by the
atomisp2_pm driver.

On my VLV FFRD8 board the firmware power gates both of these
by default. Let's assume that is always the case and just
WARN if we ever encounter something different.

Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Alan Cox <alan@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181129175504.3630-2-ville.syrjala@linux.intel.com
Reviewed-by: Imre Deak <imre.deak@intel.com>
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_runtime_pm.c

index 1a07bce0bd229badf57f817ddb9bf3cc7c70cd2d..0df8c6e76da77b41ec3ec71cfbf50fda18e2bb50 100644 (file)
@@ -1044,6 +1044,31 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
 /* See configdb bunit SB addr map */
 #define BUNIT_REG_BISOC                                0x11
 
+/* PUNIT_REG_*SSPM0 */
+#define   _SSPM0_SSC(val)                      ((val) << 0)
+#define   SSPM0_SSC_MASK                       _SSPM0_SSC(0x3)
+#define   SSPM0_SSC_PWR_ON                     _SSPM0_SSC(0x0)
+#define   SSPM0_SSC_CLK_GATE                   _SSPM0_SSC(0x1)
+#define   SSPM0_SSC_RESET                      _SSPM0_SSC(0x2)
+#define   SSPM0_SSC_PWR_GATE                   _SSPM0_SSC(0x3)
+#define   _SSPM0_SSS(val)                      ((val) << 24)
+#define   SSPM0_SSS_MASK                       _SSPM0_SSS(0x3)
+#define   SSPM0_SSS_PWR_ON                     _SSPM0_SSS(0x0)
+#define   SSPM0_SSS_CLK_GATE                   _SSPM0_SSS(0x1)
+#define   SSPM0_SSS_RESET                      _SSPM0_SSS(0x2)
+#define   SSPM0_SSS_PWR_GATE                   _SSPM0_SSS(0x3)
+
+/* PUNIT_REG_*SSPM1 */
+#define   SSPM1_FREQSTAT_SHIFT                 24
+#define   SSPM1_FREQSTAT_MASK                  (0x1f << SSPM1_FREQSTAT_SHIFT)
+#define   SSPM1_FREQGUAR_SHIFT                 8
+#define   SSPM1_FREQGUAR_MASK                  (0x1f << SSPM1_FREQGUAR_SHIFT)
+#define   SSPM1_FREQ_SHIFT                     0
+#define   SSPM1_FREQ_MASK                      (0x1f << SSPM1_FREQ_SHIFT)
+
+#define PUNIT_REG_VEDSSPM0                     0x32
+#define PUNIT_REG_VEDSSPM1                     0x33
+
 #define PUNIT_REG_DSPSSPM                      0x36
 #define   DSPFREQSTAT_SHIFT_CHV                        24
 #define   DSPFREQSTAT_MASK_CHV                 (0x1f << DSPFREQSTAT_SHIFT_CHV)
@@ -1069,6 +1094,9 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
 #define   DP_SSS_RESET(pipe)                   _DP_SSS(0x2, (pipe))
 #define   DP_SSS_PWR_GATE(pipe)                        _DP_SSS(0x3, (pipe))
 
+#define PUNIT_REG_ISPSSPM0                     0x39
+#define PUNIT_REG_ISPSSPM1                     0x3a
+
 /*
  * i915_power_well_id:
  *
index 2d8673150c44122674821ef4645b36b1bab9a00c..aa974b11928a09e051b9fae7bae67cbc80726998 100644 (file)
@@ -3993,6 +3993,36 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv)
        cmn->desc->ops->disable(dev_priv, cmn);
 }
 
+static bool vlv_punit_is_power_gated(struct drm_i915_private *dev_priv, u32 reg0)
+{
+       bool ret;
+
+       mutex_lock(&dev_priv->pcu_lock);
+       ret = (vlv_punit_read(dev_priv, reg0) & SSPM0_SSC_MASK) == SSPM0_SSC_PWR_GATE;
+       mutex_unlock(&dev_priv->pcu_lock);
+
+       return ret;
+}
+
+static void assert_ved_power_gated(struct drm_i915_private *dev_priv)
+{
+       WARN(!vlv_punit_is_power_gated(dev_priv, PUNIT_REG_VEDSSPM0),
+            "VED not power gated\n");
+}
+
+static void assert_isp_power_gated(struct drm_i915_private *dev_priv)
+{
+       static const struct pci_device_id isp_ids[] = {
+               {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0f38)},
+               {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x22b8)},
+               {}
+       };
+
+       WARN(!pci_dev_present(isp_ids) &&
+            !vlv_punit_is_power_gated(dev_priv, PUNIT_REG_ISPSSPM0),
+            "ISP not power gated\n");
+}
+
 static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv);
 
 /**
@@ -4029,10 +4059,13 @@ void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume)
                mutex_lock(&power_domains->lock);
                chv_phy_control_init(i915);
                mutex_unlock(&power_domains->lock);
+               assert_isp_power_gated(i915);
        } else if (IS_VALLEYVIEW(i915)) {
                mutex_lock(&power_domains->lock);
                vlv_cmnlane_wa(i915);
                mutex_unlock(&power_domains->lock);
+               assert_ved_power_gated(i915);
+               assert_isp_power_gated(i915);
        } else if (IS_IVYBRIDGE(i915) || INTEL_GEN(i915) >= 7) {
                intel_pch_reset_handshake(i915, !HAS_PCH_NOP(i915));
        }