diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-09-03 16:38:52 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-09-03 16:38:52 -0400 |
commit | 68885a3ff38ed51fa02f241feb405c9922a90ee0 (patch) | |
tree | 2fc626df39d5e0e1f6b065238141f7d49187c737 /drivers/gpu/drm/i915/intel_display.c | |
parent | 7b28079b3284ccb15ad4f003fb7073890600d0c1 (diff) | |
parent | a2acad8298a42b7be684a32fafaf83332bba9c2b (diff) |
Merge branch 'fix/misc' into topic/misc
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 519 |
1 files changed, 289 insertions, 230 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5ec10e02341..11a3394f5fe 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/vgaarb.h> | ||
32 | #include "drmP.h" | 33 | #include "drmP.h" |
33 | #include "intel_drv.h" | 34 | #include "intel_drv.h" |
34 | #include "i915_drm.h" | 35 | #include "i915_drm.h" |
@@ -976,14 +977,54 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
976 | return true; | 977 | return true; |
977 | } | 978 | } |
978 | 979 | ||
979 | void | 980 | /** |
980 | intel_wait_for_vblank(struct drm_device *dev) | 981 | * intel_wait_for_vblank - wait for vblank on a given pipe |
982 | * @dev: drm device | ||
983 | * @pipe: pipe to wait for | ||
984 | * | ||
985 | * Wait for vblank to occur on a given pipe. Needed for various bits of | ||
986 | * mode setting code. | ||
987 | */ | ||
988 | void intel_wait_for_vblank(struct drm_device *dev, int pipe) | ||
981 | { | 989 | { |
982 | /* Wait for 20ms, i.e. one cycle at 50hz. */ | 990 | struct drm_i915_private *dev_priv = dev->dev_private; |
983 | if (in_dbg_master()) | 991 | int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT); |
984 | mdelay(20); /* The kernel debugger cannot call msleep() */ | 992 | |
985 | else | 993 | /* Wait for vblank interrupt bit to set */ |
986 | msleep(20); | 994 | if (wait_for((I915_READ(pipestat_reg) & |
995 | PIPE_VBLANK_INTERRUPT_STATUS), | ||
996 | 50, 0)) | ||
997 | DRM_DEBUG_KMS("vblank wait timed out\n"); | ||
998 | } | ||
999 | |||
1000 | /** | ||
1001 | * intel_wait_for_vblank_off - wait for vblank after disabling a pipe | ||
1002 | * @dev: drm device | ||
1003 | * @pipe: pipe to wait for | ||
1004 | * | ||
1005 | * After disabling a pipe, we can't wait for vblank in the usual way, | ||
1006 | * spinning on the vblank interrupt status bit, since we won't actually | ||
1007 | * see an interrupt when the pipe is disabled. | ||
1008 | * | ||
1009 | * So this function waits for the display line value to settle (it | ||
1010 | * usually ends up stopping at the start of the next frame). | ||
1011 | */ | ||
1012 | void intel_wait_for_vblank_off(struct drm_device *dev, int pipe) | ||
1013 | { | ||
1014 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1015 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); | ||
1016 | unsigned long timeout = jiffies + msecs_to_jiffies(100); | ||
1017 | u32 last_line; | ||
1018 | |||
1019 | /* Wait for the display line to settle */ | ||
1020 | do { | ||
1021 | last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | ||
1022 | mdelay(5); | ||
1023 | } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && | ||
1024 | time_after(timeout, jiffies)); | ||
1025 | |||
1026 | if (time_after(jiffies, timeout)) | ||
1027 | DRM_DEBUG_KMS("vblank wait timed out\n"); | ||
987 | } | 1028 | } |
988 | 1029 | ||
989 | /* Parameters have changed, update FBC info */ | 1030 | /* Parameters have changed, update FBC info */ |
@@ -1037,7 +1078,6 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1037 | void i8xx_disable_fbc(struct drm_device *dev) | 1078 | void i8xx_disable_fbc(struct drm_device *dev) |
1038 | { | 1079 | { |
1039 | struct drm_i915_private *dev_priv = dev->dev_private; | 1080 | struct drm_i915_private *dev_priv = dev->dev_private; |
1040 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | ||
1041 | u32 fbc_ctl; | 1081 | u32 fbc_ctl; |
1042 | 1082 | ||
1043 | if (!I915_HAS_FBC(dev)) | 1083 | if (!I915_HAS_FBC(dev)) |
@@ -1052,16 +1092,11 @@ void i8xx_disable_fbc(struct drm_device *dev) | |||
1052 | I915_WRITE(FBC_CONTROL, fbc_ctl); | 1092 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
1053 | 1093 | ||
1054 | /* Wait for compressing bit to clear */ | 1094 | /* Wait for compressing bit to clear */ |
1055 | while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) { | 1095 | if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10, 0)) { |
1056 | if (time_after(jiffies, timeout)) { | 1096 | DRM_DEBUG_KMS("FBC idle timed out\n"); |
1057 | DRM_DEBUG_DRIVER("FBC idle timed out\n"); | 1097 | return; |
1058 | break; | ||
1059 | } | ||
1060 | ; /* do nothing */ | ||
1061 | } | 1098 | } |
1062 | 1099 | ||
1063 | intel_wait_for_vblank(dev); | ||
1064 | |||
1065 | DRM_DEBUG_KMS("disabled FBC\n"); | 1100 | DRM_DEBUG_KMS("disabled FBC\n"); |
1066 | } | 1101 | } |
1067 | 1102 | ||
@@ -1118,7 +1153,6 @@ void g4x_disable_fbc(struct drm_device *dev) | |||
1118 | dpfc_ctl = I915_READ(DPFC_CONTROL); | 1153 | dpfc_ctl = I915_READ(DPFC_CONTROL); |
1119 | dpfc_ctl &= ~DPFC_CTL_EN; | 1154 | dpfc_ctl &= ~DPFC_CTL_EN; |
1120 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); | 1155 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); |
1121 | intel_wait_for_vblank(dev); | ||
1122 | 1156 | ||
1123 | DRM_DEBUG_KMS("disabled FBC\n"); | 1157 | DRM_DEBUG_KMS("disabled FBC\n"); |
1124 | } | 1158 | } |
@@ -1179,7 +1213,6 @@ void ironlake_disable_fbc(struct drm_device *dev) | |||
1179 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | 1213 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); |
1180 | dpfc_ctl &= ~DPFC_CTL_EN; | 1214 | dpfc_ctl &= ~DPFC_CTL_EN; |
1181 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); | 1215 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); |
1182 | intel_wait_for_vblank(dev); | ||
1183 | 1216 | ||
1184 | DRM_DEBUG_KMS("disabled FBC\n"); | 1217 | DRM_DEBUG_KMS("disabled FBC\n"); |
1185 | } | 1218 | } |
@@ -1478,7 +1511,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1478 | if ((IS_I965G(dev) || plane == 0)) | 1511 | if ((IS_I965G(dev) || plane == 0)) |
1479 | intel_update_fbc(crtc, &crtc->mode); | 1512 | intel_update_fbc(crtc, &crtc->mode); |
1480 | 1513 | ||
1481 | intel_wait_for_vblank(dev); | 1514 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1482 | intel_increase_pllclock(crtc, true); | 1515 | intel_increase_pllclock(crtc, true); |
1483 | 1516 | ||
1484 | return 0; | 1517 | return 0; |
@@ -1585,20 +1618,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1585 | Start, Offset, x, y, crtc->fb->pitch); | 1618 | Start, Offset, x, y, crtc->fb->pitch); |
1586 | I915_WRITE(dspstride, crtc->fb->pitch); | 1619 | I915_WRITE(dspstride, crtc->fb->pitch); |
1587 | if (IS_I965G(dev)) { | 1620 | if (IS_I965G(dev)) { |
1588 | I915_WRITE(dspbase, Offset); | ||
1589 | I915_READ(dspbase); | ||
1590 | I915_WRITE(dspsurf, Start); | 1621 | I915_WRITE(dspsurf, Start); |
1591 | I915_READ(dspsurf); | ||
1592 | I915_WRITE(dsptileoff, (y << 16) | x); | 1622 | I915_WRITE(dsptileoff, (y << 16) | x); |
1623 | I915_WRITE(dspbase, Offset); | ||
1593 | } else { | 1624 | } else { |
1594 | I915_WRITE(dspbase, Start + Offset); | 1625 | I915_WRITE(dspbase, Start + Offset); |
1595 | I915_READ(dspbase); | ||
1596 | } | 1626 | } |
1627 | POSTING_READ(dspbase); | ||
1597 | 1628 | ||
1598 | if ((IS_I965G(dev) || plane == 0)) | 1629 | if ((IS_I965G(dev) || plane == 0)) |
1599 | intel_update_fbc(crtc, &crtc->mode); | 1630 | intel_update_fbc(crtc, &crtc->mode); |
1600 | 1631 | ||
1601 | intel_wait_for_vblank(dev); | 1632 | intel_wait_for_vblank(dev, pipe); |
1602 | 1633 | ||
1603 | if (old_fb) { | 1634 | if (old_fb) { |
1604 | intel_fb = to_intel_framebuffer(old_fb); | 1635 | intel_fb = to_intel_framebuffer(old_fb); |
@@ -1627,54 +1658,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1627 | return 0; | 1658 | return 0; |
1628 | } | 1659 | } |
1629 | 1660 | ||
1630 | /* Disable the VGA plane that we never use */ | ||
1631 | static void i915_disable_vga (struct drm_device *dev) | ||
1632 | { | ||
1633 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1634 | u8 sr1; | ||
1635 | u32 vga_reg; | ||
1636 | |||
1637 | if (HAS_PCH_SPLIT(dev)) | ||
1638 | vga_reg = CPU_VGACNTRL; | ||
1639 | else | ||
1640 | vga_reg = VGACNTRL; | ||
1641 | |||
1642 | if (I915_READ(vga_reg) & VGA_DISP_DISABLE) | ||
1643 | return; | ||
1644 | |||
1645 | I915_WRITE8(VGA_SR_INDEX, 1); | ||
1646 | sr1 = I915_READ8(VGA_SR_DATA); | ||
1647 | I915_WRITE8(VGA_SR_DATA, sr1 | (1 << 5)); | ||
1648 | udelay(100); | ||
1649 | |||
1650 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
1651 | } | ||
1652 | |||
1653 | static void ironlake_disable_pll_edp (struct drm_crtc *crtc) | ||
1654 | { | ||
1655 | struct drm_device *dev = crtc->dev; | ||
1656 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1657 | u32 dpa_ctl; | ||
1658 | |||
1659 | DRM_DEBUG_KMS("\n"); | ||
1660 | dpa_ctl = I915_READ(DP_A); | ||
1661 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
1662 | I915_WRITE(DP_A, dpa_ctl); | ||
1663 | } | ||
1664 | |||
1665 | static void ironlake_enable_pll_edp (struct drm_crtc *crtc) | ||
1666 | { | ||
1667 | struct drm_device *dev = crtc->dev; | ||
1668 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1669 | u32 dpa_ctl; | ||
1670 | |||
1671 | dpa_ctl = I915_READ(DP_A); | ||
1672 | dpa_ctl |= DP_PLL_ENABLE; | ||
1673 | I915_WRITE(DP_A, dpa_ctl); | ||
1674 | udelay(200); | ||
1675 | } | ||
1676 | |||
1677 | |||
1678 | static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) | 1661 | static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) |
1679 | { | 1662 | { |
1680 | struct drm_device *dev = crtc->dev; | 1663 | struct drm_device *dev = crtc->dev; |
@@ -1945,7 +1928,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1945 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; | 1928 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; |
1946 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; | 1929 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; |
1947 | u32 temp; | 1930 | u32 temp; |
1948 | int n; | ||
1949 | u32 pipe_bpc; | 1931 | u32 pipe_bpc; |
1950 | 1932 | ||
1951 | temp = I915_READ(pipeconf_reg); | 1933 | temp = I915_READ(pipeconf_reg); |
@@ -1958,7 +1940,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1958 | case DRM_MODE_DPMS_ON: | 1940 | case DRM_MODE_DPMS_ON: |
1959 | case DRM_MODE_DPMS_STANDBY: | 1941 | case DRM_MODE_DPMS_STANDBY: |
1960 | case DRM_MODE_DPMS_SUSPEND: | 1942 | case DRM_MODE_DPMS_SUSPEND: |
1961 | DRM_DEBUG_KMS("crtc %d dpms on\n", pipe); | 1943 | DRM_DEBUG_KMS("crtc %d/%d dpms on\n", pipe, plane); |
1962 | 1944 | ||
1963 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 1945 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
1964 | temp = I915_READ(PCH_LVDS); | 1946 | temp = I915_READ(PCH_LVDS); |
@@ -1968,10 +1950,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1968 | } | 1950 | } |
1969 | } | 1951 | } |
1970 | 1952 | ||
1971 | if (HAS_eDP) { | 1953 | if (!HAS_eDP) { |
1972 | /* enable eDP PLL */ | ||
1973 | ironlake_enable_pll_edp(crtc); | ||
1974 | } else { | ||
1975 | 1954 | ||
1976 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1955 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
1977 | temp = I915_READ(fdi_rx_reg); | 1956 | temp = I915_READ(fdi_rx_reg); |
@@ -2005,15 +1984,13 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2005 | /* Enable panel fitting for LVDS */ | 1984 | /* Enable panel fitting for LVDS */ |
2006 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) | 1985 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) |
2007 | || HAS_eDP || intel_pch_has_edp(crtc)) { | 1986 | || HAS_eDP || intel_pch_has_edp(crtc)) { |
2008 | temp = I915_READ(pf_ctl_reg); | 1987 | if (dev_priv->pch_pf_size) { |
2009 | I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); | 1988 | temp = I915_READ(pf_ctl_reg); |
2010 | 1989 | I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); | |
2011 | /* currently full aspect */ | 1990 | I915_WRITE(pf_win_pos, dev_priv->pch_pf_pos); |
2012 | I915_WRITE(pf_win_pos, 0); | 1991 | I915_WRITE(pf_win_size, dev_priv->pch_pf_size); |
2013 | 1992 | } else | |
2014 | I915_WRITE(pf_win_size, | 1993 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); |
2015 | (dev_priv->panel_fixed_mode->hdisplay << 16) | | ||
2016 | (dev_priv->panel_fixed_mode->vdisplay)); | ||
2017 | } | 1994 | } |
2018 | 1995 | ||
2019 | /* Enable CPU pipe */ | 1996 | /* Enable CPU pipe */ |
@@ -2097,9 +2074,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2097 | int reg; | 2074 | int reg; |
2098 | 2075 | ||
2099 | reg = I915_READ(trans_dp_ctl); | 2076 | reg = I915_READ(trans_dp_ctl); |
2100 | reg &= ~TRANS_DP_PORT_SEL_MASK; | 2077 | reg &= ~(TRANS_DP_PORT_SEL_MASK | |
2101 | reg = TRANS_DP_OUTPUT_ENABLE | | 2078 | TRANS_DP_SYNC_MASK); |
2102 | TRANS_DP_ENH_FRAMING; | 2079 | reg |= (TRANS_DP_OUTPUT_ENABLE | |
2080 | TRANS_DP_ENH_FRAMING); | ||
2103 | 2081 | ||
2104 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | 2082 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
2105 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; | 2083 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; |
@@ -2137,18 +2115,17 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2137 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | 2115 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); |
2138 | I915_READ(transconf_reg); | 2116 | I915_READ(transconf_reg); |
2139 | 2117 | ||
2140 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) | 2118 | if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 10, 0)) |
2141 | ; | 2119 | DRM_ERROR("failed to enable transcoder\n"); |
2142 | |||
2143 | } | 2120 | } |
2144 | 2121 | ||
2145 | intel_crtc_load_lut(crtc); | 2122 | intel_crtc_load_lut(crtc); |
2146 | 2123 | ||
2147 | intel_update_fbc(crtc, &crtc->mode); | 2124 | intel_update_fbc(crtc, &crtc->mode); |
2125 | break; | ||
2148 | 2126 | ||
2149 | break; | ||
2150 | case DRM_MODE_DPMS_OFF: | 2127 | case DRM_MODE_DPMS_OFF: |
2151 | DRM_DEBUG_KMS("crtc %d dpms off\n", pipe); | 2128 | DRM_DEBUG_KMS("crtc %d/%d dpms off\n", pipe, plane); |
2152 | 2129 | ||
2153 | drm_vblank_off(dev, pipe); | 2130 | drm_vblank_off(dev, pipe); |
2154 | /* Disable display plane */ | 2131 | /* Disable display plane */ |
@@ -2164,26 +2141,14 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2164 | dev_priv->display.disable_fbc) | 2141 | dev_priv->display.disable_fbc) |
2165 | dev_priv->display.disable_fbc(dev); | 2142 | dev_priv->display.disable_fbc(dev); |
2166 | 2143 | ||
2167 | i915_disable_vga(dev); | ||
2168 | |||
2169 | /* disable cpu pipe, disable after all planes disabled */ | 2144 | /* disable cpu pipe, disable after all planes disabled */ |
2170 | temp = I915_READ(pipeconf_reg); | 2145 | temp = I915_READ(pipeconf_reg); |
2171 | if ((temp & PIPEACONF_ENABLE) != 0) { | 2146 | if ((temp & PIPEACONF_ENABLE) != 0) { |
2172 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); | 2147 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); |
2173 | I915_READ(pipeconf_reg); | 2148 | |
2174 | n = 0; | ||
2175 | /* wait for cpu pipe off, pipe state */ | 2149 | /* wait for cpu pipe off, pipe state */ |
2176 | while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) { | 2150 | if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, 50, 1)) |
2177 | n++; | 2151 | DRM_ERROR("failed to turn off cpu pipe\n"); |
2178 | if (n < 60) { | ||
2179 | udelay(500); | ||
2180 | continue; | ||
2181 | } else { | ||
2182 | DRM_DEBUG_KMS("pipe %d off delay\n", | ||
2183 | pipe); | ||
2184 | break; | ||
2185 | } | ||
2186 | } | ||
2187 | } else | 2152 | } else |
2188 | DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); | 2153 | DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); |
2189 | 2154 | ||
@@ -2244,20 +2209,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2244 | temp = I915_READ(transconf_reg); | 2209 | temp = I915_READ(transconf_reg); |
2245 | if ((temp & TRANS_ENABLE) != 0) { | 2210 | if ((temp & TRANS_ENABLE) != 0) { |
2246 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); | 2211 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); |
2247 | I915_READ(transconf_reg); | 2212 | |
2248 | n = 0; | ||
2249 | /* wait for PCH transcoder off, transcoder state */ | 2213 | /* wait for PCH transcoder off, transcoder state */ |
2250 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) { | 2214 | if (wait_for((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0, 50, 1)) |
2251 | n++; | 2215 | DRM_ERROR("failed to disable transcoder\n"); |
2252 | if (n < 60) { | ||
2253 | udelay(500); | ||
2254 | continue; | ||
2255 | } else { | ||
2256 | DRM_DEBUG_KMS("transcoder %d off " | ||
2257 | "delay\n", pipe); | ||
2258 | break; | ||
2259 | } | ||
2260 | } | ||
2261 | } | 2216 | } |
2262 | 2217 | ||
2263 | temp = I915_READ(transconf_reg); | 2218 | temp = I915_READ(transconf_reg); |
@@ -2294,10 +2249,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2294 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); | 2249 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); |
2295 | I915_READ(pch_dpll_reg); | 2250 | I915_READ(pch_dpll_reg); |
2296 | 2251 | ||
2297 | if (HAS_eDP) { | ||
2298 | ironlake_disable_pll_edp(crtc); | ||
2299 | } | ||
2300 | |||
2301 | /* Switch from PCDclk to Rawclk */ | 2252 | /* Switch from PCDclk to Rawclk */ |
2302 | temp = I915_READ(fdi_rx_reg); | 2253 | temp = I915_READ(fdi_rx_reg); |
2303 | temp &= ~FDI_SEL_PCDCLK; | 2254 | temp &= ~FDI_SEL_PCDCLK; |
@@ -2372,8 +2323,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2372 | case DRM_MODE_DPMS_ON: | 2323 | case DRM_MODE_DPMS_ON: |
2373 | case DRM_MODE_DPMS_STANDBY: | 2324 | case DRM_MODE_DPMS_STANDBY: |
2374 | case DRM_MODE_DPMS_SUSPEND: | 2325 | case DRM_MODE_DPMS_SUSPEND: |
2375 | intel_update_watermarks(dev); | ||
2376 | |||
2377 | /* Enable the DPLL */ | 2326 | /* Enable the DPLL */ |
2378 | temp = I915_READ(dpll_reg); | 2327 | temp = I915_READ(dpll_reg); |
2379 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 2328 | if ((temp & DPLL_VCO_ENABLE) == 0) { |
@@ -2413,8 +2362,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2413 | intel_crtc_dpms_overlay(intel_crtc, true); | 2362 | intel_crtc_dpms_overlay(intel_crtc, true); |
2414 | break; | 2363 | break; |
2415 | case DRM_MODE_DPMS_OFF: | 2364 | case DRM_MODE_DPMS_OFF: |
2416 | intel_update_watermarks(dev); | ||
2417 | |||
2418 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 2365 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
2419 | intel_crtc_dpms_overlay(intel_crtc, false); | 2366 | intel_crtc_dpms_overlay(intel_crtc, false); |
2420 | drm_vblank_off(dev, pipe); | 2367 | drm_vblank_off(dev, pipe); |
@@ -2423,9 +2370,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2423 | dev_priv->display.disable_fbc) | 2370 | dev_priv->display.disable_fbc) |
2424 | dev_priv->display.disable_fbc(dev); | 2371 | dev_priv->display.disable_fbc(dev); |
2425 | 2372 | ||
2426 | /* Disable the VGA plane that we never use */ | ||
2427 | i915_disable_vga(dev); | ||
2428 | |||
2429 | /* Disable display plane */ | 2373 | /* Disable display plane */ |
2430 | temp = I915_READ(dspcntr_reg); | 2374 | temp = I915_READ(dspcntr_reg); |
2431 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { | 2375 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { |
@@ -2435,10 +2379,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2435 | I915_READ(dspbase_reg); | 2379 | I915_READ(dspbase_reg); |
2436 | } | 2380 | } |
2437 | 2381 | ||
2438 | if (!IS_I9XX(dev)) { | 2382 | /* Wait for vblank for the disable to take effect */ |
2439 | /* Wait for vblank for the disable to take effect */ | 2383 | intel_wait_for_vblank_off(dev, pipe); |
2440 | intel_wait_for_vblank(dev); | ||
2441 | } | ||
2442 | 2384 | ||
2443 | /* Don't disable pipe A or pipe A PLLs if needed */ | 2385 | /* Don't disable pipe A or pipe A PLLs if needed */ |
2444 | if (pipeconf_reg == PIPEACONF && | 2386 | if (pipeconf_reg == PIPEACONF && |
@@ -2453,7 +2395,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2453 | } | 2395 | } |
2454 | 2396 | ||
2455 | /* Wait for vblank for the disable to take effect. */ | 2397 | /* Wait for vblank for the disable to take effect. */ |
2456 | intel_wait_for_vblank(dev); | 2398 | intel_wait_for_vblank_off(dev, pipe); |
2457 | 2399 | ||
2458 | temp = I915_READ(dpll_reg); | 2400 | temp = I915_READ(dpll_reg); |
2459 | if ((temp & DPLL_VCO_ENABLE) != 0) { | 2401 | if ((temp & DPLL_VCO_ENABLE) != 0) { |
@@ -2469,9 +2411,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2469 | 2411 | ||
2470 | /** | 2412 | /** |
2471 | * Sets the power management mode of the pipe and plane. | 2413 | * Sets the power management mode of the pipe and plane. |
2472 | * | ||
2473 | * This code should probably grow support for turning the cursor off and back | ||
2474 | * on appropriately at the same time as we're turning the pipe off/on. | ||
2475 | */ | 2414 | */ |
2476 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | 2415 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) |
2477 | { | 2416 | { |
@@ -2482,9 +2421,26 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2482 | int pipe = intel_crtc->pipe; | 2421 | int pipe = intel_crtc->pipe; |
2483 | bool enabled; | 2422 | bool enabled; |
2484 | 2423 | ||
2424 | intel_crtc->dpms_mode = mode; | ||
2425 | intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON; | ||
2426 | |||
2427 | /* When switching on the display, ensure that SR is disabled | ||
2428 | * with multiple pipes prior to enabling to new pipe. | ||
2429 | * | ||
2430 | * When switching off the display, make sure the cursor is | ||
2431 | * properly hidden prior to disabling the pipe. | ||
2432 | */ | ||
2433 | if (mode == DRM_MODE_DPMS_ON) | ||
2434 | intel_update_watermarks(dev); | ||
2435 | else | ||
2436 | intel_crtc_update_cursor(crtc); | ||
2437 | |||
2485 | dev_priv->display.dpms(crtc, mode); | 2438 | dev_priv->display.dpms(crtc, mode); |
2486 | 2439 | ||
2487 | intel_crtc->dpms_mode = mode; | 2440 | if (mode == DRM_MODE_DPMS_ON) |
2441 | intel_crtc_update_cursor(crtc); | ||
2442 | else | ||
2443 | intel_update_watermarks(dev); | ||
2488 | 2444 | ||
2489 | if (!dev->primary->master) | 2445 | if (!dev->primary->master) |
2490 | return; | 2446 | return; |
@@ -2536,6 +2492,20 @@ void intel_encoder_commit (struct drm_encoder *encoder) | |||
2536 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); | 2492 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); |
2537 | } | 2493 | } |
2538 | 2494 | ||
2495 | void intel_encoder_destroy(struct drm_encoder *encoder) | ||
2496 | { | ||
2497 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
2498 | |||
2499 | if (intel_encoder->ddc_bus) | ||
2500 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
2501 | |||
2502 | if (intel_encoder->i2c_bus) | ||
2503 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
2504 | |||
2505 | drm_encoder_cleanup(encoder); | ||
2506 | kfree(intel_encoder); | ||
2507 | } | ||
2508 | |||
2539 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | 2509 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, |
2540 | struct drm_display_mode *mode, | 2510 | struct drm_display_mode *mode, |
2541 | struct drm_display_mode *adjusted_mode) | 2511 | struct drm_display_mode *adjusted_mode) |
@@ -2867,7 +2837,7 @@ struct cxsr_latency { | |||
2867 | unsigned long cursor_hpll_disable; | 2837 | unsigned long cursor_hpll_disable; |
2868 | }; | 2838 | }; |
2869 | 2839 | ||
2870 | static struct cxsr_latency cxsr_latency_table[] = { | 2840 | static const struct cxsr_latency cxsr_latency_table[] = { |
2871 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | 2841 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ |
2872 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | 2842 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ |
2873 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | 2843 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ |
@@ -2905,11 +2875,13 @@ static struct cxsr_latency cxsr_latency_table[] = { | |||
2905 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ | 2875 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ |
2906 | }; | 2876 | }; |
2907 | 2877 | ||
2908 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, | 2878 | static const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, |
2909 | int fsb, int mem) | 2879 | int is_ddr3, |
2880 | int fsb, | ||
2881 | int mem) | ||
2910 | { | 2882 | { |
2883 | const struct cxsr_latency *latency; | ||
2911 | int i; | 2884 | int i; |
2912 | struct cxsr_latency *latency; | ||
2913 | 2885 | ||
2914 | if (fsb == 0 || mem == 0) | 2886 | if (fsb == 0 || mem == 0) |
2915 | return NULL; | 2887 | return NULL; |
@@ -2930,13 +2902,9 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, | |||
2930 | static void pineview_disable_cxsr(struct drm_device *dev) | 2902 | static void pineview_disable_cxsr(struct drm_device *dev) |
2931 | { | 2903 | { |
2932 | struct drm_i915_private *dev_priv = dev->dev_private; | 2904 | struct drm_i915_private *dev_priv = dev->dev_private; |
2933 | u32 reg; | ||
2934 | 2905 | ||
2935 | /* deactivate cxsr */ | 2906 | /* deactivate cxsr */ |
2936 | reg = I915_READ(DSPFW3); | 2907 | I915_WRITE(DSPFW3, I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN); |
2937 | reg &= ~(PINEVIEW_SELF_REFRESH_EN); | ||
2938 | I915_WRITE(DSPFW3, reg); | ||
2939 | DRM_INFO("Big FIFO is disabled\n"); | ||
2940 | } | 2908 | } |
2941 | 2909 | ||
2942 | /* | 2910 | /* |
@@ -3024,12 +2992,12 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
3024 | int pixel_size) | 2992 | int pixel_size) |
3025 | { | 2993 | { |
3026 | struct drm_i915_private *dev_priv = dev->dev_private; | 2994 | struct drm_i915_private *dev_priv = dev->dev_private; |
2995 | const struct cxsr_latency *latency; | ||
3027 | u32 reg; | 2996 | u32 reg; |
3028 | unsigned long wm; | 2997 | unsigned long wm; |
3029 | struct cxsr_latency *latency; | ||
3030 | int sr_clock; | 2998 | int sr_clock; |
3031 | 2999 | ||
3032 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, | 3000 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, |
3033 | dev_priv->fsb_freq, dev_priv->mem_freq); | 3001 | dev_priv->fsb_freq, dev_priv->mem_freq); |
3034 | if (!latency) { | 3002 | if (!latency) { |
3035 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | 3003 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
@@ -3075,9 +3043,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
3075 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); | 3043 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); |
3076 | 3044 | ||
3077 | /* activate cxsr */ | 3045 | /* activate cxsr */ |
3078 | reg = I915_READ(DSPFW3); | 3046 | I915_WRITE(DSPFW3, |
3079 | reg |= PINEVIEW_SELF_REFRESH_EN; | 3047 | I915_READ(DSPFW3) | PINEVIEW_SELF_REFRESH_EN); |
3080 | I915_WRITE(DSPFW3, reg); | ||
3081 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); | 3048 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); |
3082 | } else { | 3049 | } else { |
3083 | pineview_disable_cxsr(dev); | 3050 | pineview_disable_cxsr(dev); |
@@ -3354,12 +3321,11 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
3354 | int line_count; | 3321 | int line_count; |
3355 | int planea_htotal = 0, planeb_htotal = 0; | 3322 | int planea_htotal = 0, planeb_htotal = 0; |
3356 | struct drm_crtc *crtc; | 3323 | struct drm_crtc *crtc; |
3357 | struct intel_crtc *intel_crtc; | ||
3358 | 3324 | ||
3359 | /* Need htotal for all active display plane */ | 3325 | /* Need htotal for all active display plane */ |
3360 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3326 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
3361 | intel_crtc = to_intel_crtc(crtc); | 3327 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3362 | if (crtc->enabled) { | 3328 | if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { |
3363 | if (intel_crtc->plane == 0) | 3329 | if (intel_crtc->plane == 0) |
3364 | planea_htotal = crtc->mode.htotal; | 3330 | planea_htotal = crtc->mode.htotal; |
3365 | else | 3331 | else |
@@ -3519,7 +3485,6 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
3519 | { | 3485 | { |
3520 | struct drm_i915_private *dev_priv = dev->dev_private; | 3486 | struct drm_i915_private *dev_priv = dev->dev_private; |
3521 | struct drm_crtc *crtc; | 3487 | struct drm_crtc *crtc; |
3522 | struct intel_crtc *intel_crtc; | ||
3523 | int sr_hdisplay = 0; | 3488 | int sr_hdisplay = 0; |
3524 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | 3489 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; |
3525 | int enabled = 0, pixel_size = 0; | 3490 | int enabled = 0, pixel_size = 0; |
@@ -3530,8 +3495,8 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
3530 | 3495 | ||
3531 | /* Get the clock config from both planes */ | 3496 | /* Get the clock config from both planes */ |
3532 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3497 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
3533 | intel_crtc = to_intel_crtc(crtc); | 3498 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3534 | if (crtc->enabled) { | 3499 | if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { |
3535 | enabled++; | 3500 | enabled++; |
3536 | if (intel_crtc->plane == 0) { | 3501 | if (intel_crtc->plane == 0) { |
3537 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", | 3502 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", |
@@ -3966,9 +3931,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3966 | dpll_reg = pch_dpll_reg; | 3931 | dpll_reg = pch_dpll_reg; |
3967 | } | 3932 | } |
3968 | 3933 | ||
3969 | if (is_edp) { | 3934 | if (!is_edp) { |
3970 | ironlake_disable_pll_edp(crtc); | ||
3971 | } else if ((dpll & DPLL_VCO_ENABLE)) { | ||
3972 | I915_WRITE(fp_reg, fp); | 3935 | I915_WRITE(fp_reg, fp); |
3973 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); | 3936 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); |
3974 | I915_READ(dpll_reg); | 3937 | I915_READ(dpll_reg); |
@@ -4167,7 +4130,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4167 | I915_WRITE(pipeconf_reg, pipeconf); | 4130 | I915_WRITE(pipeconf_reg, pipeconf); |
4168 | I915_READ(pipeconf_reg); | 4131 | I915_READ(pipeconf_reg); |
4169 | 4132 | ||
4170 | intel_wait_for_vblank(dev); | 4133 | intel_wait_for_vblank(dev, pipe); |
4171 | 4134 | ||
4172 | if (IS_IRONLAKE(dev)) { | 4135 | if (IS_IRONLAKE(dev)) { |
4173 | /* enable address swizzle for tiling buffer */ | 4136 | /* enable address swizzle for tiling buffer */ |
@@ -4180,9 +4143,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4180 | /* Flush the plane changes */ | 4143 | /* Flush the plane changes */ |
4181 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 4144 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
4182 | 4145 | ||
4183 | if ((IS_I965G(dev) || plane == 0)) | ||
4184 | intel_update_fbc(crtc, &crtc->mode); | ||
4185 | |||
4186 | intel_update_watermarks(dev); | 4146 | intel_update_watermarks(dev); |
4187 | 4147 | ||
4188 | drm_vblank_post_modeset(dev, pipe); | 4148 | drm_vblank_post_modeset(dev, pipe); |
@@ -4216,6 +4176,62 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) | |||
4216 | } | 4176 | } |
4217 | } | 4177 | } |
4218 | 4178 | ||
4179 | static void i845_update_cursor(struct drm_crtc *crtc, u32 base) | ||
4180 | { | ||
4181 | struct drm_device *dev = crtc->dev; | ||
4182 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4183 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
4184 | bool visible = base != 0; | ||
4185 | u32 cntl; | ||
4186 | |||
4187 | if (intel_crtc->cursor_visible == visible) | ||
4188 | return; | ||
4189 | |||
4190 | cntl = I915_READ(CURACNTR); | ||
4191 | if (visible) { | ||
4192 | /* On these chipsets we can only modify the base whilst | ||
4193 | * the cursor is disabled. | ||
4194 | */ | ||
4195 | I915_WRITE(CURABASE, base); | ||
4196 | |||
4197 | cntl &= ~(CURSOR_FORMAT_MASK); | ||
4198 | /* XXX width must be 64, stride 256 => 0x00 << 28 */ | ||
4199 | cntl |= CURSOR_ENABLE | | ||
4200 | CURSOR_GAMMA_ENABLE | | ||
4201 | CURSOR_FORMAT_ARGB; | ||
4202 | } else | ||
4203 | cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
4204 | I915_WRITE(CURACNTR, cntl); | ||
4205 | |||
4206 | intel_crtc->cursor_visible = visible; | ||
4207 | } | ||
4208 | |||
4209 | static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) | ||
4210 | { | ||
4211 | struct drm_device *dev = crtc->dev; | ||
4212 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4213 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
4214 | int pipe = intel_crtc->pipe; | ||
4215 | bool visible = base != 0; | ||
4216 | |||
4217 | if (intel_crtc->cursor_visible != visible) { | ||
4218 | uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); | ||
4219 | if (base) { | ||
4220 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
4221 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
4222 | cntl |= pipe << 28; /* Connect to correct pipe */ | ||
4223 | } else { | ||
4224 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
4225 | cntl |= CURSOR_MODE_DISABLE; | ||
4226 | } | ||
4227 | I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); | ||
4228 | |||
4229 | intel_crtc->cursor_visible = visible; | ||
4230 | } | ||
4231 | /* and commit changes on next vblank */ | ||
4232 | I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); | ||
4233 | } | ||
4234 | |||
4219 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ | 4235 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ |
4220 | static void intel_crtc_update_cursor(struct drm_crtc *crtc) | 4236 | static void intel_crtc_update_cursor(struct drm_crtc *crtc) |
4221 | { | 4237 | { |
@@ -4225,12 +4241,12 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) | |||
4225 | int pipe = intel_crtc->pipe; | 4241 | int pipe = intel_crtc->pipe; |
4226 | int x = intel_crtc->cursor_x; | 4242 | int x = intel_crtc->cursor_x; |
4227 | int y = intel_crtc->cursor_y; | 4243 | int y = intel_crtc->cursor_y; |
4228 | uint32_t base, pos; | 4244 | u32 base, pos; |
4229 | bool visible; | 4245 | bool visible; |
4230 | 4246 | ||
4231 | pos = 0; | 4247 | pos = 0; |
4232 | 4248 | ||
4233 | if (crtc->fb) { | 4249 | if (intel_crtc->cursor_on && crtc->fb) { |
4234 | base = intel_crtc->cursor_addr; | 4250 | base = intel_crtc->cursor_addr; |
4235 | if (x > (int) crtc->fb->width) | 4251 | if (x > (int) crtc->fb->width) |
4236 | base = 0; | 4252 | base = 0; |
@@ -4259,37 +4275,14 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) | |||
4259 | pos |= y << CURSOR_Y_SHIFT; | 4275 | pos |= y << CURSOR_Y_SHIFT; |
4260 | 4276 | ||
4261 | visible = base != 0; | 4277 | visible = base != 0; |
4262 | if (!visible && !intel_crtc->cursor_visble) | 4278 | if (!visible && !intel_crtc->cursor_visible) |
4263 | return; | 4279 | return; |
4264 | 4280 | ||
4265 | I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); | 4281 | I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); |
4266 | if (intel_crtc->cursor_visble != visible) { | 4282 | if (IS_845G(dev) || IS_I865G(dev)) |
4267 | uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); | 4283 | i845_update_cursor(crtc, base); |
4268 | if (base) { | 4284 | else |
4269 | /* Hooray for CUR*CNTR differences */ | 4285 | i9xx_update_cursor(crtc, base); |
4270 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
4271 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
4272 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
4273 | cntl |= pipe << 28; /* Connect to correct pipe */ | ||
4274 | } else { | ||
4275 | cntl &= ~(CURSOR_FORMAT_MASK); | ||
4276 | cntl |= CURSOR_ENABLE; | ||
4277 | cntl |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; | ||
4278 | } | ||
4279 | } else { | ||
4280 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
4281 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
4282 | cntl |= CURSOR_MODE_DISABLE; | ||
4283 | } else { | ||
4284 | cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
4285 | } | ||
4286 | } | ||
4287 | I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); | ||
4288 | |||
4289 | intel_crtc->cursor_visble = visible; | ||
4290 | } | ||
4291 | /* and commit changes on next vblank */ | ||
4292 | I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); | ||
4293 | 4286 | ||
4294 | if (visible) | 4287 | if (visible) |
4295 | intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); | 4288 | intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); |
@@ -4354,8 +4347,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4354 | 4347 | ||
4355 | addr = obj_priv->gtt_offset; | 4348 | addr = obj_priv->gtt_offset; |
4356 | } else { | 4349 | } else { |
4350 | int align = IS_I830(dev) ? 16 * 1024 : 256; | ||
4357 | ret = i915_gem_attach_phys_object(dev, bo, | 4351 | ret = i915_gem_attach_phys_object(dev, bo, |
4358 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); | 4352 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, |
4353 | align); | ||
4359 | if (ret) { | 4354 | if (ret) { |
4360 | DRM_ERROR("failed to attach phys object\n"); | 4355 | DRM_ERROR("failed to attach phys object\n"); |
4361 | goto fail_locked; | 4356 | goto fail_locked; |
@@ -4544,7 +4539,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | |||
4544 | encoder_funcs->commit(encoder); | 4539 | encoder_funcs->commit(encoder); |
4545 | } | 4540 | } |
4546 | /* let the connector get through one full cycle before testing */ | 4541 | /* let the connector get through one full cycle before testing */ |
4547 | intel_wait_for_vblank(dev); | 4542 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
4548 | 4543 | ||
4549 | return crtc; | 4544 | return crtc; |
4550 | } | 4545 | } |
@@ -4749,7 +4744,7 @@ static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule) | |||
4749 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; | 4744 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; |
4750 | I915_WRITE(dpll_reg, dpll); | 4745 | I915_WRITE(dpll_reg, dpll); |
4751 | dpll = I915_READ(dpll_reg); | 4746 | dpll = I915_READ(dpll_reg); |
4752 | intel_wait_for_vblank(dev); | 4747 | intel_wait_for_vblank(dev, pipe); |
4753 | dpll = I915_READ(dpll_reg); | 4748 | dpll = I915_READ(dpll_reg); |
4754 | if (dpll & DISPLAY_RATE_SELECT_FPA1) | 4749 | if (dpll & DISPLAY_RATE_SELECT_FPA1) |
4755 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); | 4750 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); |
@@ -4793,7 +4788,7 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) | |||
4793 | dpll |= DISPLAY_RATE_SELECT_FPA1; | 4788 | dpll |= DISPLAY_RATE_SELECT_FPA1; |
4794 | I915_WRITE(dpll_reg, dpll); | 4789 | I915_WRITE(dpll_reg, dpll); |
4795 | dpll = I915_READ(dpll_reg); | 4790 | dpll = I915_READ(dpll_reg); |
4796 | intel_wait_for_vblank(dev); | 4791 | intel_wait_for_vblank(dev, pipe); |
4797 | dpll = I915_READ(dpll_reg); | 4792 | dpll = I915_READ(dpll_reg); |
4798 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) | 4793 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) |
4799 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); | 4794 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); |
@@ -5083,14 +5078,16 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5083 | work->pending_flip_obj = obj; | 5078 | work->pending_flip_obj = obj; |
5084 | 5079 | ||
5085 | if (intel_crtc->plane) | 5080 | if (intel_crtc->plane) |
5086 | flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; | 5081 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; |
5087 | else | 5082 | else |
5088 | flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT; | 5083 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; |
5089 | 5084 | ||
5090 | /* Wait for any previous flip to finish */ | 5085 | if (IS_GEN3(dev) || IS_GEN2(dev)) { |
5091 | if (IS_GEN3(dev)) | 5086 | BEGIN_LP_RING(2); |
5092 | while (I915_READ(ISR) & flip_mask) | 5087 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); |
5093 | ; | 5088 | OUT_RING(0); |
5089 | ADVANCE_LP_RING(); | ||
5090 | } | ||
5094 | 5091 | ||
5095 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | 5092 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ |
5096 | offset = obj_priv->gtt_offset; | 5093 | offset = obj_priv->gtt_offset; |
@@ -5104,12 +5101,18 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5104 | OUT_RING(offset | obj_priv->tiling_mode); | 5101 | OUT_RING(offset | obj_priv->tiling_mode); |
5105 | pipesrc = I915_READ(pipesrc_reg); | 5102 | pipesrc = I915_READ(pipesrc_reg); |
5106 | OUT_RING(pipesrc & 0x0fff0fff); | 5103 | OUT_RING(pipesrc & 0x0fff0fff); |
5107 | } else { | 5104 | } else if (IS_GEN3(dev)) { |
5108 | OUT_RING(MI_DISPLAY_FLIP_I915 | | 5105 | OUT_RING(MI_DISPLAY_FLIP_I915 | |
5109 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5106 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
5110 | OUT_RING(fb->pitch); | 5107 | OUT_RING(fb->pitch); |
5111 | OUT_RING(offset); | 5108 | OUT_RING(offset); |
5112 | OUT_RING(MI_NOOP); | 5109 | OUT_RING(MI_NOOP); |
5110 | } else { | ||
5111 | OUT_RING(MI_DISPLAY_FLIP | | ||
5112 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
5113 | OUT_RING(fb->pitch); | ||
5114 | OUT_RING(offset); | ||
5115 | OUT_RING(MI_NOOP); | ||
5113 | } | 5116 | } |
5114 | ADVANCE_LP_RING(); | 5117 | ADVANCE_LP_RING(); |
5115 | 5118 | ||
@@ -5432,37 +5435,37 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { | |||
5432 | }; | 5435 | }; |
5433 | 5436 | ||
5434 | static struct drm_gem_object * | 5437 | static struct drm_gem_object * |
5435 | intel_alloc_power_context(struct drm_device *dev) | 5438 | intel_alloc_context_page(struct drm_device *dev) |
5436 | { | 5439 | { |
5437 | struct drm_gem_object *pwrctx; | 5440 | struct drm_gem_object *ctx; |
5438 | int ret; | 5441 | int ret; |
5439 | 5442 | ||
5440 | pwrctx = i915_gem_alloc_object(dev, 4096); | 5443 | ctx = i915_gem_alloc_object(dev, 4096); |
5441 | if (!pwrctx) { | 5444 | if (!ctx) { |
5442 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); | 5445 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); |
5443 | return NULL; | 5446 | return NULL; |
5444 | } | 5447 | } |
5445 | 5448 | ||
5446 | mutex_lock(&dev->struct_mutex); | 5449 | mutex_lock(&dev->struct_mutex); |
5447 | ret = i915_gem_object_pin(pwrctx, 4096); | 5450 | ret = i915_gem_object_pin(ctx, 4096); |
5448 | if (ret) { | 5451 | if (ret) { |
5449 | DRM_ERROR("failed to pin power context: %d\n", ret); | 5452 | DRM_ERROR("failed to pin power context: %d\n", ret); |
5450 | goto err_unref; | 5453 | goto err_unref; |
5451 | } | 5454 | } |
5452 | 5455 | ||
5453 | ret = i915_gem_object_set_to_gtt_domain(pwrctx, 1); | 5456 | ret = i915_gem_object_set_to_gtt_domain(ctx, 1); |
5454 | if (ret) { | 5457 | if (ret) { |
5455 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); | 5458 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); |
5456 | goto err_unpin; | 5459 | goto err_unpin; |
5457 | } | 5460 | } |
5458 | mutex_unlock(&dev->struct_mutex); | 5461 | mutex_unlock(&dev->struct_mutex); |
5459 | 5462 | ||
5460 | return pwrctx; | 5463 | return ctx; |
5461 | 5464 | ||
5462 | err_unpin: | 5465 | err_unpin: |
5463 | i915_gem_object_unpin(pwrctx); | 5466 | i915_gem_object_unpin(ctx); |
5464 | err_unref: | 5467 | err_unref: |
5465 | drm_gem_object_unreference(pwrctx); | 5468 | drm_gem_object_unreference(ctx); |
5466 | mutex_unlock(&dev->struct_mutex); | 5469 | mutex_unlock(&dev->struct_mutex); |
5467 | return NULL; | 5470 | return NULL; |
5468 | } | 5471 | } |
@@ -5494,7 +5497,6 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5494 | struct drm_i915_private *dev_priv = dev->dev_private; | 5497 | struct drm_i915_private *dev_priv = dev->dev_private; |
5495 | u32 rgvmodectl = I915_READ(MEMMODECTL); | 5498 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
5496 | u8 fmax, fmin, fstart, vstart; | 5499 | u8 fmax, fmin, fstart, vstart; |
5497 | int i = 0; | ||
5498 | 5500 | ||
5499 | /* 100ms RC evaluation intervals */ | 5501 | /* 100ms RC evaluation intervals */ |
5500 | I915_WRITE(RCUPEI, 100000); | 5502 | I915_WRITE(RCUPEI, 100000); |
@@ -5538,13 +5540,8 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5538 | rgvmodectl |= MEMMODE_SWMODE_EN; | 5540 | rgvmodectl |= MEMMODE_SWMODE_EN; |
5539 | I915_WRITE(MEMMODECTL, rgvmodectl); | 5541 | I915_WRITE(MEMMODECTL, rgvmodectl); |
5540 | 5542 | ||
5541 | while (I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) { | 5543 | if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 1, 0)) |
5542 | if (i++ > 100) { | 5544 | DRM_ERROR("stuck trying to change perf mode\n"); |
5543 | DRM_ERROR("stuck trying to change perf mode\n"); | ||
5544 | break; | ||
5545 | } | ||
5546 | msleep(1); | ||
5547 | } | ||
5548 | msleep(1); | 5545 | msleep(1); |
5549 | 5546 | ||
5550 | ironlake_set_drps(dev, fstart); | 5547 | ironlake_set_drps(dev, fstart); |
@@ -5725,7 +5722,8 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5725 | ILK_DPFC_DIS2 | | 5722 | ILK_DPFC_DIS2 | |
5726 | ILK_CLK_FBC); | 5723 | ILK_CLK_FBC); |
5727 | } | 5724 | } |
5728 | return; | 5725 | if (IS_GEN6(dev)) |
5726 | return; | ||
5729 | } else if (IS_G4X(dev)) { | 5727 | } else if (IS_G4X(dev)) { |
5730 | uint32_t dspclk_gate; | 5728 | uint32_t dspclk_gate; |
5731 | I915_WRITE(RENCLK_GATE_D1, 0); | 5729 | I915_WRITE(RENCLK_GATE_D1, 0); |
@@ -5768,6 +5766,31 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5768 | * GPU can automatically power down the render unit if given a page | 5766 | * GPU can automatically power down the render unit if given a page |
5769 | * to save state. | 5767 | * to save state. |
5770 | */ | 5768 | */ |
5769 | if (IS_IRONLAKE_M(dev)) { | ||
5770 | if (dev_priv->renderctx == NULL) | ||
5771 | dev_priv->renderctx = intel_alloc_context_page(dev); | ||
5772 | if (dev_priv->renderctx) { | ||
5773 | struct drm_i915_gem_object *obj_priv; | ||
5774 | obj_priv = to_intel_bo(dev_priv->renderctx); | ||
5775 | if (obj_priv) { | ||
5776 | BEGIN_LP_RING(4); | ||
5777 | OUT_RING(MI_SET_CONTEXT); | ||
5778 | OUT_RING(obj_priv->gtt_offset | | ||
5779 | MI_MM_SPACE_GTT | | ||
5780 | MI_SAVE_EXT_STATE_EN | | ||
5781 | MI_RESTORE_EXT_STATE_EN | | ||
5782 | MI_RESTORE_INHIBIT); | ||
5783 | OUT_RING(MI_NOOP); | ||
5784 | OUT_RING(MI_FLUSH); | ||
5785 | ADVANCE_LP_RING(); | ||
5786 | } | ||
5787 | } else { | ||
5788 | DRM_DEBUG_KMS("Failed to allocate render context." | ||
5789 | "Disable RC6\n"); | ||
5790 | return; | ||
5791 | } | ||
5792 | } | ||
5793 | |||
5771 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { | 5794 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { |
5772 | struct drm_i915_gem_object *obj_priv = NULL; | 5795 | struct drm_i915_gem_object *obj_priv = NULL; |
5773 | 5796 | ||
@@ -5776,7 +5799,7 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5776 | } else { | 5799 | } else { |
5777 | struct drm_gem_object *pwrctx; | 5800 | struct drm_gem_object *pwrctx; |
5778 | 5801 | ||
5779 | pwrctx = intel_alloc_power_context(dev); | 5802 | pwrctx = intel_alloc_context_page(dev); |
5780 | if (pwrctx) { | 5803 | if (pwrctx) { |
5781 | dev_priv->pwrctx = pwrctx; | 5804 | dev_priv->pwrctx = pwrctx; |
5782 | obj_priv = to_intel_bo(pwrctx); | 5805 | obj_priv = to_intel_bo(pwrctx); |
@@ -5948,6 +5971,29 @@ static void intel_init_quirks(struct drm_device *dev) | |||
5948 | } | 5971 | } |
5949 | } | 5972 | } |
5950 | 5973 | ||
5974 | /* Disable the VGA plane that we never use */ | ||
5975 | static void i915_disable_vga(struct drm_device *dev) | ||
5976 | { | ||
5977 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5978 | u8 sr1; | ||
5979 | u32 vga_reg; | ||
5980 | |||
5981 | if (HAS_PCH_SPLIT(dev)) | ||
5982 | vga_reg = CPU_VGACNTRL; | ||
5983 | else | ||
5984 | vga_reg = VGACNTRL; | ||
5985 | |||
5986 | vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); | ||
5987 | outb(1, VGA_SR_INDEX); | ||
5988 | sr1 = inb(VGA_SR_DATA); | ||
5989 | outb(sr1 | 1<<5, VGA_SR_DATA); | ||
5990 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); | ||
5991 | udelay(300); | ||
5992 | |||
5993 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
5994 | POSTING_READ(vga_reg); | ||
5995 | } | ||
5996 | |||
5951 | void intel_modeset_init(struct drm_device *dev) | 5997 | void intel_modeset_init(struct drm_device *dev) |
5952 | { | 5998 | { |
5953 | struct drm_i915_private *dev_priv = dev->dev_private; | 5999 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -5996,6 +6042,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
5996 | 6042 | ||
5997 | intel_init_clock_gating(dev); | 6043 | intel_init_clock_gating(dev); |
5998 | 6044 | ||
6045 | /* Just disable it once at startup */ | ||
6046 | i915_disable_vga(dev); | ||
6047 | |||
5999 | if (IS_IRONLAKE_M(dev)) { | 6048 | if (IS_IRONLAKE_M(dev)) { |
6000 | ironlake_enable_drps(dev); | 6049 | ironlake_enable_drps(dev); |
6001 | intel_init_emon(dev); | 6050 | intel_init_emon(dev); |
@@ -6034,6 +6083,16 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
6034 | if (dev_priv->display.disable_fbc) | 6083 | if (dev_priv->display.disable_fbc) |
6035 | dev_priv->display.disable_fbc(dev); | 6084 | dev_priv->display.disable_fbc(dev); |
6036 | 6085 | ||
6086 | if (dev_priv->renderctx) { | ||
6087 | struct drm_i915_gem_object *obj_priv; | ||
6088 | |||
6089 | obj_priv = to_intel_bo(dev_priv->renderctx); | ||
6090 | I915_WRITE(CCID, obj_priv->gtt_offset &~ CCID_EN); | ||
6091 | I915_READ(CCID); | ||
6092 | i915_gem_object_unpin(dev_priv->renderctx); | ||
6093 | drm_gem_object_unreference(dev_priv->renderctx); | ||
6094 | } | ||
6095 | |||
6037 | if (dev_priv->pwrctx) { | 6096 | if (dev_priv->pwrctx) { |
6038 | struct drm_i915_gem_object *obj_priv; | 6097 | struct drm_i915_gem_object *obj_priv; |
6039 | 6098 | ||