}
 }
 
-static bool broxton_phy_is_enabled(struct drm_i915_private *dev_priv,
-                                  enum dpio_phy phy)
+bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv,
+                           enum dpio_phy phy)
 {
        if (!(I915_READ(BXT_P_CR_GT_DISP_PWRON) & GT_DISPLAY_POWER_ON(phy)))
                return false;
                DRM_ERROR("timeout waiting for PHY%d GRC\n", phy);
 }
 
-static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv,
-                                    enum dpio_phy phy);
-
-static void broxton_phy_init(struct drm_i915_private *dev_priv,
-                            enum dpio_phy phy)
+void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy)
 {
        enum port port;
        u32 ports, val;
 
-       if (broxton_phy_is_enabled(dev_priv, phy)) {
+       if (bxt_ddi_phy_is_enabled(dev_priv, phy)) {
                /* Still read out the GRC value for state verification */
                if (phy == DPIO_PHY0)
                        dev_priv->bxt_phy_grc = broxton_get_grc(dev_priv, phy);
 
-               if (broxton_phy_verify_state(dev_priv, phy)) {
+               if (bxt_ddi_phy_verify_state(dev_priv, phy)) {
                        DRM_DEBUG_DRIVER("DDI PHY %d already enabled, "
                                         "won't reprogram it\n", phy);
 
 
                DRM_DEBUG_DRIVER("DDI PHY %d enabled with invalid state, "
                                 "force reprogramming it\n", phy);
-       } else {
-               DRM_DEBUG_DRIVER("DDI PHY %d not enabled, enabling it\n", phy);
        }
 
        val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
                broxton_phy_wait_grc_done(dev_priv, DPIO_PHY1);
 }
 
-void broxton_ddi_phy_init(struct drm_i915_private *dev_priv)
-{
-       /* Enable PHY1 first since it provides Rcomp for PHY0 */
-       broxton_phy_init(dev_priv, DPIO_PHY1);
-       broxton_phy_init(dev_priv, DPIO_PHY0);
-}
-
-static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
-                              enum dpio_phy phy)
+void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy)
 {
        uint32_t val;
 
        I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
 }
 
-void broxton_ddi_phy_uninit(struct drm_i915_private *dev_priv)
-{
-       broxton_phy_uninit(dev_priv, DPIO_PHY1);
-       broxton_phy_uninit(dev_priv, DPIO_PHY0);
-}
-
 static bool __printf(6, 7)
 __phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy,
                       i915_reg_t reg, u32 mask, u32 expected,
        return false;
 }
 
-static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv,
-                                    enum dpio_phy phy)
+bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv,
+                             enum dpio_phy phy)
 {
        enum port port;
        u32 ports;
        __phy_reg_verify_state(dev_priv, phy, reg, mask, exp, fmt,      \
                               ## __VA_ARGS__)
 
-       /* We expect the PHY to be always enabled */
-       if (!broxton_phy_is_enabled(dev_priv, phy))
+       if (!bxt_ddi_phy_is_enabled(dev_priv, phy))
                return false;
 
        ok = true;
 #undef _CHK
 }
 
-void broxton_ddi_phy_verify_state(struct drm_i915_private *dev_priv)
-{
-       if (!broxton_phy_verify_state(dev_priv, DPIO_PHY0) ||
-           !broxton_phy_verify_state(dev_priv, DPIO_PHY1))
-               i915_report_error(dev_priv, "DDI PHY state mismatch\n");
-}
-
 void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
 {
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 
 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)
 {
        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)
 {
        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)
 {
        gen9_assert_dbuf_enabled(dev_priv);
 
        if (IS_BROXTON(dev_priv))
-               broxton_ddi_phy_verify_state(dev_priv);
+               bxt_verify_ddi_phy_power_wells(dev_priv);
 }
 
 static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv,
        .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",
                .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
 
        gen9_dbuf_enable(dev_priv);
 
-       broxton_ddi_phy_init(dev_priv);
-
-       broxton_ddi_phy_verify_state(dev_priv);
-
        if (resume && dev_priv->csr.dmc_payload)
                intel_csr_load_program(dev_priv);
 }
 
        gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
 
-       broxton_ddi_phy_uninit(dev_priv);
-
        gen9_dbuf_disable(dev_priv);
 
        broxton_uninit_cdclk(dev_priv);