aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_runtime_pm.c
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2016-06-13 09:44:34 -0400
committerImre Deak <imre.deak@intel.com>2016-06-13 11:46:08 -0400
commit9c8d0b8e53b902daeb3622c722b9337a78db724a (patch)
treeca4b5682bd4988eb07311f7e1ba8e5fe5c534932 /drivers/gpu/drm/i915/intel_runtime_pm.c
parentb409ca9587cb62fc066841f457b73a1f92e136ee (diff)
drm/i915/bxt: Move DDI PHY enabling/disabling to the power well code
So far we depended on the HW to dynamically power down unused PHYs and so we enabled them manually once during driver loading/resuming. There are indications however that we can achieve better power savings by manual powering toggling. So make the PHY enabling/disabling to happen on-demand whenever we need either the corresponding AUX or port functionality. CHV does this already by enabling the PHY along the corresponding PHY common lane power wells there, do the same on BXT by adding virtual power wells for the same purpose. Also sanity check the common lane power down ack signal from the PHY. Do this only when the PHY is enabled, since it's not clear at what point the HW power/clock gates things. While at it rename broxton_ prefix to bxt_ in related function names to better align with the SKL code. Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c106
1 files changed, 99 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 10978cb87700..7e91881726a8 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -65,6 +65,9 @@
65bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, 65bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
66 int power_well_id); 66 int power_well_id);
67 67
68static struct i915_power_well *
69lookup_power_well(struct drm_i915_private *dev_priv, int power_well_id);
70
68const char * 71const char *
69intel_display_power_domain_str(enum intel_display_power_domain domain) 72intel_display_power_domain_str(enum intel_display_power_domain domain)
70{ 73{
@@ -436,6 +439,16 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
436 BIT(POWER_DOMAIN_MODESET) | \ 439 BIT(POWER_DOMAIN_MODESET) | \
437 BIT(POWER_DOMAIN_AUX_A) | \ 440 BIT(POWER_DOMAIN_AUX_A) | \
438 BIT(POWER_DOMAIN_INIT)) 441 BIT(POWER_DOMAIN_INIT))
442#define BXT_DPIO_CMN_A_POWER_DOMAINS ( \
443 BIT(POWER_DOMAIN_PORT_DDI_A_LANES) | \
444 BIT(POWER_DOMAIN_AUX_A) | \
445 BIT(POWER_DOMAIN_INIT))
446#define BXT_DPIO_CMN_BC_POWER_DOMAINS ( \
447 BIT(POWER_DOMAIN_PORT_DDI_B_LANES) | \
448 BIT(POWER_DOMAIN_PORT_DDI_C_LANES) | \
449 BIT(POWER_DOMAIN_AUX_B) | \
450 BIT(POWER_DOMAIN_AUX_C) | \
451 BIT(POWER_DOMAIN_INIT))
439 452
440static void assert_can_enable_dc9(struct drm_i915_private *dev_priv) 453static void assert_can_enable_dc9(struct drm_i915_private *dev_priv)
441{ 454{
@@ -817,6 +830,72 @@ static void skl_power_well_disable(struct drm_i915_private *dev_priv,
817 skl_set_power_well(dev_priv, power_well, false); 830 skl_set_power_well(dev_priv, power_well, false);
818} 831}
819 832
833static enum dpio_phy bxt_power_well_to_phy(struct i915_power_well *power_well)
834{
835 enum skl_disp_power_wells power_well_id = power_well->data;
836
837 return power_well_id == BXT_DPIO_CMN_A ? DPIO_PHY1 : DPIO_PHY0;
838}
839
840static void bxt_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
841 struct i915_power_well *power_well)
842{
843 enum skl_disp_power_wells power_well_id = power_well->data;
844 struct i915_power_well *cmn_a_well;
845
846 if (power_well_id == BXT_DPIO_CMN_BC) {
847 /*
848 * We need to copy the GRC calibration value from the eDP PHY,
849 * so make sure it's powered up.
850 */
851 cmn_a_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A);
852 intel_power_well_get(dev_priv, cmn_a_well);
853 }
854
855 bxt_ddi_phy_init(dev_priv, bxt_power_well_to_phy(power_well));
856
857 if (power_well_id == BXT_DPIO_CMN_BC)
858 intel_power_well_put(dev_priv, cmn_a_well);
859}
860
861static void bxt_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
862 struct i915_power_well *power_well)
863{
864 bxt_ddi_phy_uninit(dev_priv, bxt_power_well_to_phy(power_well));
865}
866
867static bool bxt_dpio_cmn_power_well_enabled(struct drm_i915_private *dev_priv,
868 struct i915_power_well *power_well)
869{
870 return bxt_ddi_phy_is_enabled(dev_priv,
871 bxt_power_well_to_phy(power_well));
872}
873
874static void bxt_dpio_cmn_power_well_sync_hw(struct drm_i915_private *dev_priv,
875 struct i915_power_well *power_well)
876{
877 if (power_well->count > 0)
878 bxt_dpio_cmn_power_well_enable(dev_priv, power_well);
879 else
880 bxt_dpio_cmn_power_well_disable(dev_priv, power_well);
881}
882
883
884static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv)
885{
886 struct i915_power_well *power_well;
887
888 power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A);
889 if (power_well->count > 0)
890 bxt_ddi_phy_verify_state(dev_priv,
891 bxt_power_well_to_phy(power_well));
892
893 power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_BC);
894 if (power_well->count > 0)
895 bxt_ddi_phy_verify_state(dev_priv,
896 bxt_power_well_to_phy(power_well));
897}
898
820static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv, 899static bool gen9_dc_off_power_well_enabled(struct drm_i915_private *dev_priv,
821 struct i915_power_well *power_well) 900 struct i915_power_well *power_well)
822{ 901{
@@ -843,7 +922,7 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
843 gen9_assert_dbuf_enabled(dev_priv); 922 gen9_assert_dbuf_enabled(dev_priv);
844 923
845 if (IS_BROXTON(dev_priv)) 924 if (IS_BROXTON(dev_priv))
846 broxton_ddi_phy_verify_state(dev_priv); 925 bxt_verify_ddi_phy_power_wells(dev_priv);
847} 926}
848 927
849static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv, 928static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv,
@@ -1802,6 +1881,13 @@ static const struct i915_power_well_ops gen9_dc_off_power_well_ops = {
1802 .is_enabled = gen9_dc_off_power_well_enabled, 1881 .is_enabled = gen9_dc_off_power_well_enabled,
1803}; 1882};
1804 1883
1884static const struct i915_power_well_ops bxt_dpio_cmn_power_well_ops = {
1885 .sync_hw = bxt_dpio_cmn_power_well_sync_hw,
1886 .enable = bxt_dpio_cmn_power_well_enable,
1887 .disable = bxt_dpio_cmn_power_well_disable,
1888 .is_enabled = bxt_dpio_cmn_power_well_enabled,
1889};
1890
1805static struct i915_power_well hsw_power_wells[] = { 1891static struct i915_power_well hsw_power_wells[] = {
1806 { 1892 {
1807 .name = "always-on", 1893 .name = "always-on",
@@ -2038,6 +2124,18 @@ static struct i915_power_well bxt_power_wells[] = {
2038 .ops = &skl_power_well_ops, 2124 .ops = &skl_power_well_ops,
2039 .data = SKL_DISP_PW_2, 2125 .data = SKL_DISP_PW_2,
2040 }, 2126 },
2127 {
2128 .name = "dpio-common-a",
2129 .domains = BXT_DPIO_CMN_A_POWER_DOMAINS,
2130 .ops = &bxt_dpio_cmn_power_well_ops,
2131 .data = BXT_DPIO_CMN_A,
2132 },
2133 {
2134 .name = "dpio-common-bc",
2135 .domains = BXT_DPIO_CMN_BC_POWER_DOMAINS,
2136 .ops = &bxt_dpio_cmn_power_well_ops,
2137 .data = BXT_DPIO_CMN_BC,
2138 },
2041}; 2139};
2042 2140
2043static int 2141static int
@@ -2307,10 +2405,6 @@ void bxt_display_core_init(struct drm_i915_private *dev_priv,
2307 2405
2308 gen9_dbuf_enable(dev_priv); 2406 gen9_dbuf_enable(dev_priv);
2309 2407
2310 broxton_ddi_phy_init(dev_priv);
2311
2312 broxton_ddi_phy_verify_state(dev_priv);
2313
2314 if (resume && dev_priv->csr.dmc_payload) 2408 if (resume && dev_priv->csr.dmc_payload)
2315 intel_csr_load_program(dev_priv); 2409 intel_csr_load_program(dev_priv);
2316} 2410}
@@ -2322,8 +2416,6 @@ void bxt_display_core_uninit(struct drm_i915_private *dev_priv)
2322 2416
2323 gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); 2417 gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
2324 2418
2325 broxton_ddi_phy_uninit(dev_priv);
2326
2327 gen9_dbuf_disable(dev_priv); 2419 gen9_dbuf_disable(dev_priv);
2328 2420
2329 broxton_uninit_cdclk(dev_priv); 2421 broxton_uninit_cdclk(dev_priv);