aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2016-04-04 10:27:10 -0400
committerImre Deak <imre.deak@intel.com>2016-04-15 07:48:19 -0400
commitadc7f04bfda9cd0b2b4b84b5e8b72fd4c7b56d0a (patch)
treea7bd03920c9a195d6723b41e2d1656e9b95c72db /drivers/gpu/drm/i915
parentbd480061788fe2f657daba7e519c9175b7dba968 (diff)
drm/i915/bxt: Add HW state verification for DDI PHY and CDCLK
I caught a few errors in our current PHY/CDCLK programming by sanity checking the actual programmed state, so I thought it would be also useful for the future. In addition to verifying the state after programming it also verify it after exiting DC5, to make sure DMC restored/kept intact everything related. v2: - Inlining __phy_reg_verify_state() doesn't make sense and also incorrect, so don't do it (PW/CI gcc) v3: - Rebase on latest -nightly Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: David Weinehall <david.weinehall@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1459780030-15781-1-git-send-email-imre.deak@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c124
-rw-r--r--drivers/gpu/drm/i915/intel_display.c5
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c8
5 files changed, 138 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b9ed1b305beb..946b5df7b7df 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1924,6 +1924,7 @@ struct drm_i915_private {
1924 * crappiness (can't read out DPLL_MD for pipes B & C). 1924 * crappiness (can't read out DPLL_MD for pipes B & C).
1925 */ 1925 */
1926 u32 chv_dpll_md[I915_MAX_PIPES]; 1926 u32 chv_dpll_md[I915_MAX_PIPES];
1927 u32 bxt_phy_grc;
1927 1928
1928 u32 suspend_count; 1929 u32 suspend_count;
1929 bool suspended_to_idle; 1930 bool suspended_to_idle;
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index a3db4daec844..96234c589850 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1753,6 +1753,13 @@ static bool broxton_phy_is_enabled(struct drm_i915_private *dev_priv,
1753 return true; 1753 return true;
1754} 1754}
1755 1755
1756static u32 broxton_get_grc(struct drm_i915_private *dev_priv, enum dpio_phy phy)
1757{
1758 u32 val = I915_READ(BXT_PORT_REF_DW6(phy));
1759
1760 return (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
1761}
1762
1756static void broxton_phy_init(struct drm_i915_private *dev_priv, 1763static void broxton_phy_init(struct drm_i915_private *dev_priv,
1757 enum dpio_phy phy) 1764 enum dpio_phy phy)
1758{ 1765{
@@ -1762,6 +1769,9 @@ static void broxton_phy_init(struct drm_i915_private *dev_priv,
1762 if (broxton_phy_is_enabled(dev_priv, phy)) { 1769 if (broxton_phy_is_enabled(dev_priv, phy)) {
1763 DRM_DEBUG_DRIVER("DDI PHY %d already enabled, " 1770 DRM_DEBUG_DRIVER("DDI PHY %d already enabled, "
1764 "won't reprogram it\n", phy); 1771 "won't reprogram it\n", phy);
1772 /* Still read out the GRC value for state verification */
1773 if (phy == DPIO_PHY1)
1774 dev_priv->bxt_phy_grc = broxton_get_grc(dev_priv, phy);
1765 1775
1766 return; 1776 return;
1767 } 1777 }
@@ -1857,8 +1867,8 @@ static void broxton_phy_init(struct drm_i915_private *dev_priv,
1857 10)) 1867 10))
1858 DRM_ERROR("timeout waiting for PHY1 GRC\n"); 1868 DRM_ERROR("timeout waiting for PHY1 GRC\n");
1859 1869
1860 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1)); 1870 val = dev_priv->bxt_phy_grc = broxton_get_grc(dev_priv,
1861 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT; 1871 DPIO_PHY1);
1862 grc_code = val << GRC_CODE_FAST_SHIFT | 1872 grc_code = val << GRC_CODE_FAST_SHIFT |
1863 val << GRC_CODE_SLOW_SHIFT | 1873 val << GRC_CODE_SLOW_SHIFT |
1864 val; 1874 val;
@@ -1901,6 +1911,116 @@ void broxton_ddi_phy_uninit(struct drm_i915_private *dev_priv)
1901 broxton_phy_uninit(dev_priv, DPIO_PHY0); 1911 broxton_phy_uninit(dev_priv, DPIO_PHY0);
1902} 1912}
1903 1913
1914static bool __printf(6, 7)
1915__phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy,
1916 i915_reg_t reg, u32 mask, u32 expected,
1917 const char *reg_fmt, ...)
1918{
1919 struct va_format vaf;
1920 va_list args;
1921 u32 val;
1922
1923 val = I915_READ(reg);
1924 if ((val & mask) == expected)
1925 return true;
1926
1927 va_start(args, reg_fmt);
1928 vaf.fmt = reg_fmt;
1929 vaf.va = &args;
1930
1931 DRM_DEBUG_DRIVER("DDI PHY %d reg %pV [%08x] state mismatch: "
1932 "current %08x, expected %08x (mask %08x)\n",
1933 phy, &vaf, reg.reg, val, (val & ~mask) | expected,
1934 mask);
1935
1936 va_end(args);
1937
1938 return false;
1939}
1940
1941static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv,
1942 enum dpio_phy phy)
1943{
1944 enum port port;
1945 u32 ports;
1946 uint32_t mask;
1947 bool ok;
1948
1949#define _CHK(reg, mask, exp, fmt, ...) \
1950 __phy_reg_verify_state(dev_priv, phy, reg, mask, exp, fmt, \
1951 ## __VA_ARGS__)
1952
1953 /* We expect the PHY to be always enabled */
1954 if (!broxton_phy_is_enabled(dev_priv, phy))
1955 return false;
1956
1957 ok = true;
1958
1959 if (phy == DPIO_PHY0)
1960 ports = BIT(PORT_B) | BIT(PORT_C);
1961 else
1962 ports = BIT(PORT_A);
1963
1964 for_each_port_masked(port, ports) {
1965 int lane;
1966
1967 for (lane = 0; lane < 4; lane++)
1968 ok &= _CHK(BXT_PORT_TX_DW14_LN(port, lane),
1969 LATENCY_OPTIM,
1970 lane != 1 ? LATENCY_OPTIM : 0,
1971 "BXT_PORT_TX_DW14_LN(%d, %d)", port, lane);
1972 }
1973
1974 /* PLL Rcomp code offset */
1975 ok &= _CHK(BXT_PORT_CL1CM_DW9(phy),
1976 IREF0RC_OFFSET_MASK, 0xe4 << IREF0RC_OFFSET_SHIFT,
1977 "BXT_PORT_CL1CM_DW9(%d)", phy);
1978 ok &= _CHK(BXT_PORT_CL1CM_DW10(phy),
1979 IREF1RC_OFFSET_MASK, 0xe4 << IREF1RC_OFFSET_SHIFT,
1980 "BXT_PORT_CL1CM_DW10(%d)", phy);
1981
1982 /* Power gating */
1983 mask = OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN | SUS_CLK_CONFIG;
1984 ok &= _CHK(BXT_PORT_CL1CM_DW28(phy), mask, mask,
1985 "BXT_PORT_CL1CM_DW28(%d)", phy);
1986
1987 if (phy == DPIO_PHY0)
1988 ok &= _CHK(BXT_PORT_CL2CM_DW6_BC,
1989 DW6_OLDO_DYN_PWR_DOWN_EN, DW6_OLDO_DYN_PWR_DOWN_EN,
1990 "BXT_PORT_CL2CM_DW6_BC");
1991
1992 /*
1993 * TODO: Verify BXT_PORT_CL1CM_DW30 bit OCL2_LDOFUSE_PWR_DIS,
1994 * at least on stepping A this bit is read-only and fixed at 0.
1995 */
1996
1997 if (phy == DPIO_PHY0) {
1998 u32 grc_code = dev_priv->bxt_phy_grc;
1999
2000 grc_code = grc_code << GRC_CODE_FAST_SHIFT |
2001 grc_code << GRC_CODE_SLOW_SHIFT |
2002 grc_code;
2003 mask = GRC_CODE_FAST_MASK | GRC_CODE_SLOW_MASK |
2004 GRC_CODE_NOM_MASK;
2005 ok &= _CHK(BXT_PORT_REF_DW6(DPIO_PHY0), mask, grc_code,
2006 "BXT_PORT_REF_DW6(%d)", DPIO_PHY0);
2007
2008 mask = GRC_DIS | GRC_RDY_OVRD;
2009 ok &= _CHK(BXT_PORT_REF_DW8(DPIO_PHY0), mask, mask,
2010 "BXT_PORT_REF_DW8(%d)", DPIO_PHY0);
2011 }
2012
2013 return ok;
2014#undef _CHK
2015}
2016
2017void broxton_ddi_phy_verify_state(struct drm_i915_private *dev_priv)
2018{
2019 if (!broxton_phy_verify_state(dev_priv, DPIO_PHY0) ||
2020 !broxton_phy_verify_state(dev_priv, DPIO_PHY1))
2021 i915_report_error(dev_priv, "DDI PHY state mismatch\n");
2022}
2023
1904void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) 2024void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
1905{ 2025{
1906 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); 2026 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 089cf603a6f7..f587f7dd8ad9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5468,6 +5468,11 @@ static bool broxton_cdclk_is_enabled(struct drm_i915_private *dev_priv)
5468 return true; 5468 return true;
5469} 5469}
5470 5470
5471bool broxton_cdclk_verify_state(struct drm_i915_private *dev_priv)
5472{
5473 return broxton_cdclk_is_enabled(dev_priv);
5474}
5475
5471void broxton_init_cdclk(struct drm_i915_private *dev_priv) 5476void broxton_init_cdclk(struct drm_i915_private *dev_priv)
5472{ 5477{
5473 /* check if cd clock is enabled */ 5478 /* check if cd clock is enabled */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f8c26a5b715a..72153359cbb3 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1226,8 +1226,10 @@ void hsw_enable_pc8(struct drm_i915_private *dev_priv);
1226void hsw_disable_pc8(struct drm_i915_private *dev_priv); 1226void hsw_disable_pc8(struct drm_i915_private *dev_priv);
1227void broxton_init_cdclk(struct drm_i915_private *dev_priv); 1227void broxton_init_cdclk(struct drm_i915_private *dev_priv);
1228void broxton_uninit_cdclk(struct drm_i915_private *dev_priv); 1228void broxton_uninit_cdclk(struct drm_i915_private *dev_priv);
1229bool broxton_cdclk_verify_state(struct drm_i915_private *dev_priv);
1229void broxton_ddi_phy_init(struct drm_i915_private *dev_priv); 1230void broxton_ddi_phy_init(struct drm_i915_private *dev_priv);
1230void broxton_ddi_phy_uninit(struct drm_i915_private *dev_priv); 1231void broxton_ddi_phy_uninit(struct drm_i915_private *dev_priv);
1232void broxton_ddi_phy_verify_state(struct drm_i915_private *dev_priv);
1231void bxt_enable_dc9(struct drm_i915_private *dev_priv); 1233void bxt_enable_dc9(struct drm_i915_private *dev_priv);
1232void bxt_disable_dc9(struct drm_i915_private *dev_priv); 1234void bxt_disable_dc9(struct drm_i915_private *dev_priv);
1233void skl_init_cdclk(struct drm_i915_private *dev_priv); 1235void skl_init_cdclk(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 e3f70c53c57e..cb20606d7d57 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -799,6 +799,11 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
799 struct i915_power_well *power_well) 799 struct i915_power_well *power_well)
800{ 800{
801 gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); 801 gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
802
803 if (IS_BROXTON(dev_priv)) {
804 broxton_cdclk_verify_state(dev_priv);
805 broxton_ddi_phy_verify_state(dev_priv);
806 }
802} 807}
803 808
804static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv, 809static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv,
@@ -2199,6 +2204,9 @@ void bxt_display_core_init(struct drm_i915_private *dev_priv,
2199 broxton_init_cdclk(dev_priv); 2204 broxton_init_cdclk(dev_priv);
2200 broxton_ddi_phy_init(dev_priv); 2205 broxton_ddi_phy_init(dev_priv);
2201 2206
2207 broxton_cdclk_verify_state(dev_priv);
2208 broxton_ddi_phy_verify_state(dev_priv);
2209
2202 if (resume && dev_priv->csr.dmc_payload) 2210 if (resume && dev_priv->csr.dmc_payload)
2203 intel_csr_load_program(dev_priv); 2211 intel_csr_load_program(dev_priv);
2204} 2212}