diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 160 |
1 files changed, 142 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 496caa73eb70..e6f54ffab3ba 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -405,7 +405,7 @@ void intel_update_fbc(struct drm_device *dev) | |||
405 | * - going to an unsupported config (interlace, pixel multiply, etc.) | 405 | * - going to an unsupported config (interlace, pixel multiply, etc.) |
406 | */ | 406 | */ |
407 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { | 407 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { |
408 | if (tmp_crtc->enabled && | 408 | if (to_intel_crtc(tmp_crtc)->active && |
409 | !to_intel_crtc(tmp_crtc)->primary_disabled && | 409 | !to_intel_crtc(tmp_crtc)->primary_disabled && |
410 | tmp_crtc->fb) { | 410 | tmp_crtc->fb) { |
411 | if (crtc) { | 411 | if (crtc) { |
@@ -992,7 +992,7 @@ static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) | |||
992 | struct drm_crtc *crtc, *enabled = NULL; | 992 | struct drm_crtc *crtc, *enabled = NULL; |
993 | 993 | ||
994 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 994 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
995 | if (crtc->enabled && crtc->fb) { | 995 | if (to_intel_crtc(crtc)->active && crtc->fb) { |
996 | if (enabled) | 996 | if (enabled) |
997 | return NULL; | 997 | return NULL; |
998 | enabled = crtc; | 998 | enabled = crtc; |
@@ -1086,7 +1086,7 @@ static bool g4x_compute_wm0(struct drm_device *dev, | |||
1086 | int entries, tlb_miss; | 1086 | int entries, tlb_miss; |
1087 | 1087 | ||
1088 | crtc = intel_get_crtc_for_plane(dev, plane); | 1088 | crtc = intel_get_crtc_for_plane(dev, plane); |
1089 | if (crtc->fb == NULL || !crtc->enabled) { | 1089 | if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) { |
1090 | *cursor_wm = cursor->guard_size; | 1090 | *cursor_wm = cursor->guard_size; |
1091 | *plane_wm = display->guard_size; | 1091 | *plane_wm = display->guard_size; |
1092 | return false; | 1092 | return false; |
@@ -1215,7 +1215,7 @@ static bool vlv_compute_drain_latency(struct drm_device *dev, | |||
1215 | int entries; | 1215 | int entries; |
1216 | 1216 | ||
1217 | crtc = intel_get_crtc_for_plane(dev, plane); | 1217 | crtc = intel_get_crtc_for_plane(dev, plane); |
1218 | if (crtc->fb == NULL || !crtc->enabled) | 1218 | if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) |
1219 | return false; | 1219 | return false; |
1220 | 1220 | ||
1221 | clock = crtc->mode.clock; /* VESA DOT Clock */ | 1221 | clock = crtc->mode.clock; /* VESA DOT Clock */ |
@@ -1286,6 +1286,7 @@ static void valleyview_update_wm(struct drm_device *dev) | |||
1286 | struct drm_i915_private *dev_priv = dev->dev_private; | 1286 | struct drm_i915_private *dev_priv = dev->dev_private; |
1287 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | 1287 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; |
1288 | int plane_sr, cursor_sr; | 1288 | int plane_sr, cursor_sr; |
1289 | int ignore_plane_sr, ignore_cursor_sr; | ||
1289 | unsigned int enabled = 0; | 1290 | unsigned int enabled = 0; |
1290 | 1291 | ||
1291 | vlv_update_drain_latency(dev); | 1292 | vlv_update_drain_latency(dev); |
@@ -1302,17 +1303,23 @@ static void valleyview_update_wm(struct drm_device *dev) | |||
1302 | &planeb_wm, &cursorb_wm)) | 1303 | &planeb_wm, &cursorb_wm)) |
1303 | enabled |= 2; | 1304 | enabled |= 2; |
1304 | 1305 | ||
1305 | plane_sr = cursor_sr = 0; | ||
1306 | if (single_plane_enabled(enabled) && | 1306 | if (single_plane_enabled(enabled) && |
1307 | g4x_compute_srwm(dev, ffs(enabled) - 1, | 1307 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
1308 | sr_latency_ns, | 1308 | sr_latency_ns, |
1309 | &valleyview_wm_info, | 1309 | &valleyview_wm_info, |
1310 | &valleyview_cursor_wm_info, | 1310 | &valleyview_cursor_wm_info, |
1311 | &plane_sr, &cursor_sr)) | 1311 | &plane_sr, &ignore_cursor_sr) && |
1312 | g4x_compute_srwm(dev, ffs(enabled) - 1, | ||
1313 | 2*sr_latency_ns, | ||
1314 | &valleyview_wm_info, | ||
1315 | &valleyview_cursor_wm_info, | ||
1316 | &ignore_plane_sr, &cursor_sr)) { | ||
1312 | I915_WRITE(FW_BLC_SELF_VLV, FW_CSPWRDWNEN); | 1317 | I915_WRITE(FW_BLC_SELF_VLV, FW_CSPWRDWNEN); |
1313 | else | 1318 | } else { |
1314 | I915_WRITE(FW_BLC_SELF_VLV, | 1319 | I915_WRITE(FW_BLC_SELF_VLV, |
1315 | I915_READ(FW_BLC_SELF_VLV) & ~FW_CSPWRDWNEN); | 1320 | I915_READ(FW_BLC_SELF_VLV) & ~FW_CSPWRDWNEN); |
1321 | plane_sr = cursor_sr = 0; | ||
1322 | } | ||
1316 | 1323 | ||
1317 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", | 1324 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", |
1318 | planea_wm, cursora_wm, | 1325 | planea_wm, cursora_wm, |
@@ -1352,17 +1359,18 @@ static void g4x_update_wm(struct drm_device *dev) | |||
1352 | &planeb_wm, &cursorb_wm)) | 1359 | &planeb_wm, &cursorb_wm)) |
1353 | enabled |= 2; | 1360 | enabled |= 2; |
1354 | 1361 | ||
1355 | plane_sr = cursor_sr = 0; | ||
1356 | if (single_plane_enabled(enabled) && | 1362 | if (single_plane_enabled(enabled) && |
1357 | g4x_compute_srwm(dev, ffs(enabled) - 1, | 1363 | g4x_compute_srwm(dev, ffs(enabled) - 1, |
1358 | sr_latency_ns, | 1364 | sr_latency_ns, |
1359 | &g4x_wm_info, | 1365 | &g4x_wm_info, |
1360 | &g4x_cursor_wm_info, | 1366 | &g4x_cursor_wm_info, |
1361 | &plane_sr, &cursor_sr)) | 1367 | &plane_sr, &cursor_sr)) { |
1362 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | 1368 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); |
1363 | else | 1369 | } else { |
1364 | I915_WRITE(FW_BLC_SELF, | 1370 | I915_WRITE(FW_BLC_SELF, |
1365 | I915_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN); | 1371 | I915_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN); |
1372 | plane_sr = cursor_sr = 0; | ||
1373 | } | ||
1366 | 1374 | ||
1367 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", | 1375 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", |
1368 | planea_wm, cursora_wm, | 1376 | planea_wm, cursora_wm, |
@@ -1468,7 +1476,7 @@ static void i9xx_update_wm(struct drm_device *dev) | |||
1468 | 1476 | ||
1469 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); | 1477 | fifo_size = dev_priv->display.get_fifo_size(dev, 0); |
1470 | crtc = intel_get_crtc_for_plane(dev, 0); | 1478 | crtc = intel_get_crtc_for_plane(dev, 0); |
1471 | if (crtc->enabled && crtc->fb) { | 1479 | if (to_intel_crtc(crtc)->active && crtc->fb) { |
1472 | int cpp = crtc->fb->bits_per_pixel / 8; | 1480 | int cpp = crtc->fb->bits_per_pixel / 8; |
1473 | if (IS_GEN2(dev)) | 1481 | if (IS_GEN2(dev)) |
1474 | cpp = 4; | 1482 | cpp = 4; |
@@ -1482,7 +1490,7 @@ static void i9xx_update_wm(struct drm_device *dev) | |||
1482 | 1490 | ||
1483 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); | 1491 | fifo_size = dev_priv->display.get_fifo_size(dev, 1); |
1484 | crtc = intel_get_crtc_for_plane(dev, 1); | 1492 | crtc = intel_get_crtc_for_plane(dev, 1); |
1485 | if (crtc->enabled && crtc->fb) { | 1493 | if (to_intel_crtc(crtc)->active && crtc->fb) { |
1486 | int cpp = crtc->fb->bits_per_pixel / 8; | 1494 | int cpp = crtc->fb->bits_per_pixel / 8; |
1487 | if (IS_GEN2(dev)) | 1495 | if (IS_GEN2(dev)) |
1488 | cpp = 4; | 1496 | cpp = 4; |
@@ -1811,8 +1819,110 @@ static void sandybridge_update_wm(struct drm_device *dev) | |||
1811 | enabled |= 2; | 1819 | enabled |= 2; |
1812 | } | 1820 | } |
1813 | 1821 | ||
1814 | if ((dev_priv->num_pipe == 3) && | 1822 | /* |
1815 | g4x_compute_wm0(dev, 2, | 1823 | * Calculate and update the self-refresh watermark only when one |
1824 | * display plane is used. | ||
1825 | * | ||
1826 | * SNB support 3 levels of watermark. | ||
1827 | * | ||
1828 | * WM1/WM2/WM2 watermarks have to be enabled in the ascending order, | ||
1829 | * and disabled in the descending order | ||
1830 | * | ||
1831 | */ | ||
1832 | I915_WRITE(WM3_LP_ILK, 0); | ||
1833 | I915_WRITE(WM2_LP_ILK, 0); | ||
1834 | I915_WRITE(WM1_LP_ILK, 0); | ||
1835 | |||
1836 | if (!single_plane_enabled(enabled) || | ||
1837 | dev_priv->sprite_scaling_enabled) | ||
1838 | return; | ||
1839 | enabled = ffs(enabled) - 1; | ||
1840 | |||
1841 | /* WM1 */ | ||
1842 | if (!ironlake_compute_srwm(dev, 1, enabled, | ||
1843 | SNB_READ_WM1_LATENCY() * 500, | ||
1844 | &sandybridge_display_srwm_info, | ||
1845 | &sandybridge_cursor_srwm_info, | ||
1846 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
1847 | return; | ||
1848 | |||
1849 | I915_WRITE(WM1_LP_ILK, | ||
1850 | WM1_LP_SR_EN | | ||
1851 | (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
1852 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
1853 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
1854 | cursor_wm); | ||
1855 | |||
1856 | /* WM2 */ | ||
1857 | if (!ironlake_compute_srwm(dev, 2, enabled, | ||
1858 | SNB_READ_WM2_LATENCY() * 500, | ||
1859 | &sandybridge_display_srwm_info, | ||
1860 | &sandybridge_cursor_srwm_info, | ||
1861 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
1862 | return; | ||
1863 | |||
1864 | I915_WRITE(WM2_LP_ILK, | ||
1865 | WM2_LP_EN | | ||
1866 | (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
1867 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
1868 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
1869 | cursor_wm); | ||
1870 | |||
1871 | /* WM3 */ | ||
1872 | if (!ironlake_compute_srwm(dev, 3, enabled, | ||
1873 | SNB_READ_WM3_LATENCY() * 500, | ||
1874 | &sandybridge_display_srwm_info, | ||
1875 | &sandybridge_cursor_srwm_info, | ||
1876 | &fbc_wm, &plane_wm, &cursor_wm)) | ||
1877 | return; | ||
1878 | |||
1879 | I915_WRITE(WM3_LP_ILK, | ||
1880 | WM3_LP_EN | | ||
1881 | (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) | | ||
1882 | (fbc_wm << WM1_LP_FBC_SHIFT) | | ||
1883 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
1884 | cursor_wm); | ||
1885 | } | ||
1886 | |||
1887 | static void ivybridge_update_wm(struct drm_device *dev) | ||
1888 | { | ||
1889 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1890 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ | ||
1891 | u32 val; | ||
1892 | int fbc_wm, plane_wm, cursor_wm; | ||
1893 | int ignore_fbc_wm, ignore_plane_wm, ignore_cursor_wm; | ||
1894 | unsigned int enabled; | ||
1895 | |||
1896 | enabled = 0; | ||
1897 | if (g4x_compute_wm0(dev, 0, | ||
1898 | &sandybridge_display_wm_info, latency, | ||
1899 | &sandybridge_cursor_wm_info, latency, | ||
1900 | &plane_wm, &cursor_wm)) { | ||
1901 | val = I915_READ(WM0_PIPEA_ILK); | ||
1902 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
1903 | I915_WRITE(WM0_PIPEA_ILK, val | | ||
1904 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
1905 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | ||
1906 | " plane %d, " "cursor: %d\n", | ||
1907 | plane_wm, cursor_wm); | ||
1908 | enabled |= 1; | ||
1909 | } | ||
1910 | |||
1911 | if (g4x_compute_wm0(dev, 1, | ||
1912 | &sandybridge_display_wm_info, latency, | ||
1913 | &sandybridge_cursor_wm_info, latency, | ||
1914 | &plane_wm, &cursor_wm)) { | ||
1915 | val = I915_READ(WM0_PIPEB_ILK); | ||
1916 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
1917 | I915_WRITE(WM0_PIPEB_ILK, val | | ||
1918 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
1919 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | ||
1920 | " plane %d, cursor: %d\n", | ||
1921 | plane_wm, cursor_wm); | ||
1922 | enabled |= 2; | ||
1923 | } | ||
1924 | |||
1925 | if (g4x_compute_wm0(dev, 2, | ||
1816 | &sandybridge_display_wm_info, latency, | 1926 | &sandybridge_display_wm_info, latency, |
1817 | &sandybridge_cursor_wm_info, latency, | 1927 | &sandybridge_cursor_wm_info, latency, |
1818 | &plane_wm, &cursor_wm)) { | 1928 | &plane_wm, &cursor_wm)) { |
@@ -1875,12 +1985,17 @@ static void sandybridge_update_wm(struct drm_device *dev) | |||
1875 | (plane_wm << WM1_LP_SR_SHIFT) | | 1985 | (plane_wm << WM1_LP_SR_SHIFT) | |
1876 | cursor_wm); | 1986 | cursor_wm); |
1877 | 1987 | ||
1878 | /* WM3 */ | 1988 | /* WM3, note we have to correct the cursor latency */ |
1879 | if (!ironlake_compute_srwm(dev, 3, enabled, | 1989 | if (!ironlake_compute_srwm(dev, 3, enabled, |
1880 | SNB_READ_WM3_LATENCY() * 500, | 1990 | SNB_READ_WM3_LATENCY() * 500, |
1881 | &sandybridge_display_srwm_info, | 1991 | &sandybridge_display_srwm_info, |
1882 | &sandybridge_cursor_srwm_info, | 1992 | &sandybridge_cursor_srwm_info, |
1883 | &fbc_wm, &plane_wm, &cursor_wm)) | 1993 | &fbc_wm, &plane_wm, &ignore_cursor_wm) || |
1994 | !ironlake_compute_srwm(dev, 3, enabled, | ||
1995 | 2 * SNB_READ_WM3_LATENCY() * 500, | ||
1996 | &sandybridge_display_srwm_info, | ||
1997 | &sandybridge_cursor_srwm_info, | ||
1998 | &ignore_fbc_wm, &ignore_plane_wm, &cursor_wm)) | ||
1884 | return; | 1999 | return; |
1885 | 2000 | ||
1886 | I915_WRITE(WM3_LP_ILK, | 2001 | I915_WRITE(WM3_LP_ILK, |
@@ -1929,7 +2044,7 @@ sandybridge_compute_sprite_wm(struct drm_device *dev, int plane, | |||
1929 | int entries, tlb_miss; | 2044 | int entries, tlb_miss; |
1930 | 2045 | ||
1931 | crtc = intel_get_crtc_for_plane(dev, plane); | 2046 | crtc = intel_get_crtc_for_plane(dev, plane); |
1932 | if (crtc->fb == NULL || !crtc->enabled) { | 2047 | if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) { |
1933 | *sprite_wm = display->guard_size; | 2048 | *sprite_wm = display->guard_size; |
1934 | return false; | 2049 | return false; |
1935 | } | 2050 | } |
@@ -3471,6 +3586,15 @@ static void gen6_init_clock_gating(struct drm_device *dev) | |||
3471 | I915_READ(ILK_DISPLAY_CHICKEN2) | | 3586 | I915_READ(ILK_DISPLAY_CHICKEN2) | |
3472 | ILK_ELPIN_409_SELECT); | 3587 | ILK_ELPIN_409_SELECT); |
3473 | 3588 | ||
3589 | /* WaDisableHiZPlanesWhenMSAAEnabled */ | ||
3590 | I915_WRITE(_3D_CHICKEN, | ||
3591 | _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB)); | ||
3592 | |||
3593 | /* WaSetupGtModeTdRowDispatch */ | ||
3594 | if (IS_SNB_GT1(dev)) | ||
3595 | I915_WRITE(GEN6_GT_MODE, | ||
3596 | _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE)); | ||
3597 | |||
3474 | I915_WRITE(WM3_LP_ILK, 0); | 3598 | I915_WRITE(WM3_LP_ILK, 0); |
3475 | I915_WRITE(WM2_LP_ILK, 0); | 3599 | I915_WRITE(WM2_LP_ILK, 0); |
3476 | I915_WRITE(WM1_LP_ILK, 0); | 3600 | I915_WRITE(WM1_LP_ILK, 0); |
@@ -3999,7 +4123,7 @@ void intel_init_pm(struct drm_device *dev) | |||
3999 | } else if (IS_IVYBRIDGE(dev)) { | 4123 | } else if (IS_IVYBRIDGE(dev)) { |
4000 | /* FIXME: detect B0+ stepping and use auto training */ | 4124 | /* FIXME: detect B0+ stepping and use auto training */ |
4001 | if (SNB_READ_WM0_LATENCY()) { | 4125 | if (SNB_READ_WM0_LATENCY()) { |
4002 | dev_priv->display.update_wm = sandybridge_update_wm; | 4126 | dev_priv->display.update_wm = ivybridge_update_wm; |
4003 | dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; | 4127 | dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; |
4004 | } else { | 4128 | } else { |
4005 | DRM_DEBUG_KMS("Failed to read display plane latency. " | 4129 | DRM_DEBUG_KMS("Failed to read display plane latency. " |