aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-01-07 05:11:40 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-01-07 11:40:19 -0500
commit3490ea5de6ac4af309c3df8a26a5cca61306334c (patch)
tree6adbd7881412b084fb3ba05080231122fb63e4f5 /drivers/gpu
parent48e858340dae43189a4e55647f6eac736766f828 (diff)
drm/i915: Treat crtc->mode.clock == 0 as disabled
Prevent a divide-by-zero by consistently treating an 'active' CRTC without a mode set as actually disabled. This looks to have been first introduced with commit 24929352481f085c5f85d4d4cbc919ddf106d381 Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Mon Jul 2 20:28:59 2012 +0200 drm/i915: read out the modeset hw state at load and resume time but then combined with commit b0a2658acb5bf9ca86b4aab011b7106de3af0add Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Tue Dec 18 09:37:54 2012 +0100 drm/i915: don't disable disconnected outputs it finally started oopsing. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reported-and-tested-by: Alexey Zaytsev <alexey.zaytsev@gmail.com> Tested-by: Sedat Dilek <sedat.dilek@gmail.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index e6f54ffab3ba..e83a11794172 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -44,6 +44,14 @@
44 * i915.i915_enable_fbc parameter 44 * i915.i915_enable_fbc parameter
45 */ 45 */
46 46
47static bool intel_crtc_active(struct drm_crtc *crtc)
48{
49 /* Be paranoid as we can arrive here with only partial
50 * state retrieved from the hardware during setup.
51 */
52 return to_intel_crtc(crtc)->active && crtc->fb && crtc->mode.clock;
53}
54
47static void i8xx_disable_fbc(struct drm_device *dev) 55static void i8xx_disable_fbc(struct drm_device *dev)
48{ 56{
49 struct drm_i915_private *dev_priv = dev->dev_private; 57 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -405,9 +413,8 @@ void intel_update_fbc(struct drm_device *dev)
405 * - going to an unsupported config (interlace, pixel multiply, etc.) 413 * - going to an unsupported config (interlace, pixel multiply, etc.)
406 */ 414 */
407 list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { 415 list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) {
408 if (to_intel_crtc(tmp_crtc)->active && 416 if (intel_crtc_active(tmp_crtc) &&
409 !to_intel_crtc(tmp_crtc)->primary_disabled && 417 !to_intel_crtc(tmp_crtc)->primary_disabled) {
410 tmp_crtc->fb) {
411 if (crtc) { 418 if (crtc) {
412 DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); 419 DRM_DEBUG_KMS("more than one pipe active, disabling compression\n");
413 dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; 420 dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES;
@@ -992,7 +999,7 @@ static struct drm_crtc *single_enabled_crtc(struct drm_device *dev)
992 struct drm_crtc *crtc, *enabled = NULL; 999 struct drm_crtc *crtc, *enabled = NULL;
993 1000
994 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 1001 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
995 if (to_intel_crtc(crtc)->active && crtc->fb) { 1002 if (intel_crtc_active(crtc)) {
996 if (enabled) 1003 if (enabled)
997 return NULL; 1004 return NULL;
998 enabled = crtc; 1005 enabled = crtc;
@@ -1086,7 +1093,7 @@ static bool g4x_compute_wm0(struct drm_device *dev,
1086 int entries, tlb_miss; 1093 int entries, tlb_miss;
1087 1094
1088 crtc = intel_get_crtc_for_plane(dev, plane); 1095 crtc = intel_get_crtc_for_plane(dev, plane);
1089 if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) { 1096 if (!intel_crtc_active(crtc)) {
1090 *cursor_wm = cursor->guard_size; 1097 *cursor_wm = cursor->guard_size;
1091 *plane_wm = display->guard_size; 1098 *plane_wm = display->guard_size;
1092 return false; 1099 return false;
@@ -1215,7 +1222,7 @@ static bool vlv_compute_drain_latency(struct drm_device *dev,
1215 int entries; 1222 int entries;
1216 1223
1217 crtc = intel_get_crtc_for_plane(dev, plane); 1224 crtc = intel_get_crtc_for_plane(dev, plane);
1218 if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) 1225 if (!intel_crtc_active(crtc))
1219 return false; 1226 return false;
1220 1227
1221 clock = crtc->mode.clock; /* VESA DOT Clock */ 1228 clock = crtc->mode.clock; /* VESA DOT Clock */
@@ -1476,7 +1483,7 @@ static void i9xx_update_wm(struct drm_device *dev)
1476 1483
1477 fifo_size = dev_priv->display.get_fifo_size(dev, 0); 1484 fifo_size = dev_priv->display.get_fifo_size(dev, 0);
1478 crtc = intel_get_crtc_for_plane(dev, 0); 1485 crtc = intel_get_crtc_for_plane(dev, 0);
1479 if (to_intel_crtc(crtc)->active && crtc->fb) { 1486 if (intel_crtc_active(crtc)) {
1480 int cpp = crtc->fb->bits_per_pixel / 8; 1487 int cpp = crtc->fb->bits_per_pixel / 8;
1481 if (IS_GEN2(dev)) 1488 if (IS_GEN2(dev))
1482 cpp = 4; 1489 cpp = 4;
@@ -1490,7 +1497,7 @@ static void i9xx_update_wm(struct drm_device *dev)
1490 1497
1491 fifo_size = dev_priv->display.get_fifo_size(dev, 1); 1498 fifo_size = dev_priv->display.get_fifo_size(dev, 1);
1492 crtc = intel_get_crtc_for_plane(dev, 1); 1499 crtc = intel_get_crtc_for_plane(dev, 1);
1493 if (to_intel_crtc(crtc)->active && crtc->fb) { 1500 if (intel_crtc_active(crtc)) {
1494 int cpp = crtc->fb->bits_per_pixel / 8; 1501 int cpp = crtc->fb->bits_per_pixel / 8;
1495 if (IS_GEN2(dev)) 1502 if (IS_GEN2(dev))
1496 cpp = 4; 1503 cpp = 4;
@@ -2044,7 +2051,7 @@ sandybridge_compute_sprite_wm(struct drm_device *dev, int plane,
2044 int entries, tlb_miss; 2051 int entries, tlb_miss;
2045 2052
2046 crtc = intel_get_crtc_for_plane(dev, plane); 2053 crtc = intel_get_crtc_for_plane(dev, plane);
2047 if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) { 2054 if (!intel_crtc_active(crtc)) {
2048 *sprite_wm = display->guard_size; 2055 *sprite_wm = display->guard_size;
2049 return false; 2056 return false;
2050 } 2057 }