drm/i915: Convert dev_priv->dev backpointers to dev_priv->drm
[cascardo/linux.git] / drivers / gpu / drm / i915 / intel_runtime_pm.c
index 7fb1da4..6b78295 100644 (file)
@@ -65,6 +65,9 @@
 bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
                                    int power_well_id);
 
+static struct i915_power_well *
+lookup_power_well(struct drm_i915_private *dev_priv, int power_well_id);
+
 const char *
 intel_display_power_domain_str(enum intel_display_power_domain domain)
 {
@@ -151,6 +154,23 @@ static void intel_power_well_disable(struct drm_i915_private *dev_priv,
        power_well->ops->disable(dev_priv, power_well);
 }
 
+static void intel_power_well_get(struct drm_i915_private *dev_priv,
+                                struct i915_power_well *power_well)
+{
+       if (!power_well->count++)
+               intel_power_well_enable(dev_priv, power_well);
+}
+
+static void intel_power_well_put(struct drm_i915_private *dev_priv,
+                                struct i915_power_well *power_well)
+{
+       WARN(!power_well->count, "Use count on power well %s is already zero",
+            power_well->name);
+
+       if (!--power_well->count)
+               intel_power_well_disable(dev_priv, power_well);
+}
+
 /*
  * We should only use the power well if we explicitly asked the hardware to
  * enable it, so check if it's enabled and also check if we've requested it to
@@ -267,7 +287,7 @@ void intel_display_set_init_power(struct drm_i915_private *dev_priv,
  */
 static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = dev_priv->dev;
+       struct drm_device *dev = &dev_priv->drm;
 
        /*
         * After we re-enable the power well, if we touch VGA register 0x3d5
@@ -298,7 +318,7 @@ static void hsw_power_well_pre_disable(struct drm_i915_private *dev_priv)
 static void skl_power_well_post_enable(struct drm_i915_private *dev_priv,
                                       struct i915_power_well *power_well)
 {
-       struct drm_device *dev = dev_priv->dev;
+       struct drm_device *dev = &dev_priv->drm;
 
        /*
         * After we re-enable the power well, if we touch VGA register 0x3d5
@@ -345,8 +365,11 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
 
                if (!is_enabled) {
                        DRM_DEBUG_KMS("Enabling power well\n");
-                       if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) &
-                                     HSW_PWR_WELL_STATE_ENABLED), 20))
+                       if (intel_wait_for_register(dev_priv,
+                                                   HSW_PWR_WELL_DRIVER,
+                                                   HSW_PWR_WELL_STATE_ENABLED,
+                                                   HSW_PWR_WELL_STATE_ENABLED,
+                                                   20))
                                DRM_ERROR("Timeout enabling power well\n");
                        hsw_power_well_post_enable(dev_priv);
                }
@@ -419,6 +442,16 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
        BIT(POWER_DOMAIN_MODESET) |                     \
        BIT(POWER_DOMAIN_AUX_A) |                       \
        BIT(POWER_DOMAIN_INIT))
+#define BXT_DPIO_CMN_A_POWER_DOMAINS (                 \
+       BIT(POWER_DOMAIN_PORT_DDI_A_LANES) |            \
+       BIT(POWER_DOMAIN_AUX_A) |                       \
+       BIT(POWER_DOMAIN_INIT))
+#define BXT_DPIO_CMN_BC_POWER_DOMAINS (                        \
+       BIT(POWER_DOMAIN_PORT_DDI_B_LANES) |            \
+       BIT(POWER_DOMAIN_PORT_DDI_C_LANES) |            \
+       BIT(POWER_DOMAIN_AUX_B) |                       \
+       BIT(POWER_DOMAIN_AUX_C) |                       \
+       BIT(POWER_DOMAIN_INIT))
 
 static void assert_can_enable_dc9(struct drm_i915_private *dev_priv)
 {
@@ -548,6 +581,7 @@ void bxt_enable_dc9(struct drm_i915_private *dev_priv)
 
        DRM_DEBUG_KMS("Enabling DC9\n");
 
+       intel_power_sequencer_reset(dev_priv);
        gen9_set_dc_state(dev_priv, DC_STATE_EN_DC9);
 }
 
@@ -669,8 +703,11 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv,
 
        switch (power_well->data) {
        case SKL_DISP_PW_1:
-               if (wait_for((I915_READ(SKL_FUSE_STATUS) &
-                       SKL_FUSE_PG0_DIST_STATUS), 1)) {
+               if (intel_wait_for_register(dev_priv,
+                                           SKL_FUSE_STATUS,
+                                           SKL_FUSE_PG0_DIST_STATUS,
+                                           SKL_FUSE_PG0_DIST_STATUS,
+                                           1)) {
                        DRM_ERROR("PG0 not enabled\n");
                        return;
                }
@@ -731,12 +768,18 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv,
 
        if (check_fuse_status) {
                if (power_well->data == SKL_DISP_PW_1) {
-                       if (wait_for((I915_READ(SKL_FUSE_STATUS) &
-                               SKL_FUSE_PG1_DIST_STATUS), 1))
+                       if (intel_wait_for_register(dev_priv,
+                                                   SKL_FUSE_STATUS,
+                                                   SKL_FUSE_PG1_DIST_STATUS,
+                                                   SKL_FUSE_PG1_DIST_STATUS,
+                                                   1))
                                DRM_ERROR("PG1 distributing status timeout\n");
                } else if (power_well->data == SKL_DISP_PW_2) {
-                       if (wait_for((I915_READ(SKL_FUSE_STATUS) &
-                               SKL_FUSE_PG2_DIST_STATUS), 1))
+                       if (intel_wait_for_register(dev_priv,
+                                                   SKL_FUSE_STATUS,
+                                                   SKL_FUSE_PG2_DIST_STATUS,
+                                                   SKL_FUSE_PG2_DIST_STATUS,
+                                                   1))
                                DRM_ERROR("PG2 distributing status timeout\n");
                }
        }
@@ -800,21 +843,99 @@ static void skl_power_well_disable(struct drm_i915_private *dev_priv,
        skl_set_power_well(dev_priv, power_well, false);
 }
 
+static enum dpio_phy bxt_power_well_to_phy(struct i915_power_well *power_well)
+{
+       enum skl_disp_power_wells power_well_id = power_well->data;
+
+       return power_well_id == BXT_DPIO_CMN_A ? DPIO_PHY1 : DPIO_PHY0;
+}
+
+static void bxt_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
+                                          struct i915_power_well *power_well)
+{
+       enum skl_disp_power_wells power_well_id = power_well->data;
+       struct i915_power_well *cmn_a_well;
+
+       if (power_well_id == BXT_DPIO_CMN_BC) {
+               /*
+                * We need to copy the GRC calibration value from the eDP PHY,
+                * so make sure it's powered up.
+                */
+               cmn_a_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A);
+               intel_power_well_get(dev_priv, cmn_a_well);
+       }
+
+       bxt_ddi_phy_init(dev_priv, bxt_power_well_to_phy(power_well));
+
+       if (power_well_id == BXT_DPIO_CMN_BC)
+               intel_power_well_put(dev_priv, cmn_a_well);
+}
+
+static void bxt_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
+                                           struct i915_power_well *power_well)
+{
+       bxt_ddi_phy_uninit(dev_priv, bxt_power_well_to_phy(power_well));
+}
+
+static bool bxt_dpio_cmn_power_well_enabled(struct drm_i915_private *dev_priv,
+                                           struct i915_power_well *power_well)
+{
+       return bxt_ddi_phy_is_enabled(dev_priv,
+                                     bxt_power_well_to_phy(power_well));
+}
+
+static void bxt_dpio_cmn_power_well_sync_hw(struct drm_i915_private *dev_priv,
+                                           struct i915_power_well *power_well)
+{
+       if (power_well->count > 0)
+               bxt_dpio_cmn_power_well_enable(dev_priv, power_well);
+       else
+               bxt_dpio_cmn_power_well_disable(dev_priv, power_well);
+}
+
+
+static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv)
+{
+       struct i915_power_well *power_well;
+
+       power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A);
+       if (power_well->count > 0)
+               bxt_ddi_phy_verify_state(dev_priv,
+                                        bxt_power_well_to_phy(power_well));
+
+       power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_BC);
+       if (power_well->count > 0)
+               bxt_ddi_phy_verify_state(dev_priv,
+                                        bxt_power_well_to_phy(power_well));
+}
+
 static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv,
                                           struct i915_power_well *power_well)
 {
        return (I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5_DC6_MASK) == 0;
 }
 
+static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv)
+{
+       u32 tmp = I915_READ(DBUF_CTL);
+
+       WARN((tmp & (DBUF_POWER_STATE | DBUF_POWER_REQUEST)) !=
+            (DBUF_POWER_STATE | DBUF_POWER_REQUEST),
+            "Unexpected DBuf power power state (0x%08x)\n", tmp);
+}
+
 static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
                                          struct i915_power_well *power_well)
 {
        gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
 
-       if (IS_BROXTON(dev_priv)) {
-               broxton_cdclk_verify_state(dev_priv);
-               broxton_ddi_phy_verify_state(dev_priv);
-       }
+       WARN_ON(dev_priv->cdclk_freq !=
+               dev_priv->display.get_display_clock_speed(&dev_priv->drm));
+
+       gen9_assert_dbuf_enabled(dev_priv);
+
+       if (IS_BROXTON(dev_priv))
+               bxt_verify_ddi_phy_power_wells(dev_priv);
 }
 
 static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv,
@@ -948,6 +1069,11 @@ static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv)
         */
        I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE);
        I915_WRITE(CBR1_VLV, 0);
+
+       WARN_ON(dev_priv->rawclk_freq == 0);
+
+       I915_WRITE(RAWCLK_FREQ_VLV,
+                  DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 1000));
 }
 
 static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)
@@ -962,7 +1088,7 @@ static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)
         *
         * CHV DPLL B/C have some issues if VGA mode is enabled.
         */
-       for_each_pipe(dev_priv->dev, pipe) {
+       for_each_pipe(&dev_priv->drm, pipe) {
                u32 val = I915_READ(DPLL(pipe));
 
                val |= DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
@@ -987,7 +1113,7 @@ static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)
 
        intel_hpd_init(dev_priv);
 
-       i915_redisable_vga_power_on(dev_priv->dev);
+       i915_redisable_vga_power_on(&dev_priv->drm);
 }
 
 static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv)
@@ -997,9 +1123,9 @@ static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv)
        spin_unlock_irq(&dev_priv->irq_lock);
 
        /* make sure we're done processing display irqs */
-       synchronize_irq(dev_priv->dev->irq);
+       synchronize_irq(dev_priv->drm.irq);
 
-       vlv_power_sequencer_reset(dev_priv);
+       intel_power_sequencer_reset(dev_priv);
 }
 
 static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv,
@@ -1092,7 +1218,6 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
        u32 phy_control = dev_priv->chv_phy_control;
        u32 phy_status = 0;
        u32 phy_status_mask = 0xffffffff;
-       u32 tmp;
 
        /*
         * The BIOS can leave the PHY is some weird state
@@ -1180,10 +1305,14 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
         * The PHY may be busy with some initial calibration and whatnot,
         * so the power state can take a while to actually change.
         */
-       if (wait_for((tmp = I915_READ(DISPLAY_PHY_STATUS) & phy_status_mask) == phy_status, 10))
-               WARN(phy_status != tmp,
-                    "Unexpected PHY_STATUS 0x%08x, expected 0x%08x (PHY_CONTROL=0x%08x)\n",
-                    tmp, phy_status, dev_priv->chv_phy_control);
+       if (intel_wait_for_register(dev_priv,
+                                   DISPLAY_PHY_STATUS,
+                                   phy_status_mask,
+                                   phy_status,
+                                   10))
+               DRM_ERROR("Unexpected PHY_STATUS 0x%08x, expected 0x%08x (PHY_CONTROL=0x%08x)\n",
+                         I915_READ(DISPLAY_PHY_STATUS) & phy_status_mask,
+                          phy_status, dev_priv->chv_phy_control);
 }
 
 #undef BITS_SET
@@ -1211,7 +1340,11 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
        vlv_set_power_well(dev_priv, power_well, true);
 
        /* Poll for phypwrgood signal */
-       if (wait_for(I915_READ(DISPLAY_PHY_STATUS) & PHY_POWERGOOD(phy), 1))
+       if (intel_wait_for_register(dev_priv,
+                                   DISPLAY_PHY_STATUS,
+                                   PHY_POWERGOOD(phy),
+                                   PHY_POWERGOOD(phy),
+                                   1))
                DRM_ERROR("Display PHY %d is not power up\n", phy);
 
        mutex_lock(&dev_priv->sb_lock);
@@ -1501,10 +1634,8 @@ __intel_display_power_get_domain(struct drm_i915_private *dev_priv,
        struct i915_power_well *power_well;
        int i;
 
-       for_each_power_well(i, power_well, BIT(domain), power_domains) {
-               if (!power_well->count++)
-                       intel_power_well_enable(dev_priv, power_well);
-       }
+       for_each_power_well(i, power_well, BIT(domain), power_domains)
+               intel_power_well_get(dev_priv, power_well);
 
        power_domains->domain_use_count[domain]++;
 }
@@ -1598,14 +1729,8 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
             intel_display_power_domain_str(domain));
        power_domains->domain_use_count[domain]--;
 
-       for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
-               WARN(!power_well->count,
-                    "Use count on power well %s is already zero",
-                    power_well->name);
-
-               if (!--power_well->count)
-                       intel_power_well_disable(dev_priv, power_well);
-       }
+       for_each_power_well_rev(i, power_well, BIT(domain), power_domains)
+               intel_power_well_put(dev_priv, power_well);
 
        mutex_unlock(&power_domains->lock);
 
@@ -1776,6 +1901,13 @@ static const struct i915_power_well_ops gen9_dc_off_power_well_ops = {
        .is_enabled = gen9_dc_off_power_well_enabled,
 };
 
+static const struct i915_power_well_ops bxt_dpio_cmn_power_well_ops = {
+       .sync_hw = bxt_dpio_cmn_power_well_sync_hw,
+       .enable = bxt_dpio_cmn_power_well_enable,
+       .disable = bxt_dpio_cmn_power_well_disable,
+       .is_enabled = bxt_dpio_cmn_power_well_enabled,
+};
+
 static struct i915_power_well hsw_power_wells[] = {
        {
                .name = "always-on",
@@ -2012,6 +2144,18 @@ static struct i915_power_well bxt_power_wells[] = {
                .ops = &skl_power_well_ops,
                .data = SKL_DISP_PW_2,
        },
+       {
+               .name = "dpio-common-a",
+               .domains = BXT_DPIO_CMN_A_POWER_DOMAINS,
+               .ops = &bxt_dpio_cmn_power_well_ops,
+               .data = BXT_DPIO_CMN_A,
+       },
+       {
+               .name = "dpio-common-bc",
+               .domains = BXT_DPIO_CMN_BC_POWER_DOMAINS,
+               .ops = &bxt_dpio_cmn_power_well_ops,
+               .data = BXT_DPIO_CMN_BC,
+       },
 };
 
 static int
@@ -2131,7 +2275,7 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
  */
 void intel_power_domains_fini(struct drm_i915_private *dev_priv)
 {
-       struct device *device = &dev_priv->dev->pdev->dev;
+       struct device *device = &dev_priv->drm.pdev->dev;
 
        /*
         * The i915.ko module is still not prepared to be loaded when
@@ -2171,6 +2315,28 @@ static void intel_power_domains_sync_hw(struct drm_i915_private *dev_priv)
        mutex_unlock(&power_domains->lock);
 }
 
+static void gen9_dbuf_enable(struct drm_i915_private *dev_priv)
+{
+       I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) | DBUF_POWER_REQUEST);
+       POSTING_READ(DBUF_CTL);
+
+       udelay(10);
+
+       if (!(I915_READ(DBUF_CTL) & DBUF_POWER_STATE))
+               DRM_ERROR("DBuf power enable timeout\n");
+}
+
+static void gen9_dbuf_disable(struct drm_i915_private *dev_priv)
+{
+       I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) & ~DBUF_POWER_REQUEST);
+       POSTING_READ(DBUF_CTL);
+
+       udelay(10);
+
+       if (I915_READ(DBUF_CTL) & DBUF_POWER_STATE)
+               DRM_ERROR("DBuf power disable timeout!\n");
+}
+
 static void skl_display_core_init(struct drm_i915_private *dev_priv,
                                   bool resume)
 {
@@ -2195,12 +2361,11 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv,
 
        mutex_unlock(&power_domains->lock);
 
-       if (!resume)
-               return;
-
        skl_init_cdclk(dev_priv);
 
-       if (dev_priv->csr.dmc_payload)
+       gen9_dbuf_enable(dev_priv);
+
+       if (resume && dev_priv->csr.dmc_payload)
                intel_csr_load_program(dev_priv);
 }
 
@@ -2211,6 +2376,8 @@ static void skl_display_core_uninit(struct drm_i915_private *dev_priv)
 
        gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
 
+       gen9_dbuf_disable(dev_priv);
+
        skl_uninit_cdclk(dev_priv);
 
        /* The spec doesn't call for removing the reset handshake flag */
@@ -2254,11 +2421,9 @@ void bxt_display_core_init(struct drm_i915_private *dev_priv,
 
        mutex_unlock(&power_domains->lock);
 
-       broxton_init_cdclk(dev_priv);
-       broxton_ddi_phy_init(dev_priv);
+       bxt_init_cdclk(dev_priv);
 
-       broxton_cdclk_verify_state(dev_priv);
-       broxton_ddi_phy_verify_state(dev_priv);
+       gen9_dbuf_enable(dev_priv);
 
        if (resume && dev_priv->csr.dmc_payload)
                intel_csr_load_program(dev_priv);
@@ -2271,8 +2436,9 @@ void bxt_display_core_uninit(struct drm_i915_private *dev_priv)
 
        gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
 
-       broxton_ddi_phy_uninit(dev_priv);
-       broxton_uninit_cdclk(dev_priv);
+       gen9_dbuf_disable(dev_priv);
+
+       bxt_uninit_cdclk(dev_priv);
 
        /* The spec doesn't call for removing the reset handshake flag */
 
@@ -2403,13 +2569,14 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv)
 /**
  * intel_power_domains_init_hw - initialize hardware power domain state
  * @dev_priv: i915 device instance
+ * @resume: Called from resume code paths or not
  *
  * This function initializes the hardware power domain state and enables all
  * power domains using intel_display_set_init_power().
  */
 void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume)
 {
-       struct drm_device *dev = dev_priv->dev;
+       struct drm_device *dev = &dev_priv->drm;
        struct i915_power_domains *power_domains = &dev_priv->power_domains;
 
        power_domains->initializing = true;
@@ -2471,7 +2638,7 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv)
  */
 void intel_runtime_pm_get(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = dev_priv->dev;
+       struct drm_device *dev = &dev_priv->drm;
        struct device *device = &dev->pdev->dev;
 
        pm_runtime_get_sync(device);
@@ -2492,7 +2659,7 @@ void intel_runtime_pm_get(struct drm_i915_private *dev_priv)
  */
 bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = dev_priv->dev;
+       struct drm_device *dev = &dev_priv->drm;
        struct device *device = &dev->pdev->dev;
 
        if (IS_ENABLED(CONFIG_PM)) {
@@ -2534,7 +2701,7 @@ bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv)
  */
 void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = dev_priv->dev;
+       struct drm_device *dev = &dev_priv->drm;
        struct device *device = &dev->pdev->dev;
 
        assert_rpm_wakelock_held(dev_priv);
@@ -2553,7 +2720,7 @@ void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv)
  */
 void intel_runtime_pm_put(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = dev_priv->dev;
+       struct drm_device *dev = &dev_priv->drm;
        struct device *device = &dev->pdev->dev;
 
        assert_rpm_wakelock_held(dev_priv);
@@ -2576,7 +2743,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv)
  */
 void intel_runtime_pm_enable(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = dev_priv->dev;
+       struct drm_device *dev = &dev_priv->drm;
        struct device *device = &dev->pdev->dev;
 
        pm_runtime_set_autosuspend_delay(device, 10000); /* 10s */