diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 309 |
2 files changed, 231 insertions, 98 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2f89c2136be9..ebdc639e9858 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -153,6 +153,23 @@ struct drm_i915_error_state { | |||
153 | struct timeval time; | 153 | struct timeval time; |
154 | }; | 154 | }; |
155 | 155 | ||
156 | struct drm_i915_display_funcs { | ||
157 | void (*dpms)(struct drm_crtc *crtc, int mode); | ||
158 | bool (*fbc_enabled)(struct drm_crtc *crtc); | ||
159 | void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); | ||
160 | void (*disable_fbc)(struct drm_device *dev); | ||
161 | int (*get_display_clock_speed)(struct drm_device *dev); | ||
162 | int (*get_fifo_size)(struct drm_device *dev, int plane); | ||
163 | void (*update_wm)(struct drm_device *dev, int planea_clock, | ||
164 | int planeb_clock, int sr_hdisplay, int pixel_size); | ||
165 | /* clock updates for mode set */ | ||
166 | /* cursor updates */ | ||
167 | /* render clock increase/decrease */ | ||
168 | /* display clock increase/decrease */ | ||
169 | /* pll clock increase/decrease */ | ||
170 | /* clock gating init */ | ||
171 | }; | ||
172 | |||
156 | typedef struct drm_i915_private { | 173 | typedef struct drm_i915_private { |
157 | struct drm_device *dev; | 174 | struct drm_device *dev; |
158 | 175 | ||
@@ -252,6 +269,9 @@ typedef struct drm_i915_private { | |||
252 | struct work_struct error_work; | 269 | struct work_struct error_work; |
253 | struct workqueue_struct *wq; | 270 | struct workqueue_struct *wq; |
254 | 271 | ||
272 | /* Display functions */ | ||
273 | struct drm_i915_display_funcs display; | ||
274 | |||
255 | /* Register state */ | 275 | /* Register state */ |
256 | bool suspended; | 276 | bool suspended; |
257 | u8 saveLBB; | 277 | u8 saveLBB; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cb0f4f96439e..bac6c510fbaf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1064,6 +1064,11 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1064 | if (!i915_powersave) | 1064 | if (!i915_powersave) |
1065 | return; | 1065 | return; |
1066 | 1066 | ||
1067 | if (!dev_priv->display.fbc_enabled || | ||
1068 | !dev_priv->display.enable_fbc || | ||
1069 | !dev_priv->display.disable_fbc) | ||
1070 | return; | ||
1071 | |||
1067 | if (!crtc->fb) | 1072 | if (!crtc->fb) |
1068 | return; | 1073 | return; |
1069 | 1074 | ||
@@ -1101,19 +1106,19 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1101 | goto out_disable; | 1106 | goto out_disable; |
1102 | } | 1107 | } |
1103 | 1108 | ||
1104 | if (i8xx_fbc_enabled(crtc)) { | 1109 | if (dev_priv->display.fbc_enabled(crtc)) { |
1105 | /* We can re-enable it in this case, but need to update pitch */ | 1110 | /* We can re-enable it in this case, but need to update pitch */ |
1106 | if (fb->pitch > dev_priv->cfb_pitch) | 1111 | if (fb->pitch > dev_priv->cfb_pitch) |
1107 | i8xx_disable_fbc(dev); | 1112 | dev_priv->display.disable_fbc(dev); |
1108 | if (obj_priv->fence_reg != dev_priv->cfb_fence) | 1113 | if (obj_priv->fence_reg != dev_priv->cfb_fence) |
1109 | i8xx_disable_fbc(dev); | 1114 | dev_priv->display.disable_fbc(dev); |
1110 | if (plane != dev_priv->cfb_plane) | 1115 | if (plane != dev_priv->cfb_plane) |
1111 | i8xx_disable_fbc(dev); | 1116 | dev_priv->display.disable_fbc(dev); |
1112 | } | 1117 | } |
1113 | 1118 | ||
1114 | if (!i8xx_fbc_enabled(crtc)) { | 1119 | if (!dev_priv->display.fbc_enabled(crtc)) { |
1115 | /* Now try to turn it back on if possible */ | 1120 | /* Now try to turn it back on if possible */ |
1116 | i8xx_enable_fbc(crtc, 500); | 1121 | dev_priv->display.enable_fbc(crtc, 500); |
1117 | } | 1122 | } |
1118 | 1123 | ||
1119 | return; | 1124 | return; |
@@ -1121,8 +1126,8 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1121 | out_disable: | 1126 | out_disable: |
1122 | DRM_DEBUG("unsupported config, disabling FBC\n"); | 1127 | DRM_DEBUG("unsupported config, disabling FBC\n"); |
1123 | /* Multiple disables should be harmless */ | 1128 | /* Multiple disables should be harmless */ |
1124 | if (i8xx_fbc_enabled(crtc)) | 1129 | if (dev_priv->display.fbc_enabled(crtc)) |
1125 | i8xx_disable_fbc(dev); | 1130 | dev_priv->display.disable_fbc(dev); |
1126 | } | 1131 | } |
1127 | 1132 | ||
1128 | static int | 1133 | static int |
@@ -1769,8 +1774,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1769 | 1774 | ||
1770 | intel_crtc_load_lut(crtc); | 1775 | intel_crtc_load_lut(crtc); |
1771 | 1776 | ||
1772 | if (I915_HAS_FBC(dev) && (IS_I965G(dev) || plane == 0)) | 1777 | intel_update_fbc(crtc, &crtc->mode); |
1773 | intel_update_fbc(crtc, &crtc->mode); | ||
1774 | 1778 | ||
1775 | /* Give the overlay scaler a chance to enable if it's on this pipe */ | 1779 | /* Give the overlay scaler a chance to enable if it's on this pipe */ |
1776 | //intel_crtc_dpms_video(crtc, true); TODO | 1780 | //intel_crtc_dpms_video(crtc, true); TODO |
@@ -1781,8 +1785,9 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1781 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 1785 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
1782 | //intel_crtc_dpms_video(crtc, FALSE); TODO | 1786 | //intel_crtc_dpms_video(crtc, FALSE); TODO |
1783 | 1787 | ||
1784 | if (dev_priv->cfb_plane == plane) | 1788 | if (dev_priv->cfb_plane == plane && |
1785 | i8xx_disable_fbc(dev); | 1789 | dev_priv->display.disable_fbc) |
1790 | dev_priv->display.disable_fbc(dev); | ||
1786 | 1791 | ||
1787 | /* Disable the VGA plane that we never use */ | 1792 | /* Disable the VGA plane that we never use */ |
1788 | i915_disable_vga(dev); | 1793 | i915_disable_vga(dev); |
@@ -1832,15 +1837,13 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1832 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | 1837 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) |
1833 | { | 1838 | { |
1834 | struct drm_device *dev = crtc->dev; | 1839 | struct drm_device *dev = crtc->dev; |
1840 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1835 | struct drm_i915_master_private *master_priv; | 1841 | struct drm_i915_master_private *master_priv; |
1836 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1842 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1837 | int pipe = intel_crtc->pipe; | 1843 | int pipe = intel_crtc->pipe; |
1838 | bool enabled; | 1844 | bool enabled; |
1839 | 1845 | ||
1840 | if (IS_IGDNG(dev)) | 1846 | dev_priv->display.dpms(crtc, mode); |
1841 | igdng_crtc_dpms(crtc, mode); | ||
1842 | else | ||
1843 | i9xx_crtc_dpms(crtc, mode); | ||
1844 | 1847 | ||
1845 | intel_crtc->dpms_mode = mode; | 1848 | intel_crtc->dpms_mode = mode; |
1846 | 1849 | ||
@@ -1907,56 +1910,68 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | |||
1907 | return true; | 1910 | return true; |
1908 | } | 1911 | } |
1909 | 1912 | ||
1913 | static int i945_get_display_clock_speed(struct drm_device *dev) | ||
1914 | { | ||
1915 | return 400000; | ||
1916 | } | ||
1910 | 1917 | ||
1911 | /** Returns the core display clock speed for i830 - i945 */ | 1918 | static int i915_get_display_clock_speed(struct drm_device *dev) |
1912 | static int intel_get_core_clock_speed(struct drm_device *dev) | ||
1913 | { | 1919 | { |
1920 | return 333000; | ||
1921 | } | ||
1914 | 1922 | ||
1915 | /* Core clock values taken from the published datasheets. | 1923 | static int i9xx_misc_get_display_clock_speed(struct drm_device *dev) |
1916 | * The 830 may go up to 166 Mhz, which we should check. | 1924 | { |
1917 | */ | 1925 | return 200000; |
1918 | if (IS_I945G(dev)) | 1926 | } |
1919 | return 400000; | ||
1920 | else if (IS_I915G(dev)) | ||
1921 | return 333000; | ||
1922 | else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev)) | ||
1923 | return 200000; | ||
1924 | else if (IS_I915GM(dev)) { | ||
1925 | u16 gcfgc = 0; | ||
1926 | 1927 | ||
1927 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | 1928 | static int i915gm_get_display_clock_speed(struct drm_device *dev) |
1929 | { | ||
1930 | u16 gcfgc = 0; | ||
1928 | 1931 | ||
1929 | if (gcfgc & GC_LOW_FREQUENCY_ENABLE) | 1932 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); |
1930 | return 133000; | 1933 | |
1931 | else { | 1934 | if (gcfgc & GC_LOW_FREQUENCY_ENABLE) |
1932 | switch (gcfgc & GC_DISPLAY_CLOCK_MASK) { | 1935 | return 133000; |
1933 | case GC_DISPLAY_CLOCK_333_MHZ: | 1936 | else { |
1934 | return 333000; | 1937 | switch (gcfgc & GC_DISPLAY_CLOCK_MASK) { |
1935 | default: | 1938 | case GC_DISPLAY_CLOCK_333_MHZ: |
1936 | case GC_DISPLAY_CLOCK_190_200_MHZ: | 1939 | return 333000; |
1937 | return 190000; | 1940 | default: |
1938 | } | 1941 | case GC_DISPLAY_CLOCK_190_200_MHZ: |
1939 | } | 1942 | return 190000; |
1940 | } else if (IS_I865G(dev)) | ||
1941 | return 266000; | ||
1942 | else if (IS_I855(dev)) { | ||
1943 | u16 hpllcc = 0; | ||
1944 | /* Assume that the hardware is in the high speed state. This | ||
1945 | * should be the default. | ||
1946 | */ | ||
1947 | switch (hpllcc & GC_CLOCK_CONTROL_MASK) { | ||
1948 | case GC_CLOCK_133_200: | ||
1949 | case GC_CLOCK_100_200: | ||
1950 | return 200000; | ||
1951 | case GC_CLOCK_166_250: | ||
1952 | return 250000; | ||
1953 | case GC_CLOCK_100_133: | ||
1954 | return 133000; | ||
1955 | } | 1943 | } |
1956 | } else /* 852, 830 */ | 1944 | } |
1945 | } | ||
1946 | |||
1947 | static int i865_get_display_clock_speed(struct drm_device *dev) | ||
1948 | { | ||
1949 | return 266000; | ||
1950 | } | ||
1951 | |||
1952 | static int i855_get_display_clock_speed(struct drm_device *dev) | ||
1953 | { | ||
1954 | u16 hpllcc = 0; | ||
1955 | /* Assume that the hardware is in the high speed state. This | ||
1956 | * should be the default. | ||
1957 | */ | ||
1958 | switch (hpllcc & GC_CLOCK_CONTROL_MASK) { | ||
1959 | case GC_CLOCK_133_200: | ||
1960 | case GC_CLOCK_100_200: | ||
1961 | return 200000; | ||
1962 | case GC_CLOCK_166_250: | ||
1963 | return 250000; | ||
1964 | case GC_CLOCK_100_133: | ||
1957 | return 133000; | 1965 | return 133000; |
1966 | } | ||
1958 | 1967 | ||
1959 | return 0; /* Silence gcc warning */ | 1968 | /* Shouldn't happen */ |
1969 | return 0; | ||
1970 | } | ||
1971 | |||
1972 | static int i830_get_display_clock_speed(struct drm_device *dev) | ||
1973 | { | ||
1974 | return 133000; | ||
1960 | } | 1975 | } |
1961 | 1976 | ||
1962 | /** | 1977 | /** |
@@ -2288,32 +2303,17 @@ static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock, | |||
2288 | */ | 2303 | */ |
2289 | const static int latency_ns = 5000; | 2304 | const static int latency_ns = 5000; |
2290 | 2305 | ||
2291 | static int intel_get_fifo_size(struct drm_device *dev, int plane) | 2306 | static int i9xx_get_fifo_size(struct drm_device *dev, int plane) |
2292 | { | 2307 | { |
2293 | struct drm_i915_private *dev_priv = dev->dev_private; | 2308 | struct drm_i915_private *dev_priv = dev->dev_private; |
2294 | uint32_t dsparb = I915_READ(DSPARB); | 2309 | uint32_t dsparb = I915_READ(DSPARB); |
2295 | int size; | 2310 | int size; |
2296 | 2311 | ||
2297 | if (IS_I9XX(dev)) { | 2312 | if (plane == 0) |
2298 | if (plane == 0) | ||
2299 | size = dsparb & 0x7f; | ||
2300 | else | ||
2301 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - | ||
2302 | (dsparb & 0x7f); | ||
2303 | } else if (IS_I85X(dev)) { | ||
2304 | if (plane == 0) | ||
2305 | size = dsparb & 0x1ff; | ||
2306 | else | ||
2307 | size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - | ||
2308 | (dsparb & 0x1ff); | ||
2309 | size >>= 1; /* Convert to cachelines */ | ||
2310 | } else if (IS_845G(dev)) { | ||
2311 | size = dsparb & 0x7f; | ||
2312 | size >>= 2; /* Convert to cachelines */ | ||
2313 | } else { | ||
2314 | size = dsparb & 0x7f; | 2313 | size = dsparb & 0x7f; |
2315 | size >>= 1; /* Convert to cachelines */ | 2314 | else |
2316 | } | 2315 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - |
2316 | (dsparb & 0x7f); | ||
2317 | 2317 | ||
2318 | DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", | 2318 | DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", |
2319 | size); | 2319 | size); |
@@ -2321,7 +2321,57 @@ static int intel_get_fifo_size(struct drm_device *dev, int plane) | |||
2321 | return size; | 2321 | return size; |
2322 | } | 2322 | } |
2323 | 2323 | ||
2324 | static void g4x_update_wm(struct drm_device *dev) | 2324 | static int i85x_get_fifo_size(struct drm_device *dev, int plane) |
2325 | { | ||
2326 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2327 | uint32_t dsparb = I915_READ(DSPARB); | ||
2328 | int size; | ||
2329 | |||
2330 | if (plane == 0) | ||
2331 | size = dsparb & 0x1ff; | ||
2332 | else | ||
2333 | size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - | ||
2334 | (dsparb & 0x1ff); | ||
2335 | size >>= 1; /* Convert to cachelines */ | ||
2336 | |||
2337 | DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", | ||
2338 | size); | ||
2339 | |||
2340 | return size; | ||
2341 | } | ||
2342 | |||
2343 | static int i845_get_fifo_size(struct drm_device *dev, int plane) | ||
2344 | { | ||
2345 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2346 | uint32_t dsparb = I915_READ(DSPARB); | ||
2347 | int size; | ||
2348 | |||
2349 | size = dsparb & 0x7f; | ||
2350 | size >>= 2; /* Convert to cachelines */ | ||
2351 | |||
2352 | DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", | ||
2353 | size); | ||
2354 | |||
2355 | return size; | ||
2356 | } | ||
2357 | |||
2358 | static int i830_get_fifo_size(struct drm_device *dev, int plane) | ||
2359 | { | ||
2360 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2361 | uint32_t dsparb = I915_READ(DSPARB); | ||
2362 | int size; | ||
2363 | |||
2364 | size = dsparb & 0x7f; | ||
2365 | size >>= 1; /* Convert to cachelines */ | ||
2366 | |||
2367 | DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", | ||
2368 | size); | ||
2369 | |||
2370 | return size; | ||
2371 | } | ||
2372 | |||
2373 | static void g4x_update_wm(struct drm_device *dev, int unused, int unused2, | ||
2374 | int unused3, int unused4) | ||
2325 | { | 2375 | { |
2326 | struct drm_i915_private *dev_priv = dev->dev_private; | 2376 | struct drm_i915_private *dev_priv = dev->dev_private; |
2327 | u32 fw_blc_self = I915_READ(FW_BLC_SELF); | 2377 | u32 fw_blc_self = I915_READ(FW_BLC_SELF); |
@@ -2333,7 +2383,8 @@ static void g4x_update_wm(struct drm_device *dev) | |||
2333 | I915_WRITE(FW_BLC_SELF, fw_blc_self); | 2383 | I915_WRITE(FW_BLC_SELF, fw_blc_self); |
2334 | } | 2384 | } |
2335 | 2385 | ||
2336 | static void i965_update_wm(struct drm_device *dev) | 2386 | static void i965_update_wm(struct drm_device *dev, int unused, int unused2, |
2387 | int unused3, int unused4) | ||
2337 | { | 2388 | { |
2338 | struct drm_i915_private *dev_priv = dev->dev_private; | 2389 | struct drm_i915_private *dev_priv = dev->dev_private; |
2339 | 2390 | ||
@@ -2369,8 +2420,8 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
2369 | cacheline_size = planea_params.cacheline_size; | 2420 | cacheline_size = planea_params.cacheline_size; |
2370 | 2421 | ||
2371 | /* Update per-plane FIFO sizes */ | 2422 | /* Update per-plane FIFO sizes */ |
2372 | planea_params.fifo_size = intel_get_fifo_size(dev, 0); | 2423 | planea_params.fifo_size = dev_priv->display.get_fifo_size(dev, 0); |
2373 | planeb_params.fifo_size = intel_get_fifo_size(dev, 1); | 2424 | planeb_params.fifo_size = dev_priv->display.get_fifo_size(dev, 1); |
2374 | 2425 | ||
2375 | planea_wm = intel_calculate_wm(planea_clock, &planea_params, | 2426 | planea_wm = intel_calculate_wm(planea_clock, &planea_params, |
2376 | pixel_size, latency_ns); | 2427 | pixel_size, latency_ns); |
@@ -2417,14 +2468,14 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
2417 | I915_WRITE(FW_BLC2, fwater_hi); | 2468 | I915_WRITE(FW_BLC2, fwater_hi); |
2418 | } | 2469 | } |
2419 | 2470 | ||
2420 | static void i830_update_wm(struct drm_device *dev, int planea_clock, | 2471 | static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, |
2421 | int pixel_size) | 2472 | int unused2, int pixel_size) |
2422 | { | 2473 | { |
2423 | struct drm_i915_private *dev_priv = dev->dev_private; | 2474 | struct drm_i915_private *dev_priv = dev->dev_private; |
2424 | uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff; | 2475 | uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff; |
2425 | int planea_wm; | 2476 | int planea_wm; |
2426 | 2477 | ||
2427 | i830_wm_info.fifo_size = intel_get_fifo_size(dev, 0); | 2478 | i830_wm_info.fifo_size = dev_priv->display.get_fifo_size(dev, 0); |
2428 | 2479 | ||
2429 | planea_wm = intel_calculate_wm(planea_clock, &i830_wm_info, | 2480 | planea_wm = intel_calculate_wm(planea_clock, &i830_wm_info, |
2430 | pixel_size, latency_ns); | 2481 | pixel_size, latency_ns); |
@@ -2468,6 +2519,7 @@ static void i830_update_wm(struct drm_device *dev, int planea_clock, | |||
2468 | */ | 2519 | */ |
2469 | static void intel_update_watermarks(struct drm_device *dev) | 2520 | static void intel_update_watermarks(struct drm_device *dev) |
2470 | { | 2521 | { |
2522 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2471 | struct drm_crtc *crtc; | 2523 | struct drm_crtc *crtc; |
2472 | struct intel_crtc *intel_crtc; | 2524 | struct intel_crtc *intel_crtc; |
2473 | int sr_hdisplay = 0; | 2525 | int sr_hdisplay = 0; |
@@ -2506,15 +2558,8 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
2506 | else if (IS_IGD(dev)) | 2558 | else if (IS_IGD(dev)) |
2507 | igd_disable_cxsr(dev); | 2559 | igd_disable_cxsr(dev); |
2508 | 2560 | ||
2509 | if (IS_G4X(dev)) | 2561 | dev_priv->display.update_wm(dev, planea_clock, planeb_clock, |
2510 | g4x_update_wm(dev); | 2562 | sr_hdisplay, pixel_size); |
2511 | else if (IS_I965G(dev)) | ||
2512 | i965_update_wm(dev); | ||
2513 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) | ||
2514 | i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, | ||
2515 | pixel_size); | ||
2516 | else | ||
2517 | i830_update_wm(dev, planea_clock, pixel_size); | ||
2518 | } | 2563 | } |
2519 | 2564 | ||
2520 | static int intel_crtc_mode_set(struct drm_crtc *crtc, | 2565 | static int intel_crtc_mode_set(struct drm_crtc *crtc, |
@@ -2785,7 +2830,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2785 | * XXX: No double-wide on 915GM pipe B. Is that the only reason for the | 2830 | * XXX: No double-wide on 915GM pipe B. Is that the only reason for the |
2786 | * pipe == 0 check? | 2831 | * pipe == 0 check? |
2787 | */ | 2832 | */ |
2788 | if (mode->clock > intel_get_core_clock_speed(dev) * 9 / 10) | 2833 | if (mode->clock > |
2834 | dev_priv->display.get_display_clock_speed(dev) * 9 / 10) | ||
2789 | pipeconf |= PIPEACONF_DOUBLE_WIDE; | 2835 | pipeconf |= PIPEACONF_DOUBLE_WIDE; |
2790 | else | 2836 | else |
2791 | pipeconf &= ~PIPEACONF_DOUBLE_WIDE; | 2837 | pipeconf &= ~PIPEACONF_DOUBLE_WIDE; |
@@ -2942,8 +2988,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2942 | /* Flush the plane changes */ | 2988 | /* Flush the plane changes */ |
2943 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 2989 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
2944 | 2990 | ||
2945 | if (I915_HAS_FBC(dev) && (IS_I965G(dev) || plane == 0)) | 2991 | intel_update_fbc(crtc, &crtc->mode); |
2946 | intel_update_fbc(crtc, &crtc->mode); | 2992 | |
2947 | intel_update_watermarks(dev); | 2993 | intel_update_watermarks(dev); |
2948 | 2994 | ||
2949 | drm_vblank_post_modeset(dev, pipe); | 2995 | drm_vblank_post_modeset(dev, pipe); |
@@ -4049,6 +4095,69 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
4049 | } | 4095 | } |
4050 | } | 4096 | } |
4051 | 4097 | ||
4098 | /* Set up chip specific display functions */ | ||
4099 | static void intel_init_display(struct drm_device *dev) | ||
4100 | { | ||
4101 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4102 | |||
4103 | /* We always want a DPMS function */ | ||
4104 | if (IS_IGDNG(dev)) | ||
4105 | dev_priv->display.dpms = igdng_crtc_dpms; | ||
4106 | else | ||
4107 | dev_priv->display.dpms = i9xx_crtc_dpms; | ||
4108 | |||
4109 | /* Only mobile has FBC, leave pointers NULL for other chips */ | ||
4110 | if (IS_MOBILE(dev)) { | ||
4111 | /* 855GM needs testing */ | ||
4112 | if (IS_I965GM(dev) || IS_I945GM(dev) || IS_I915GM(dev)) { | ||
4113 | dev_priv->display.fbc_enabled = i8xx_fbc_enabled; | ||
4114 | dev_priv->display.enable_fbc = i8xx_enable_fbc; | ||
4115 | dev_priv->display.disable_fbc = i8xx_disable_fbc; | ||
4116 | } | ||
4117 | } | ||
4118 | |||
4119 | /* Returns the core display clock speed */ | ||
4120 | if (IS_I945G(dev)) | ||
4121 | dev_priv->display.get_display_clock_speed = | ||
4122 | i945_get_display_clock_speed; | ||
4123 | else if (IS_I915G(dev)) | ||
4124 | dev_priv->display.get_display_clock_speed = | ||
4125 | i915_get_display_clock_speed; | ||
4126 | else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev)) | ||
4127 | dev_priv->display.get_display_clock_speed = | ||
4128 | i9xx_misc_get_display_clock_speed; | ||
4129 | else if (IS_I915GM(dev)) | ||
4130 | dev_priv->display.get_display_clock_speed = | ||
4131 | i915gm_get_display_clock_speed; | ||
4132 | else if (IS_I865G(dev)) | ||
4133 | dev_priv->display.get_display_clock_speed = | ||
4134 | i865_get_display_clock_speed; | ||
4135 | else if (IS_I855(dev)) | ||
4136 | dev_priv->display.get_display_clock_speed = | ||
4137 | i855_get_display_clock_speed; | ||
4138 | else /* 852, 830 */ | ||
4139 | dev_priv->display.get_display_clock_speed = | ||
4140 | i830_get_display_clock_speed; | ||
4141 | |||
4142 | /* For FIFO watermark updates */ | ||
4143 | if (IS_G4X(dev)) | ||
4144 | dev_priv->display.update_wm = g4x_update_wm; | ||
4145 | else if (IS_I965G(dev)) | ||
4146 | dev_priv->display.update_wm = i965_update_wm; | ||
4147 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) { | ||
4148 | dev_priv->display.update_wm = i9xx_update_wm; | ||
4149 | dev_priv->display.get_fifo_size = i9xx_get_fifo_size; | ||
4150 | } else { | ||
4151 | if (IS_I85X(dev)) | ||
4152 | dev_priv->display.get_fifo_size = i85x_get_fifo_size; | ||
4153 | else if (IS_845G(dev)) | ||
4154 | dev_priv->display.get_fifo_size = i845_get_fifo_size; | ||
4155 | else | ||
4156 | dev_priv->display.get_fifo_size = i830_get_fifo_size; | ||
4157 | dev_priv->display.update_wm = i830_update_wm; | ||
4158 | } | ||
4159 | } | ||
4160 | |||
4052 | void intel_modeset_init(struct drm_device *dev) | 4161 | void intel_modeset_init(struct drm_device *dev) |
4053 | { | 4162 | { |
4054 | struct drm_i915_private *dev_priv = dev->dev_private; | 4163 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -4062,6 +4171,8 @@ void intel_modeset_init(struct drm_device *dev) | |||
4062 | 4171 | ||
4063 | dev->mode_config.funcs = (void *)&intel_mode_funcs; | 4172 | dev->mode_config.funcs = (void *)&intel_mode_funcs; |
4064 | 4173 | ||
4174 | intel_init_display(dev); | ||
4175 | |||
4065 | if (IS_I965G(dev)) { | 4176 | if (IS_I965G(dev)) { |
4066 | dev->mode_config.max_width = 8192; | 4177 | dev->mode_config.max_width = 8192; |
4067 | dev->mode_config.max_height = 8192; | 4178 | dev->mode_config.max_height = 8192; |
@@ -4127,7 +4238,9 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
4127 | 4238 | ||
4128 | mutex_unlock(&dev->struct_mutex); | 4239 | mutex_unlock(&dev->struct_mutex); |
4129 | 4240 | ||
4130 | i8xx_disable_fbc(dev); | 4241 | if (dev_priv->display.disable_fbc) |
4242 | dev_priv->display.disable_fbc(dev); | ||
4243 | |||
4131 | drm_mode_config_cleanup(dev); | 4244 | drm_mode_config_cleanup(dev); |
4132 | } | 4245 | } |
4133 | 4246 | ||