aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
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
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')
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h3
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c46
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h9
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c106
4 files changed, 117 insertions, 47 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 4657aed5d7b0..c8fd8b94deaf 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -716,6 +716,9 @@ enum skl_disp_power_wells {
716 /* Not actual bit groups. Used as IDs for lookup_power_well() */ 716 /* Not actual bit groups. Used as IDs for lookup_power_well() */
717 SKL_DISP_PW_ALWAYS_ON, 717 SKL_DISP_PW_ALWAYS_ON,
718 SKL_DISP_PW_DC_OFF, 718 SKL_DISP_PW_DC_OFF,
719
720 BXT_DPIO_CMN_A,
721 BXT_DPIO_CMN_BC,
719}; 722};
720 723
721#define SKL_POWER_WELL_STATE(pw) (1 << ((pw) * 2)) 724#define SKL_POWER_WELL_STATE(pw) (1 << ((pw) * 2))
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index b10c7b569bd6..dee6dd0f9f37 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1742,8 +1742,8 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
1742 } 1742 }
1743} 1743}
1744 1744
1745static bool broxton_phy_is_enabled(struct drm_i915_private *dev_priv, 1745bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv,
1746 enum dpio_phy phy) 1746 enum dpio_phy phy)
1747{ 1747{
1748 if (!(I915_READ(BXT_P_CR_GT_DISP_PWRON) & GT_DISPLAY_POWER_ON(phy))) 1748 if (!(I915_READ(BXT_P_CR_GT_DISP_PWRON) & GT_DISPLAY_POWER_ON(phy)))
1749 return false; 1749 return false;
@@ -1787,21 +1787,17 @@ static void broxton_phy_wait_grc_done(struct drm_i915_private *dev_priv,
1787 DRM_ERROR("timeout waiting for PHY%d GRC\n", phy); 1787 DRM_ERROR("timeout waiting for PHY%d GRC\n", phy);
1788} 1788}
1789 1789
1790static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv, 1790void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy)
1791 enum dpio_phy phy);
1792
1793static void broxton_phy_init(struct drm_i915_private *dev_priv,
1794 enum dpio_phy phy)
1795{ 1791{
1796 enum port port; 1792 enum port port;
1797 u32 ports, val; 1793 u32 ports, val;
1798 1794
1799 if (broxton_phy_is_enabled(dev_priv, phy)) { 1795 if (bxt_ddi_phy_is_enabled(dev_priv, phy)) {
1800 /* Still read out the GRC value for state verification */ 1796 /* Still read out the GRC value for state verification */
1801 if (phy == DPIO_PHY0) 1797 if (phy == DPIO_PHY0)
1802 dev_priv->bxt_phy_grc = broxton_get_grc(dev_priv, phy); 1798 dev_priv->bxt_phy_grc = broxton_get_grc(dev_priv, phy);
1803 1799
1804 if (broxton_phy_verify_state(dev_priv, phy)) { 1800 if (bxt_ddi_phy_verify_state(dev_priv, phy)) {
1805 DRM_DEBUG_DRIVER("DDI PHY %d already enabled, " 1801 DRM_DEBUG_DRIVER("DDI PHY %d already enabled, "
1806 "won't reprogram it\n", phy); 1802 "won't reprogram it\n", phy);
1807 1803
@@ -1810,8 +1806,6 @@ static void broxton_phy_init(struct drm_i915_private *dev_priv,
1810 1806
1811 DRM_DEBUG_DRIVER("DDI PHY %d enabled with invalid state, " 1807 DRM_DEBUG_DRIVER("DDI PHY %d enabled with invalid state, "
1812 "force reprogramming it\n", phy); 1808 "force reprogramming it\n", phy);
1813 } else {
1814 DRM_DEBUG_DRIVER("DDI PHY %d not enabled, enabling it\n", phy);
1815 } 1809 }
1816 1810
1817 val = I915_READ(BXT_P_CR_GT_DISP_PWRON); 1811 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
@@ -1919,15 +1913,7 @@ static void broxton_phy_init(struct drm_i915_private *dev_priv,
1919 broxton_phy_wait_grc_done(dev_priv, DPIO_PHY1); 1913 broxton_phy_wait_grc_done(dev_priv, DPIO_PHY1);
1920} 1914}
1921 1915
1922void broxton_ddi_phy_init(struct drm_i915_private *dev_priv) 1916void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy)
1923{
1924 /* Enable PHY1 first since it provides Rcomp for PHY0 */
1925 broxton_phy_init(dev_priv, DPIO_PHY1);
1926 broxton_phy_init(dev_priv, DPIO_PHY0);
1927}
1928
1929static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
1930 enum dpio_phy phy)
1931{ 1917{
1932 uint32_t val; 1918 uint32_t val;
1933 1919
@@ -1940,12 +1926,6 @@ static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
1940 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val); 1926 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
1941} 1927}
1942 1928
1943void broxton_ddi_phy_uninit(struct drm_i915_private *dev_priv)
1944{
1945 broxton_phy_uninit(dev_priv, DPIO_PHY1);
1946 broxton_phy_uninit(dev_priv, DPIO_PHY0);
1947}
1948
1949static bool __printf(6, 7) 1929static bool __printf(6, 7)
1950__phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy, 1930__phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy,
1951 i915_reg_t reg, u32 mask, u32 expected, 1931 i915_reg_t reg, u32 mask, u32 expected,
@@ -1973,8 +1953,8 @@ __phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy,
1973 return false; 1953 return false;
1974} 1954}
1975 1955
1976static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv, 1956bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv,
1977 enum dpio_phy phy) 1957 enum dpio_phy phy)
1978{ 1958{
1979 enum port port; 1959 enum port port;
1980 u32 ports; 1960 u32 ports;
@@ -1985,8 +1965,7 @@ static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv,
1985 __phy_reg_verify_state(dev_priv, phy, reg, mask, exp, fmt, \ 1965 __phy_reg_verify_state(dev_priv, phy, reg, mask, exp, fmt, \
1986 ## __VA_ARGS__) 1966 ## __VA_ARGS__)
1987 1967
1988 /* We expect the PHY to be always enabled */ 1968 if (!bxt_ddi_phy_is_enabled(dev_priv, phy))
1989 if (!broxton_phy_is_enabled(dev_priv, phy))
1990 return false; 1969 return false;
1991 1970
1992 ok = true; 1971 ok = true;
@@ -2049,13 +2028,6 @@ static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv,
2049#undef _CHK 2028#undef _CHK
2050} 2029}
2051 2030
2052void broxton_ddi_phy_verify_state(struct drm_i915_private *dev_priv)
2053{
2054 if (!broxton_phy_verify_state(dev_priv, DPIO_PHY0) ||
2055 !broxton_phy_verify_state(dev_priv, DPIO_PHY1))
2056 i915_report_error(dev_priv, "DDI PHY state mismatch\n");
2057}
2058
2059void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) 2031void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
2060{ 2032{
2061 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); 2033 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ebe7b3427e2e..17445d7b2810 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1263,9 +1263,12 @@ void hsw_enable_pc8(struct drm_i915_private *dev_priv);
1263void hsw_disable_pc8(struct drm_i915_private *dev_priv); 1263void hsw_disable_pc8(struct drm_i915_private *dev_priv);
1264void broxton_init_cdclk(struct drm_i915_private *dev_priv); 1264void broxton_init_cdclk(struct drm_i915_private *dev_priv);
1265void broxton_uninit_cdclk(struct drm_i915_private *dev_priv); 1265void broxton_uninit_cdclk(struct drm_i915_private *dev_priv);
1266void broxton_ddi_phy_init(struct drm_i915_private *dev_priv); 1266void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy);
1267void broxton_ddi_phy_uninit(struct drm_i915_private *dev_priv); 1267void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy);
1268void broxton_ddi_phy_verify_state(struct drm_i915_private *dev_priv); 1268bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv,
1269 enum dpio_phy phy);
1270bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv,
1271 enum dpio_phy phy);
1269void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv); 1272void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv);
1270void bxt_enable_dc9(struct drm_i915_private *dev_priv); 1273void bxt_enable_dc9(struct drm_i915_private *dev_priv);
1271void bxt_disable_dc9(struct drm_i915_private *dev_priv); 1274void bxt_disable_dc9(struct drm_i915_private *dev_priv);
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);