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 | ||
