diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-09-10 13:57:18 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-09-10 18:13:47 -0400 |
commit | c98e9dcf9023e72837c1c01251f370e2358a0de6 (patch) | |
tree | 13e1e29466c013b9b0b5adc53eda0c0830c08284 /drivers/gpu/drm/i915/intel_display.c | |
parent | 7e7d76c306adb73a41d2678a42a11004df2519b7 (diff) |
drm/i915: enable PCH PLL, FDI training and transcoder even for eDP
eDP panels require these to be set up prior to panel power sequencing,
or they'll fail to power on due to an "asset not ready" check. And of
course, eDP panels attached to anything other than DP_A need them
enabled regardless, since they'll be driven from the CPU through FDI out
to the PCH.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 242 |
1 files changed, 119 insertions, 123 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 98276b8454fc..ff549199c700 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1889,34 +1889,32 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
1889 | } | 1889 | } |
1890 | } | 1890 | } |
1891 | 1891 | ||
1892 | if (!HAS_eDP) { | 1892 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
1893 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1893 | temp = I915_READ(fdi_rx_reg); |
1894 | temp = I915_READ(fdi_rx_reg); | 1894 | /* |
1895 | /* | 1895 | * make the BPC in FDI Rx be consistent with that in |
1896 | * make the BPC in FDI Rx be consistent with that in | 1896 | * pipeconf reg. |
1897 | * pipeconf reg. | 1897 | */ |
1898 | */ | 1898 | temp &= ~(0x7 << 16); |
1899 | temp &= ~(0x7 << 16); | 1899 | temp |= (pipe_bpc << 11); |
1900 | temp |= (pipe_bpc << 11); | 1900 | temp &= ~(7 << 19); |
1901 | temp &= ~(7 << 19); | 1901 | temp |= (intel_crtc->fdi_lanes - 1) << 19; |
1902 | temp |= (intel_crtc->fdi_lanes - 1) << 19; | 1902 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); |
1903 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); | 1903 | I915_READ(fdi_rx_reg); |
1904 | I915_READ(fdi_rx_reg); | 1904 | udelay(200); |
1905 | udelay(200); | ||
1906 | 1905 | ||
1907 | /* Switch from Rawclk to PCDclk */ | 1906 | /* Switch from Rawclk to PCDclk */ |
1908 | temp = I915_READ(fdi_rx_reg); | 1907 | temp = I915_READ(fdi_rx_reg); |
1909 | I915_WRITE(fdi_rx_reg, temp | FDI_SEL_PCDCLK); | 1908 | I915_WRITE(fdi_rx_reg, temp | FDI_SEL_PCDCLK); |
1910 | I915_READ(fdi_rx_reg); | 1909 | I915_READ(fdi_rx_reg); |
1911 | udelay(200); | 1910 | udelay(200); |
1912 | 1911 | ||
1913 | /* Enable CPU FDI TX PLL, always on for Ironlake */ | 1912 | /* Enable CPU FDI TX PLL, always on for Ironlake */ |
1914 | temp = I915_READ(fdi_tx_reg); | 1913 | temp = I915_READ(fdi_tx_reg); |
1915 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { | 1914 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { |
1916 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); | 1915 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); |
1917 | I915_READ(fdi_tx_reg); | 1916 | I915_READ(fdi_tx_reg); |
1918 | udelay(100); | 1917 | udelay(100); |
1919 | } | ||
1920 | } | 1918 | } |
1921 | 1919 | ||
1922 | /* Enable panel fitting for LVDS */ | 1920 | /* Enable panel fitting for LVDS */ |
@@ -1951,115 +1949,113 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
1951 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); | 1949 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); |
1952 | } | 1950 | } |
1953 | 1951 | ||
1954 | if (!HAS_eDP) { | 1952 | /* For PCH output, training FDI link */ |
1955 | /* For PCH output, training FDI link */ | 1953 | if (IS_GEN6(dev)) |
1956 | if (IS_GEN6(dev)) | 1954 | gen6_fdi_link_train(crtc); |
1957 | gen6_fdi_link_train(crtc); | 1955 | else |
1958 | else | 1956 | ironlake_fdi_link_train(crtc); |
1959 | ironlake_fdi_link_train(crtc); | ||
1960 | 1957 | ||
1961 | /* enable PCH DPLL */ | 1958 | /* enable PCH DPLL */ |
1962 | temp = I915_READ(pch_dpll_reg); | 1959 | temp = I915_READ(pch_dpll_reg); |
1963 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 1960 | if ((temp & DPLL_VCO_ENABLE) == 0) { |
1964 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); | 1961 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); |
1965 | I915_READ(pch_dpll_reg); | 1962 | I915_READ(pch_dpll_reg); |
1966 | } | 1963 | } |
1967 | udelay(200); | 1964 | udelay(200); |
1968 | 1965 | ||
1969 | if (HAS_PCH_CPT(dev)) { | 1966 | if (HAS_PCH_CPT(dev)) { |
1970 | /* Be sure PCH DPLL SEL is set */ | 1967 | /* Be sure PCH DPLL SEL is set */ |
1971 | temp = I915_READ(PCH_DPLL_SEL); | 1968 | temp = I915_READ(PCH_DPLL_SEL); |
1972 | if (trans_dpll_sel == 0 && | 1969 | if (trans_dpll_sel == 0 && |
1973 | (temp & TRANSA_DPLL_ENABLE) == 0) | 1970 | (temp & TRANSA_DPLL_ENABLE) == 0) |
1974 | temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL); | 1971 | temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL); |
1975 | else if (trans_dpll_sel == 1 && | 1972 | else if (trans_dpll_sel == 1 && |
1976 | (temp & TRANSB_DPLL_ENABLE) == 0) | 1973 | (temp & TRANSB_DPLL_ENABLE) == 0) |
1977 | temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); | 1974 | temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); |
1978 | I915_WRITE(PCH_DPLL_SEL, temp); | 1975 | I915_WRITE(PCH_DPLL_SEL, temp); |
1979 | I915_READ(PCH_DPLL_SEL); | 1976 | I915_READ(PCH_DPLL_SEL); |
1980 | } | 1977 | } |
1981 | /* set transcoder timing */ | 1978 | /* set transcoder timing */ |
1982 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); | 1979 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); |
1983 | I915_WRITE(trans_hblank_reg, I915_READ(cpu_hblank_reg)); | 1980 | I915_WRITE(trans_hblank_reg, I915_READ(cpu_hblank_reg)); |
1984 | I915_WRITE(trans_hsync_reg, I915_READ(cpu_hsync_reg)); | 1981 | I915_WRITE(trans_hsync_reg, I915_READ(cpu_hsync_reg)); |
1985 | 1982 | ||
1986 | I915_WRITE(trans_vtot_reg, I915_READ(cpu_vtot_reg)); | 1983 | I915_WRITE(trans_vtot_reg, I915_READ(cpu_vtot_reg)); |
1987 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); | 1984 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); |
1988 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); | 1985 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); |
1989 | 1986 | ||
1990 | /* enable normal train */ | 1987 | /* enable normal train */ |
1991 | temp = I915_READ(fdi_tx_reg); | 1988 | temp = I915_READ(fdi_tx_reg); |
1992 | temp &= ~FDI_LINK_TRAIN_NONE; | 1989 | temp &= ~FDI_LINK_TRAIN_NONE; |
1993 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | | 1990 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | |
1994 | FDI_TX_ENHANCE_FRAME_ENABLE); | 1991 | FDI_TX_ENHANCE_FRAME_ENABLE); |
1995 | I915_READ(fdi_tx_reg); | 1992 | I915_READ(fdi_tx_reg); |
1996 | 1993 | ||
1997 | temp = I915_READ(fdi_rx_reg); | 1994 | temp = I915_READ(fdi_rx_reg); |
1998 | if (HAS_PCH_CPT(dev)) { | 1995 | if (HAS_PCH_CPT(dev)) { |
1999 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; | 1996 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; |
2000 | temp |= FDI_LINK_TRAIN_NORMAL_CPT; | 1997 | temp |= FDI_LINK_TRAIN_NORMAL_CPT; |
2001 | } else { | 1998 | } else { |
2002 | temp &= ~FDI_LINK_TRAIN_NONE; | 1999 | temp &= ~FDI_LINK_TRAIN_NONE; |
2003 | temp |= FDI_LINK_TRAIN_NONE; | 2000 | temp |= FDI_LINK_TRAIN_NONE; |
2004 | } | 2001 | } |
2005 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); | 2002 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); |
2006 | I915_READ(fdi_rx_reg); | 2003 | I915_READ(fdi_rx_reg); |
2007 | 2004 | ||
2008 | /* wait one idle pattern time */ | 2005 | /* wait one idle pattern time */ |
2009 | udelay(100); | 2006 | udelay(100); |
2010 | 2007 | ||
2011 | /* For PCH DP, enable TRANS_DP_CTL */ | 2008 | /* For PCH DP, enable TRANS_DP_CTL */ |
2012 | if (HAS_PCH_CPT(dev) && | 2009 | if (HAS_PCH_CPT(dev) && |
2013 | intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { | 2010 | intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { |
2014 | int trans_dp_ctl = (pipe == 0) ? TRANS_DP_CTL_A : TRANS_DP_CTL_B; | 2011 | int trans_dp_ctl = (pipe == 0) ? TRANS_DP_CTL_A : TRANS_DP_CTL_B; |
2015 | int reg; | 2012 | int reg; |
2016 | |||
2017 | reg = I915_READ(trans_dp_ctl); | ||
2018 | reg &= ~(TRANS_DP_PORT_SEL_MASK | | ||
2019 | TRANS_DP_SYNC_MASK); | ||
2020 | reg |= (TRANS_DP_OUTPUT_ENABLE | | ||
2021 | TRANS_DP_ENH_FRAMING); | ||
2022 | |||
2023 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | ||
2024 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; | ||
2025 | if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) | ||
2026 | reg |= TRANS_DP_VSYNC_ACTIVE_HIGH; | ||
2027 | |||
2028 | switch (intel_trans_dp_port_sel(crtc)) { | ||
2029 | case PCH_DP_B: | ||
2030 | reg |= TRANS_DP_PORT_SEL_B; | ||
2031 | break; | ||
2032 | case PCH_DP_C: | ||
2033 | reg |= TRANS_DP_PORT_SEL_C; | ||
2034 | break; | ||
2035 | case PCH_DP_D: | ||
2036 | reg |= TRANS_DP_PORT_SEL_D; | ||
2037 | break; | ||
2038 | default: | ||
2039 | DRM_DEBUG_KMS("Wrong PCH DP port return. Guess port B\n"); | ||
2040 | reg |= TRANS_DP_PORT_SEL_B; | ||
2041 | break; | ||
2042 | } | ||
2043 | 2013 | ||
2044 | I915_WRITE(trans_dp_ctl, reg); | 2014 | reg = I915_READ(trans_dp_ctl); |
2045 | POSTING_READ(trans_dp_ctl); | 2015 | reg &= ~(TRANS_DP_PORT_SEL_MASK | |
2016 | TRANS_DP_SYNC_MASK); | ||
2017 | reg |= (TRANS_DP_OUTPUT_ENABLE | | ||
2018 | TRANS_DP_ENH_FRAMING); | ||
2019 | |||
2020 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | ||
2021 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; | ||
2022 | if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) | ||
2023 | reg |= TRANS_DP_VSYNC_ACTIVE_HIGH; | ||
2024 | |||
2025 | switch (intel_trans_dp_port_sel(crtc)) { | ||
2026 | case PCH_DP_B: | ||
2027 | reg |= TRANS_DP_PORT_SEL_B; | ||
2028 | break; | ||
2029 | case PCH_DP_C: | ||
2030 | reg |= TRANS_DP_PORT_SEL_C; | ||
2031 | break; | ||
2032 | case PCH_DP_D: | ||
2033 | reg |= TRANS_DP_PORT_SEL_D; | ||
2034 | break; | ||
2035 | default: | ||
2036 | DRM_DEBUG_KMS("Wrong PCH DP port return. Guess port B\n"); | ||
2037 | reg |= TRANS_DP_PORT_SEL_B; | ||
2038 | break; | ||
2046 | } | 2039 | } |
2047 | 2040 | ||
2048 | /* enable PCH transcoder */ | 2041 | I915_WRITE(trans_dp_ctl, reg); |
2049 | temp = I915_READ(transconf_reg); | 2042 | POSTING_READ(trans_dp_ctl); |
2050 | /* | ||
2051 | * make the BPC in transcoder be consistent with | ||
2052 | * that in pipeconf reg. | ||
2053 | */ | ||
2054 | temp &= ~PIPE_BPC_MASK; | ||
2055 | temp |= pipe_bpc; | ||
2056 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | ||
2057 | I915_READ(transconf_reg); | ||
2058 | |||
2059 | if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 100)) | ||
2060 | DRM_ERROR("failed to enable transcoder\n"); | ||
2061 | } | 2043 | } |
2062 | 2044 | ||
2045 | /* enable PCH transcoder */ | ||
2046 | temp = I915_READ(transconf_reg); | ||
2047 | /* | ||
2048 | * make the BPC in transcoder be consistent with | ||
2049 | * that in pipeconf reg. | ||
2050 | */ | ||
2051 | temp &= ~PIPE_BPC_MASK; | ||
2052 | temp |= pipe_bpc; | ||
2053 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | ||
2054 | I915_READ(transconf_reg); | ||
2055 | |||
2056 | if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 100)) | ||
2057 | DRM_ERROR("failed to enable transcoder\n"); | ||
2058 | |||
2063 | intel_crtc_load_lut(crtc); | 2059 | intel_crtc_load_lut(crtc); |
2064 | 2060 | ||
2065 | intel_update_fbc(crtc, &crtc->mode); | 2061 | intel_update_fbc(crtc, &crtc->mode); |