diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 336 |
1 files changed, 223 insertions, 113 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index dd176b7296c1..4692f8cb7724 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -43,14 +43,6 @@ | |||
| 43 | * i915.i915_enable_fbc parameter | 43 | * i915.i915_enable_fbc parameter |
| 44 | */ | 44 | */ |
| 45 | 45 | ||
| 46 | static bool intel_crtc_active(struct drm_crtc *crtc) | ||
| 47 | { | ||
| 48 | /* Be paranoid as we can arrive here with only partial | ||
| 49 | * state retrieved from the hardware during setup. | ||
| 50 | */ | ||
| 51 | return to_intel_crtc(crtc)->active && crtc->fb && crtc->mode.clock; | ||
| 52 | } | ||
| 53 | |||
| 54 | static void i8xx_disable_fbc(struct drm_device *dev) | 46 | static void i8xx_disable_fbc(struct drm_device *dev) |
| 55 | { | 47 | { |
| 56 | struct drm_i915_private *dev_priv = dev->dev_private; | 48 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -458,7 +450,8 @@ void intel_update_fbc(struct drm_device *dev) | |||
| 458 | struct drm_framebuffer *fb; | 450 | struct drm_framebuffer *fb; |
| 459 | struct intel_framebuffer *intel_fb; | 451 | struct intel_framebuffer *intel_fb; |
| 460 | struct drm_i915_gem_object *obj; | 452 | struct drm_i915_gem_object *obj; |
| 461 | unsigned int max_hdisplay, max_vdisplay; | 453 | const struct drm_display_mode *adjusted_mode; |
| 454 | unsigned int max_width, max_height; | ||
| 462 | 455 | ||
| 463 | if (!I915_HAS_FBC(dev)) { | 456 | if (!I915_HAS_FBC(dev)) { |
| 464 | set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED); | 457 | set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED); |
| @@ -502,6 +495,7 @@ void intel_update_fbc(struct drm_device *dev) | |||
| 502 | fb = crtc->fb; | 495 | fb = crtc->fb; |
| 503 | intel_fb = to_intel_framebuffer(fb); | 496 | intel_fb = to_intel_framebuffer(fb); |
| 504 | obj = intel_fb->obj; | 497 | obj = intel_fb->obj; |
| 498 | adjusted_mode = &intel_crtc->config.adjusted_mode; | ||
| 505 | 499 | ||
| 506 | if (i915_enable_fbc < 0 && | 500 | if (i915_enable_fbc < 0 && |
| 507 | INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) { | 501 | INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) { |
| @@ -514,8 +508,8 @@ void intel_update_fbc(struct drm_device *dev) | |||
| 514 | DRM_DEBUG_KMS("fbc disabled per module param\n"); | 508 | DRM_DEBUG_KMS("fbc disabled per module param\n"); |
| 515 | goto out_disable; | 509 | goto out_disable; |
| 516 | } | 510 | } |
| 517 | if ((crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) || | 511 | if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) || |
| 518 | (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)) { | 512 | (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) { |
| 519 | if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE)) | 513 | if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE)) |
| 520 | DRM_DEBUG_KMS("mode incompatible with compression, " | 514 | DRM_DEBUG_KMS("mode incompatible with compression, " |
| 521 | "disabling\n"); | 515 | "disabling\n"); |
| @@ -523,14 +517,14 @@ void intel_update_fbc(struct drm_device *dev) | |||
| 523 | } | 517 | } |
| 524 | 518 | ||
| 525 | if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) { | 519 | if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) { |
| 526 | max_hdisplay = 4096; | 520 | max_width = 4096; |
| 527 | max_vdisplay = 2048; | 521 | max_height = 2048; |
| 528 | } else { | 522 | } else { |
| 529 | max_hdisplay = 2048; | 523 | max_width = 2048; |
| 530 | max_vdisplay = 1536; | 524 | max_height = 1536; |
| 531 | } | 525 | } |
| 532 | if ((crtc->mode.hdisplay > max_hdisplay) || | 526 | if (intel_crtc->config.pipe_src_w > max_width || |
| 533 | (crtc->mode.vdisplay > max_vdisplay)) { | 527 | intel_crtc->config.pipe_src_h > max_height) { |
| 534 | if (set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE)) | 528 | if (set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE)) |
| 535 | DRM_DEBUG_KMS("mode too large for compression, disabling\n"); | 529 | DRM_DEBUG_KMS("mode too large for compression, disabling\n"); |
| 536 | goto out_disable; | 530 | goto out_disable; |
| @@ -1087,8 +1081,9 @@ static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) | |||
| 1087 | return enabled; | 1081 | return enabled; |
| 1088 | } | 1082 | } |
| 1089 | 1083 | ||
| 1090 | static void pineview_update_wm(struct drm_device *dev) | 1084 | static void pineview_update_wm(struct drm_crtc *unused_crtc) |
| 1091 | { | 1085 | { |
| 1086 | struct drm_device *dev = unused_crtc->dev; | ||
| 1092 | struct drm_i915_private *dev_priv = dev->dev_private; | 1087 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1093 | struct drm_crtc *crtc; | 1088 | struct drm_crtc *crtc; |
| 1094 | const struct cxsr_latency *latency; | 1089 | const struct cxsr_latency *latency; |
| @@ -1105,7 +1100,7 @@ static void pineview_update_wm(struct drm_device *dev) | |||
| 1105 | 1100 | ||
| 1106 | crtc = single_enabled_crtc(dev); | 1101 | crtc = single_enabled_crtc(dev); |
| 1107 | if (crtc) { | 1102 | if (crtc) { |
| 1108 | int clock = crtc->mode.clock; | 1103 | int clock = to_intel_crtc(crtc)->config.adjusted_mode.clock; |
| 1109 | int pixel_size = crtc->fb->bits_per_pixel / 8; | 1104 | int pixel_size = crtc->fb->bits_per_pixel / 8; |
| 1110 | 1105 | ||
| 1111 | /* Display SR */ | 1106 | /* Display SR */ |
| @@ -1166,6 +1161,7 @@ static bool g4x_compute_wm0(struct drm_device *dev, | |||
| 1166 | int *cursor_wm) | 1161 | int *cursor_wm) |
| 1167 | { | 1162 | { |
| 1168 | struct drm_crtc *crtc; | 1163 | struct drm_crtc *crtc; |
| 1164 | const struct drm_display_mode *adjusted_mode; | ||
| 1169 | int htotal, hdisplay, clock, pixel_size; | 1165 | int htotal, hdisplay, clock, pixel_size; |
| 1170 | int line_time_us, line_count; | 1166 | int line_time_us, line_count; |
| 1171 | int entries, tlb_miss; | 1167 | int entries, tlb_miss; |
| @@ -1177,9 +1173,10 @@ static bool g4x_compute_wm0(struct drm_device *dev, | |||
| 1177 | return false; | 1173 | return false; |
| 1178 | } | 1174 | } |
| 1179 | 1175 | ||
| 1180 | htotal = crtc->mode.htotal; | 1176 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
| 1181 | hdisplay = crtc->mode.hdisplay; | 1177 | clock = adjusted_mode->clock; |
| 1182 | clock = crtc->mode.clock; | 1178 | htotal = adjusted_mode->htotal; |
| 1179 | hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; | ||
| 1183 | pixel_size = crtc->fb->bits_per_pixel / 8; | 1180 | pixel_size = crtc->fb->bits_per_pixel / 8; |
| 1184 | 1181 | ||
| 1185 | /* Use the small buffer method to calculate plane watermark */ | 1182 | /* Use the small buffer method to calculate plane watermark */ |
| @@ -1250,6 +1247,7 @@ static bool g4x_compute_srwm(struct drm_device *dev, | |||
| 1250 | int *display_wm, int *cursor_wm) | 1247 | int *display_wm, int *cursor_wm) |
| 1251 | { | 1248 | { |
| 1252 | struct drm_crtc *crtc; | 1249 | struct drm_crtc *crtc; |
| 1250 | const struct drm_display_mode *adjusted_mode; | ||
| 1253 | int hdisplay, htotal, pixel_size, clock; | 1251 | int hdisplay, htotal, pixel_size, clock; |
| 1254 | unsigned long line_time_us; | 1252 | unsigned long line_time_us; |
| 1255 | int line_count, line_size; | 1253 | int line_count, line_size; |
| @@ -1262,9 +1260,10 @@ static bool g4x_compute_srwm(struct drm_device *dev, | |||
| 1262 | } | 1260 | } |
| 1263 | 1261 | ||
| 1264 | crtc = intel_get_crtc_for_plane(dev, plane); | 1262 | crtc = intel_get_crtc_for_plane(dev, plane); |
| 1265 | hdisplay = crtc->mode.hdisplay; | 1263 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
| 1266 | htotal = crtc->mode.htotal; | 1264 | clock = adjusted_mode->clock; |
| 1267 | clock = crtc->mode.clock; | 1265 | htotal = adjusted_mode->htotal; |
| 1266 | hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; | ||
| 1268 | pixel_size = crtc->fb->bits_per_pixel / 8; | 1267 | pixel_size = crtc->fb->bits_per_pixel / 8; |
| 1269 | 1268 | ||
| 1270 | line_time_us = (htotal * 1000) / clock; | 1269 | line_time_us = (htotal * 1000) / clock; |
| @@ -1303,7 +1302,7 @@ static bool vlv_compute_drain_latency(struct drm_device *dev, | |||
| 1303 | if (!intel_crtc_active(crtc)) | 1302 | if (!intel_crtc_active(crtc)) |
| 1304 | return false; | 1303 | return false; |
| 1305 | 1304 | ||
| 1306 | clock = crtc->mode.clock; /* VESA DOT Clock */ | 1305 | clock = to_intel_crtc(crtc)->config.adjusted_mode.clock; |
| 1307 | pixel_size = crtc->fb->bits_per_pixel / 8; /* BPP */ | 1306 | pixel_size = crtc->fb->bits_per_pixel / 8; /* BPP */ |
| 1308 | 1307 | ||
| 1309 | entries = (clock / 1000) * pixel_size; | 1308 | entries = (clock / 1000) * pixel_size; |
| @@ -1365,8 +1364,9 @@ static void vlv_update_drain_latency(struct drm_device *dev) | |||
| 1365 | 1364 | ||
| 1366 | #define single_plane_enabled(mask) is_power_of_2(mask) | 1365 | #define single_plane_enabled(mask) is_power_of_2(mask) |
| 1367 | 1366 | ||
| 1368 | static void valleyview_update_wm(struct drm_device *dev) | 1367 | static void valleyview_update_wm(struct drm_crtc *crtc) |
| 1369 | { | 1368 | { |
| 1369 | struct drm_device *dev = crtc->dev; | ||
| 1370 | static const int sr_latency_ns = 12000; | 1370 | static const int sr_latency_ns = 12000; |
| 1371 | struct drm_i915_private *dev_priv = dev->dev_private; | 1371 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1372 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | 1372 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; |
| @@ -1424,8 +1424,9 @@ static void valleyview_update_wm(struct drm_device *dev) | |||
| 1424 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | 1424 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
| 1425 | } | 1425 | } |
| 1426 | 1426 | ||
| 1427 | static void g4x_update_wm(struct drm_device *dev) | 1427 | static void g4x_update_wm(struct drm_crtc *crtc) |
| 1428 | { | 1428 | { |
| 1429 | struct drm_device *dev = crtc->dev; | ||
| 1429 | static const int sr_latency_ns = 12000; | 1430 | static const int sr_latency_ns = 12000; |
| 1430 | struct drm_i915_private *dev_priv = dev->dev_private; | 1431 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1431 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | 1432 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; |
| @@ -1476,8 +1477,9 @@ static void g4x_update_wm(struct drm_device *dev) | |||
| 1476 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | 1477 | (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
| 1477 | } | 1478 | } |
| 1478 | 1479 | ||
| 1479 | static void i965_update_wm(struct drm_device *dev) | 1480 | static void i965_update_wm(struct drm_crtc *unused_crtc) |
| 1480 | { | 1481 | { |
| 1482 | struct drm_device *dev = unused_crtc->dev; | ||
| 1481 | struct drm_i915_private *dev_priv = dev->dev_private; | 1483 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1482 | struct drm_crtc *crtc; | 1484 | struct drm_crtc *crtc; |
| 1483 | int srwm = 1; | 1485 | int srwm = 1; |
| @@ -1488,9 +1490,11 @@ static void i965_update_wm(struct drm_device *dev) | |||
| 1488 | if (crtc) { | 1490 | if (crtc) { |
| 1489 | /* self-refresh has much higher latency */ | 1491 | /* self-refresh has much higher latency */ |
| 1490 | static const int sr_latency_ns = 12000; | 1492 | static const int sr_latency_ns = 12000; |
| 1491 | int clock = crtc->mode.clock; | 1493 | const struct drm_display_mode *adjusted_mode = |
| 1492 | int htotal = crtc->mode.htotal; | 1494 | &to_intel_crtc(crtc)->config.adjusted_mode; |
| 1493 | int hdisplay = crtc->mode.hdisplay; | 1495 | int clock = adjusted_mode->clock; |
| 1496 | int htotal = adjusted_mode->htotal; | ||
| 1497 | int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; | ||
| 1494 | int pixel_size = crtc->fb->bits_per_pixel / 8; | 1498 | int pixel_size = crtc->fb->bits_per_pixel / 8; |
| 1495 | unsigned long line_time_us; | 1499 | unsigned long line_time_us; |
| 1496 | int entries; | 1500 | int entries; |
| @@ -1541,8 +1545,9 @@ static void i965_update_wm(struct drm_device *dev) | |||
| 1541 | I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); | 1545 | I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); |
| 1542 | } | 1546 | } |
| 1543 | 1547 | ||
| 1544 | static void i9xx_update_wm(struct drm_device *dev) | 1548 | static void i9xx_update_wm(struct drm_crtc *unused_crtc) |
| 1545 | { | 1549 | { |
| 1550 | struct drm_device *dev = unused_crtc->dev; | ||
| 1546 | struct drm_i915_private *dev_priv = dev->dev_private; | 1551 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1547 | const struct intel_watermark_params *wm_info; | 1552 | const struct intel_watermark_params *wm_info; |
| 1548 | uint32_t fwater_lo; | 1553 | uint32_t fwater_lo; |
| @@ -1566,7 +1571,7 @@ static void i9xx_update_wm(struct drm_device *dev) | |||
| 1566 | if (IS_GEN2(dev)) | 1571 | if (IS_GEN2(dev)) |
| 1567 | cpp = 4; | 1572 | cpp = 4; |
| 1568 | 1573 | ||
| 1569 | planea_wm = intel_calculate_wm(crtc->mode.clock, | 1574 | planea_wm = intel_calculate_wm(to_intel_crtc(crtc)->config.adjusted_mode.clock, |
| 1570 | wm_info, fifo_size, cpp, | 1575 | wm_info, fifo_size, cpp, |
| 1571 | latency_ns); | 1576 | latency_ns); |
| 1572 | enabled = crtc; | 1577 | enabled = crtc; |
| @@ -1580,7 +1585,7 @@ static void i9xx_update_wm(struct drm_device *dev) | |||
| 1580 | if (IS_GEN2(dev)) | 1585 | if (IS_GEN2(dev)) |
| 1581 | cpp = 4; | 1586 | cpp = 4; |
| 1582 | 1587 | ||
| 1583 | planeb_wm = intel_calculate_wm(crtc->mode.clock, | 1588 | planeb_wm = intel_calculate_wm(to_intel_crtc(crtc)->config.adjusted_mode.clock, |
| 1584 | wm_info, fifo_size, cpp, | 1589 | wm_info, fifo_size, cpp, |
| 1585 | latency_ns); | 1590 | latency_ns); |
| 1586 | if (enabled == NULL) | 1591 | if (enabled == NULL) |
| @@ -1607,9 +1612,11 @@ static void i9xx_update_wm(struct drm_device *dev) | |||
| 1607 | if (HAS_FW_BLC(dev) && enabled) { | 1612 | if (HAS_FW_BLC(dev) && enabled) { |
| 1608 | /* self-refresh has much higher latency */ | 1613 | /* self-refresh has much higher latency */ |
| 1609 | static const int sr_latency_ns = 6000; | 1614 | static const int sr_latency_ns = 6000; |
| 1610 | int clock = enabled->mode.clock; | 1615 | const struct drm_display_mode *adjusted_mode = |
| 1611 | int htotal = enabled->mode.htotal; | 1616 | &to_intel_crtc(enabled)->config.adjusted_mode; |
| 1612 | int hdisplay = enabled->mode.hdisplay; | 1617 | int clock = adjusted_mode->clock; |
| 1618 | int htotal = adjusted_mode->htotal; | ||
| 1619 | int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; | ||
| 1613 | int pixel_size = enabled->fb->bits_per_pixel / 8; | 1620 | int pixel_size = enabled->fb->bits_per_pixel / 8; |
| 1614 | unsigned long line_time_us; | 1621 | unsigned long line_time_us; |
| 1615 | int entries; | 1622 | int entries; |
| @@ -1658,8 +1665,9 @@ static void i9xx_update_wm(struct drm_device *dev) | |||
| 1658 | } | 1665 | } |
| 1659 | } | 1666 | } |
| 1660 | 1667 | ||
| 1661 | static void i830_update_wm(struct drm_device *dev) | 1668 | static void i830_update_wm(struct drm_crtc *unused_crtc) |
| 1662 | { | 1669 | { |
| 1670 | struct drm_device *dev = unused_crtc->dev; | ||
| 1663 | struct drm_i915_private *dev_priv = dev->dev_private; | 1671 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1664 | struct drm_crtc *crtc; | 1672 | struct drm_crtc *crtc; |
| 1665 | uint32_t fwater_lo; | 1673 | uint32_t fwater_lo; |
| @@ -1669,7 +1677,8 @@ static void i830_update_wm(struct drm_device *dev) | |||
| 1669 | if (crtc == NULL) | 1677 | if (crtc == NULL) |
| 1670 | return; | 1678 | return; |
| 1671 | 1679 | ||
| 1672 | planea_wm = intel_calculate_wm(crtc->mode.clock, &i830_wm_info, | 1680 | planea_wm = intel_calculate_wm(to_intel_crtc(crtc)->config.adjusted_mode.clock, |
| 1681 | &i830_wm_info, | ||
| 1673 | dev_priv->display.get_fifo_size(dev, 0), | 1682 | dev_priv->display.get_fifo_size(dev, 0), |
| 1674 | 4, latency_ns); | 1683 | 4, latency_ns); |
| 1675 | fwater_lo = I915_READ(FW_BLC) & ~0xfff; | 1684 | fwater_lo = I915_READ(FW_BLC) & ~0xfff; |
| @@ -1741,6 +1750,7 @@ static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane, | |||
| 1741 | int *fbc_wm, int *display_wm, int *cursor_wm) | 1750 | int *fbc_wm, int *display_wm, int *cursor_wm) |
| 1742 | { | 1751 | { |
| 1743 | struct drm_crtc *crtc; | 1752 | struct drm_crtc *crtc; |
| 1753 | const struct drm_display_mode *adjusted_mode; | ||
| 1744 | unsigned long line_time_us; | 1754 | unsigned long line_time_us; |
| 1745 | int hdisplay, htotal, pixel_size, clock; | 1755 | int hdisplay, htotal, pixel_size, clock; |
| 1746 | int line_count, line_size; | 1756 | int line_count, line_size; |
| @@ -1753,9 +1763,10 @@ static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane, | |||
| 1753 | } | 1763 | } |
| 1754 | 1764 | ||
| 1755 | crtc = intel_get_crtc_for_plane(dev, plane); | 1765 | crtc = intel_get_crtc_for_plane(dev, plane); |
| 1756 | hdisplay = crtc->mode.hdisplay; | 1766 | adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode; |
| 1757 | htotal = crtc->mode.htotal; | 1767 | clock = adjusted_mode->clock; |
| 1758 | clock = crtc->mode.clock; | 1768 | htotal = adjusted_mode->htotal; |
| 1769 | hdisplay = to_intel_crtc(crtc)->config.pipe_src_w; | ||
| 1759 | pixel_size = crtc->fb->bits_per_pixel / 8; | 1770 | pixel_size = crtc->fb->bits_per_pixel / 8; |
| 1760 | 1771 | ||
| 1761 | line_time_us = (htotal * 1000) / clock; | 1772 | line_time_us = (htotal * 1000) / clock; |
| @@ -1785,8 +1796,9 @@ static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane, | |||
| 1785 | display, cursor); | 1796 | display, cursor); |
| 1786 | } | 1797 | } |
| 1787 | 1798 | ||
| 1788 | static void ironlake_update_wm(struct drm_device *dev) | 1799 | static void ironlake_update_wm(struct drm_crtc *crtc) |
| 1789 | { | 1800 | { |
| 1801 | struct drm_device *dev = crtc->dev; | ||
| 1790 | struct drm_i915_private *dev_priv = dev->dev_private; | 1802 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1791 | int fbc_wm, plane_wm, cursor_wm; | 1803 | int fbc_wm, plane_wm, cursor_wm; |
| 1792 | unsigned int enabled; | 1804 | unsigned int enabled; |
| @@ -1868,8 +1880,9 @@ static void ironlake_update_wm(struct drm_device *dev) | |||
| 1868 | */ | 1880 | */ |
| 1869 | } | 1881 | } |
| 1870 | 1882 | ||
| 1871 | static void sandybridge_update_wm(struct drm_device *dev) | 1883 | static void sandybridge_update_wm(struct drm_crtc *crtc) |
| 1872 | { | 1884 | { |
| 1885 | struct drm_device *dev = crtc->dev; | ||
| 1873 | struct drm_i915_private *dev_priv = dev->dev_private; | 1886 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1874 | int latency = dev_priv->wm.pri_latency[0] * 100; /* In unit 0.1us */ | 1887 | int latency = dev_priv->wm.pri_latency[0] * 100; /* In unit 0.1us */ |
| 1875 | u32 val; | 1888 | u32 val; |
| @@ -1970,8 +1983,9 @@ static void sandybridge_update_wm(struct drm_device *dev) | |||
| 1970 | cursor_wm); | 1983 | cursor_wm); |
| 1971 | } | 1984 | } |
| 1972 | 1985 | ||
| 1973 | static void ivybridge_update_wm(struct drm_device *dev) | 1986 | static void ivybridge_update_wm(struct drm_crtc *crtc) |
| 1974 | { | 1987 | { |
| 1988 | struct drm_device *dev = crtc->dev; | ||
| 1975 | struct drm_i915_private *dev_priv = dev->dev_private; | 1989 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1976 | int latency = dev_priv->wm.pri_latency[0] * 100; /* In unit 0.1us */ | 1990 | int latency = dev_priv->wm.pri_latency[0] * 100; /* In unit 0.1us */ |
| 1977 | u32 val; | 1991 | u32 val; |
| @@ -2107,8 +2121,8 @@ static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev, | |||
| 2107 | uint64_t pipe_w, pipe_h, pfit_w, pfit_h; | 2121 | uint64_t pipe_w, pipe_h, pfit_w, pfit_h; |
| 2108 | uint32_t pfit_size = intel_crtc->config.pch_pfit.size; | 2122 | uint32_t pfit_size = intel_crtc->config.pch_pfit.size; |
| 2109 | 2123 | ||
| 2110 | pipe_w = intel_crtc->config.requested_mode.hdisplay; | 2124 | pipe_w = intel_crtc->config.pipe_src_w; |
| 2111 | pipe_h = intel_crtc->config.requested_mode.vdisplay; | 2125 | pipe_h = intel_crtc->config.pipe_src_h; |
| 2112 | pfit_w = (pfit_size >> 16) & 0xFFFF; | 2126 | pfit_w = (pfit_size >> 16) & 0xFFFF; |
| 2113 | pfit_h = pfit_size & 0xFFFF; | 2127 | pfit_h = pfit_size & 0xFFFF; |
| 2114 | if (pipe_w < pfit_w) | 2128 | if (pipe_w < pfit_w) |
| @@ -2196,7 +2210,7 @@ struct intel_wm_config { | |||
| 2196 | * For both WM_PIPE and WM_LP. | 2210 | * For both WM_PIPE and WM_LP. |
| 2197 | * mem_value must be in 0.1us units. | 2211 | * mem_value must be in 0.1us units. |
| 2198 | */ | 2212 | */ |
| 2199 | static uint32_t ilk_compute_pri_wm(struct hsw_pipe_wm_parameters *params, | 2213 | static uint32_t ilk_compute_pri_wm(const struct hsw_pipe_wm_parameters *params, |
| 2200 | uint32_t mem_value, | 2214 | uint32_t mem_value, |
| 2201 | bool is_lp) | 2215 | bool is_lp) |
| 2202 | { | 2216 | { |
| @@ -2225,7 +2239,7 @@ static uint32_t ilk_compute_pri_wm(struct hsw_pipe_wm_parameters *params, | |||
| 2225 | * For both WM_PIPE and WM_LP. | 2239 | * For both WM_PIPE and WM_LP. |
| 2226 | * mem_value must be in 0.1us units. | 2240 | * mem_value must be in 0.1us units. |
| 2227 | */ | 2241 | */ |
| 2228 | static uint32_t ilk_compute_spr_wm(struct hsw_pipe_wm_parameters *params, | 2242 | static uint32_t ilk_compute_spr_wm(const struct hsw_pipe_wm_parameters *params, |
| 2229 | uint32_t mem_value) | 2243 | uint32_t mem_value) |
| 2230 | { | 2244 | { |
| 2231 | uint32_t method1, method2; | 2245 | uint32_t method1, method2; |
| @@ -2248,7 +2262,7 @@ static uint32_t ilk_compute_spr_wm(struct hsw_pipe_wm_parameters *params, | |||
| 2248 | * For both WM_PIPE and WM_LP. | 2262 | * For both WM_PIPE and WM_LP. |
| 2249 | * mem_value must be in 0.1us units. | 2263 | * mem_value must be in 0.1us units. |
| 2250 | */ | 2264 | */ |
| 2251 | static uint32_t ilk_compute_cur_wm(struct hsw_pipe_wm_parameters *params, | 2265 | static uint32_t ilk_compute_cur_wm(const struct hsw_pipe_wm_parameters *params, |
| 2252 | uint32_t mem_value) | 2266 | uint32_t mem_value) |
| 2253 | { | 2267 | { |
| 2254 | if (!params->active || !params->cur.enabled) | 2268 | if (!params->active || !params->cur.enabled) |
| @@ -2262,7 +2276,7 @@ static uint32_t ilk_compute_cur_wm(struct hsw_pipe_wm_parameters *params, | |||
| 2262 | } | 2276 | } |
| 2263 | 2277 | ||
| 2264 | /* Only for WM_LP. */ | 2278 | /* Only for WM_LP. */ |
| 2265 | static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, | 2279 | static uint32_t ilk_compute_fbc_wm(const struct hsw_pipe_wm_parameters *params, |
| 2266 | uint32_t pri_val) | 2280 | uint32_t pri_val) |
| 2267 | { | 2281 | { |
| 2268 | if (!params->active || !params->pri.enabled) | 2282 | if (!params->active || !params->pri.enabled) |
| @@ -2413,7 +2427,7 @@ static bool ilk_check_wm(int level, | |||
| 2413 | 2427 | ||
| 2414 | static void ilk_compute_wm_level(struct drm_i915_private *dev_priv, | 2428 | static void ilk_compute_wm_level(struct drm_i915_private *dev_priv, |
| 2415 | int level, | 2429 | int level, |
| 2416 | struct hsw_pipe_wm_parameters *p, | 2430 | const struct hsw_pipe_wm_parameters *p, |
| 2417 | struct intel_wm_level *result) | 2431 | struct intel_wm_level *result) |
| 2418 | { | 2432 | { |
| 2419 | uint16_t pri_latency = dev_priv->wm.pri_latency[level]; | 2433 | uint16_t pri_latency = dev_priv->wm.pri_latency[level]; |
| @@ -2435,8 +2449,8 @@ static void ilk_compute_wm_level(struct drm_i915_private *dev_priv, | |||
| 2435 | } | 2449 | } |
| 2436 | 2450 | ||
| 2437 | static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv, | 2451 | static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv, |
| 2438 | int level, struct hsw_wm_maximums *max, | 2452 | int level, const struct hsw_wm_maximums *max, |
| 2439 | struct hsw_pipe_wm_parameters *params, | 2453 | const struct hsw_pipe_wm_parameters *params, |
| 2440 | struct intel_wm_level *result) | 2454 | struct intel_wm_level *result) |
| 2441 | { | 2455 | { |
| 2442 | enum pipe pipe; | 2456 | enum pipe pipe; |
| @@ -2454,33 +2468,31 @@ static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv, | |||
| 2454 | return ilk_check_wm(level, max, result); | 2468 | return ilk_check_wm(level, max, result); |
| 2455 | } | 2469 | } |
| 2456 | 2470 | ||
| 2457 | static uint32_t hsw_compute_wm_pipe(struct drm_i915_private *dev_priv, | 2471 | |
| 2458 | enum pipe pipe, | 2472 | static uint32_t hsw_compute_wm_pipe(struct drm_device *dev, |
| 2459 | struct hsw_pipe_wm_parameters *params) | 2473 | const struct hsw_pipe_wm_parameters *params) |
| 2460 | { | 2474 | { |
| 2461 | uint32_t pri_val, cur_val, spr_val; | 2475 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2462 | /* WM0 latency values stored in 0.1us units */ | 2476 | struct intel_wm_config config = { |
| 2463 | uint16_t pri_latency = dev_priv->wm.pri_latency[0]; | 2477 | .num_pipes_active = 1, |
| 2464 | uint16_t spr_latency = dev_priv->wm.spr_latency[0]; | 2478 | .sprites_enabled = params->spr.enabled, |
| 2465 | uint16_t cur_latency = dev_priv->wm.cur_latency[0]; | 2479 | .sprites_scaled = params->spr.scaled, |
| 2480 | }; | ||
| 2481 | struct hsw_wm_maximums max; | ||
| 2482 | struct intel_wm_level res; | ||
| 2483 | |||
| 2484 | if (!params->active) | ||
| 2485 | return 0; | ||
| 2486 | |||
| 2487 | ilk_wm_max(dev, 0, &config, INTEL_DDB_PART_1_2, &max); | ||
| 2466 | 2488 | ||
| 2467 | pri_val = ilk_compute_pri_wm(params, pri_latency, false); | 2489 | ilk_compute_wm_level(dev_priv, 0, params, &res); |
| 2468 | spr_val = ilk_compute_spr_wm(params, spr_latency); | ||
| 2469 | cur_val = ilk_compute_cur_wm(params, cur_latency); | ||
| 2470 | 2490 | ||
| 2471 | WARN(pri_val > 127, | 2491 | ilk_check_wm(0, &max, &res); |
| 2472 | "Primary WM error, mode not supported for pipe %c\n", | ||
| 2473 | pipe_name(pipe)); | ||
| 2474 | WARN(spr_val > 127, | ||
| 2475 | "Sprite WM error, mode not supported for pipe %c\n", | ||
| 2476 | pipe_name(pipe)); | ||
| 2477 | WARN(cur_val > 63, | ||
| 2478 | "Cursor WM error, mode not supported for pipe %c\n", | ||
| 2479 | pipe_name(pipe)); | ||
| 2480 | 2492 | ||
| 2481 | return (pri_val << WM0_PIPE_PLANE_SHIFT) | | 2493 | return (res.pri_val << WM0_PIPE_PLANE_SHIFT) | |
| 2482 | (spr_val << WM0_PIPE_SPRITE_SHIFT) | | 2494 | (res.spr_val << WM0_PIPE_SPRITE_SHIFT) | |
| 2483 | cur_val; | 2495 | res.cur_val; |
| 2484 | } | 2496 | } |
| 2485 | 2497 | ||
| 2486 | static uint32_t | 2498 | static uint32_t |
| @@ -2554,19 +2566,22 @@ static void intel_fixup_cur_wm_latency(struct drm_device *dev, uint16_t wm[5]) | |||
| 2554 | wm[3] *= 2; | 2566 | wm[3] *= 2; |
| 2555 | } | 2567 | } |
| 2556 | 2568 | ||
| 2557 | static void intel_print_wm_latency(struct drm_device *dev, | 2569 | static int ilk_wm_max_level(const struct drm_device *dev) |
| 2558 | const char *name, | ||
| 2559 | const uint16_t wm[5]) | ||
| 2560 | { | 2570 | { |
| 2561 | int level, max_level; | ||
| 2562 | |||
| 2563 | /* how many WM levels are we expecting */ | 2571 | /* how many WM levels are we expecting */ |
| 2564 | if (IS_HASWELL(dev)) | 2572 | if (IS_HASWELL(dev)) |
| 2565 | max_level = 4; | 2573 | return 4; |
| 2566 | else if (INTEL_INFO(dev)->gen >= 6) | 2574 | else if (INTEL_INFO(dev)->gen >= 6) |
| 2567 | max_level = 3; | 2575 | return 3; |
| 2568 | else | 2576 | else |
| 2569 | max_level = 2; | 2577 | return 2; |
| 2578 | } | ||
| 2579 | |||
| 2580 | static void intel_print_wm_latency(struct drm_device *dev, | ||
| 2581 | const char *name, | ||
| 2582 | const uint16_t wm[5]) | ||
| 2583 | { | ||
| 2584 | int level, max_level = ilk_wm_max_level(dev); | ||
| 2570 | 2585 | ||
| 2571 | for (level = 0; level <= max_level; level++) { | 2586 | for (level = 0; level <= max_level; level++) { |
| 2572 | unsigned int latency = wm[level]; | 2587 | unsigned int latency = wm[level]; |
| @@ -2633,8 +2648,7 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, | |||
| 2633 | p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); | 2648 | p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); |
| 2634 | p->pri.bytes_per_pixel = crtc->fb->bits_per_pixel / 8; | 2649 | p->pri.bytes_per_pixel = crtc->fb->bits_per_pixel / 8; |
| 2635 | p->cur.bytes_per_pixel = 4; | 2650 | p->cur.bytes_per_pixel = 4; |
| 2636 | p->pri.horiz_pixels = | 2651 | p->pri.horiz_pixels = intel_crtc->config.pipe_src_w; |
| 2637 | intel_crtc->config.requested_mode.hdisplay; | ||
| 2638 | p->cur.horiz_pixels = 64; | 2652 | p->cur.horiz_pixels = 64; |
| 2639 | /* TODO: for now, assume primary and cursor planes are always enabled. */ | 2653 | /* TODO: for now, assume primary and cursor planes are always enabled. */ |
| 2640 | p->pri.enabled = true; | 2654 | p->pri.enabled = true; |
| @@ -2664,8 +2678,8 @@ static void hsw_compute_wm_parameters(struct drm_device *dev, | |||
| 2664 | } | 2678 | } |
| 2665 | 2679 | ||
| 2666 | static void hsw_compute_wm_results(struct drm_device *dev, | 2680 | static void hsw_compute_wm_results(struct drm_device *dev, |
| 2667 | struct hsw_pipe_wm_parameters *params, | 2681 | const struct hsw_pipe_wm_parameters *params, |
| 2668 | struct hsw_wm_maximums *lp_maximums, | 2682 | const struct hsw_wm_maximums *lp_maximums, |
| 2669 | struct hsw_wm_values *results) | 2683 | struct hsw_wm_values *results) |
| 2670 | { | 2684 | { |
| 2671 | struct drm_i915_private *dev_priv = dev->dev_private; | 2685 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -2709,7 +2723,7 @@ static void hsw_compute_wm_results(struct drm_device *dev, | |||
| 2709 | } | 2723 | } |
| 2710 | 2724 | ||
| 2711 | for_each_pipe(pipe) | 2725 | for_each_pipe(pipe) |
| 2712 | results->wm_pipe[pipe] = hsw_compute_wm_pipe(dev_priv, pipe, | 2726 | results->wm_pipe[pipe] = hsw_compute_wm_pipe(dev, |
| 2713 | ¶ms[pipe]); | 2727 | ¶ms[pipe]); |
| 2714 | 2728 | ||
| 2715 | for_each_pipe(pipe) { | 2729 | for_each_pipe(pipe) { |
| @@ -2841,8 +2855,9 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv, | |||
| 2841 | I915_WRITE(WM3_LP_ILK, results->wm_lp[2]); | 2855 | I915_WRITE(WM3_LP_ILK, results->wm_lp[2]); |
| 2842 | } | 2856 | } |
| 2843 | 2857 | ||
| 2844 | static void haswell_update_wm(struct drm_device *dev) | 2858 | static void haswell_update_wm(struct drm_crtc *crtc) |
| 2845 | { | 2859 | { |
| 2860 | struct drm_device *dev = crtc->dev; | ||
| 2846 | struct drm_i915_private *dev_priv = dev->dev_private; | 2861 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2847 | struct hsw_wm_maximums lp_max_1_2, lp_max_5_6; | 2862 | struct hsw_wm_maximums lp_max_1_2, lp_max_5_6; |
| 2848 | struct hsw_pipe_wm_parameters params[3]; | 2863 | struct hsw_pipe_wm_parameters params[3]; |
| @@ -2879,7 +2894,7 @@ static void haswell_update_sprite_wm(struct drm_plane *plane, | |||
| 2879 | intel_plane->wm.horiz_pixels = sprite_width; | 2894 | intel_plane->wm.horiz_pixels = sprite_width; |
| 2880 | intel_plane->wm.bytes_per_pixel = pixel_size; | 2895 | intel_plane->wm.bytes_per_pixel = pixel_size; |
| 2881 | 2896 | ||
| 2882 | haswell_update_wm(plane->dev); | 2897 | haswell_update_wm(crtc); |
| 2883 | } | 2898 | } |
| 2884 | 2899 | ||
| 2885 | static bool | 2900 | static bool |
| @@ -2898,7 +2913,7 @@ sandybridge_compute_sprite_wm(struct drm_device *dev, int plane, | |||
| 2898 | return false; | 2913 | return false; |
| 2899 | } | 2914 | } |
| 2900 | 2915 | ||
| 2901 | clock = crtc->mode.clock; | 2916 | clock = to_intel_crtc(crtc)->config.adjusted_mode.clock; |
| 2902 | 2917 | ||
| 2903 | /* Use the small buffer method to calculate the sprite watermark */ | 2918 | /* Use the small buffer method to calculate the sprite watermark */ |
| 2904 | entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; | 2919 | entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; |
| @@ -2933,7 +2948,7 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, | |||
| 2933 | } | 2948 | } |
| 2934 | 2949 | ||
| 2935 | crtc = intel_get_crtc_for_plane(dev, plane); | 2950 | crtc = intel_get_crtc_for_plane(dev, plane); |
| 2936 | clock = crtc->mode.clock; | 2951 | clock = to_intel_crtc(crtc)->config.adjusted_mode.clock; |
| 2937 | if (!clock) { | 2952 | if (!clock) { |
| 2938 | *sprite_wm = 0; | 2953 | *sprite_wm = 0; |
| 2939 | return false; | 2954 | return false; |
| @@ -3076,12 +3091,12 @@ static void sandybridge_update_sprite_wm(struct drm_plane *plane, | |||
| 3076 | * We don't use the sprite, so we can ignore that. And on Crestline we have | 3091 | * We don't use the sprite, so we can ignore that. And on Crestline we have |
| 3077 | * to set the non-SR watermarks to 8. | 3092 | * to set the non-SR watermarks to 8. |
| 3078 | */ | 3093 | */ |
| 3079 | void intel_update_watermarks(struct drm_device *dev) | 3094 | void intel_update_watermarks(struct drm_crtc *crtc) |
| 3080 | { | 3095 | { |
| 3081 | struct drm_i915_private *dev_priv = dev->dev_private; | 3096 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
| 3082 | 3097 | ||
| 3083 | if (dev_priv->display.update_wm) | 3098 | if (dev_priv->display.update_wm) |
| 3084 | dev_priv->display.update_wm(dev); | 3099 | dev_priv->display.update_wm(crtc); |
| 3085 | } | 3100 | } |
| 3086 | 3101 | ||
| 3087 | void intel_update_sprite_watermarks(struct drm_plane *plane, | 3102 | void intel_update_sprite_watermarks(struct drm_plane *plane, |
| @@ -3773,7 +3788,7 @@ static void valleyview_enable_rps(struct drm_device *dev) | |||
| 3773 | { | 3788 | { |
| 3774 | struct drm_i915_private *dev_priv = dev->dev_private; | 3789 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 3775 | struct intel_ring_buffer *ring; | 3790 | struct intel_ring_buffer *ring; |
| 3776 | u32 gtfifodbg, val; | 3791 | u32 gtfifodbg, val, rc6_mode = 0; |
| 3777 | int i; | 3792 | int i; |
| 3778 | 3793 | ||
| 3779 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); | 3794 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); |
| @@ -3813,8 +3828,9 @@ static void valleyview_enable_rps(struct drm_device *dev) | |||
| 3813 | 3828 | ||
| 3814 | /* allows RC6 residency counter to work */ | 3829 | /* allows RC6 residency counter to work */ |
| 3815 | I915_WRITE(0x138104, _MASKED_BIT_ENABLE(0x3)); | 3830 | I915_WRITE(0x138104, _MASKED_BIT_ENABLE(0x3)); |
| 3816 | I915_WRITE(GEN6_RC_CONTROL, | 3831 | if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE) |
| 3817 | GEN7_RC_CTL_TO_MODE); | 3832 | rc6_mode = GEN7_RC_CTL_TO_MODE; |
| 3833 | I915_WRITE(GEN6_RC_CONTROL, rc6_mode); | ||
| 3818 | 3834 | ||
| 3819 | val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); | 3835 | val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); |
| 3820 | switch ((val >> 6) & 3) { | 3836 | switch ((val >> 6) & 3) { |
| @@ -5267,6 +5283,7 @@ bool intel_display_power_enabled(struct drm_device *dev, | |||
| 5267 | case POWER_DOMAIN_PIPE_A: | 5283 | case POWER_DOMAIN_PIPE_A: |
| 5268 | case POWER_DOMAIN_TRANSCODER_EDP: | 5284 | case POWER_DOMAIN_TRANSCODER_EDP: |
| 5269 | return true; | 5285 | return true; |
| 5286 | case POWER_DOMAIN_VGA: | ||
| 5270 | case POWER_DOMAIN_PIPE_B: | 5287 | case POWER_DOMAIN_PIPE_B: |
| 5271 | case POWER_DOMAIN_PIPE_C: | 5288 | case POWER_DOMAIN_PIPE_C: |
| 5272 | case POWER_DOMAIN_PIPE_A_PANEL_FITTER: | 5289 | case POWER_DOMAIN_PIPE_A_PANEL_FITTER: |
| @@ -5329,6 +5346,81 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) | |||
| 5329 | } | 5346 | } |
| 5330 | } | 5347 | } |
| 5331 | 5348 | ||
| 5349 | static void __intel_power_well_get(struct i915_power_well *power_well) | ||
| 5350 | { | ||
| 5351 | if (!power_well->count++) | ||
| 5352 | __intel_set_power_well(power_well->device, true); | ||
| 5353 | } | ||
| 5354 | |||
| 5355 | static void __intel_power_well_put(struct i915_power_well *power_well) | ||
| 5356 | { | ||
| 5357 | WARN_ON(!power_well->count); | ||
| 5358 | if (!--power_well->count) | ||
| 5359 | __intel_set_power_well(power_well->device, false); | ||
| 5360 | } | ||
| 5361 | |||
| 5362 | void intel_display_power_get(struct drm_device *dev, | ||
| 5363 | enum intel_display_power_domain domain) | ||
| 5364 | { | ||
| 5365 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 5366 | struct i915_power_well *power_well = &dev_priv->power_well; | ||
| 5367 | |||
| 5368 | if (!HAS_POWER_WELL(dev)) | ||
| 5369 | return; | ||
| 5370 | |||
| 5371 | switch (domain) { | ||
| 5372 | case POWER_DOMAIN_PIPE_A: | ||
| 5373 | case POWER_DOMAIN_TRANSCODER_EDP: | ||
| 5374 | return; | ||
| 5375 | case POWER_DOMAIN_VGA: | ||
| 5376 | case POWER_DOMAIN_PIPE_B: | ||
| 5377 | case POWER_DOMAIN_PIPE_C: | ||
| 5378 | case POWER_DOMAIN_PIPE_A_PANEL_FITTER: | ||
| 5379 | case POWER_DOMAIN_PIPE_B_PANEL_FITTER: | ||
| 5380 | case POWER_DOMAIN_PIPE_C_PANEL_FITTER: | ||
| 5381 | case POWER_DOMAIN_TRANSCODER_A: | ||
| 5382 | case POWER_DOMAIN_TRANSCODER_B: | ||
| 5383 | case POWER_DOMAIN_TRANSCODER_C: | ||
| 5384 | spin_lock_irq(&power_well->lock); | ||
| 5385 | __intel_power_well_get(power_well); | ||
| 5386 | spin_unlock_irq(&power_well->lock); | ||
| 5387 | return; | ||
| 5388 | default: | ||
| 5389 | BUG(); | ||
| 5390 | } | ||
| 5391 | } | ||
| 5392 | |||
| 5393 | void intel_display_power_put(struct drm_device *dev, | ||
| 5394 | enum intel_display_power_domain domain) | ||
| 5395 | { | ||
| 5396 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 5397 | struct i915_power_well *power_well = &dev_priv->power_well; | ||
| 5398 | |||
| 5399 | if (!HAS_POWER_WELL(dev)) | ||
| 5400 | return; | ||
| 5401 | |||
| 5402 | switch (domain) { | ||
| 5403 | case POWER_DOMAIN_PIPE_A: | ||
| 5404 | case POWER_DOMAIN_TRANSCODER_EDP: | ||
| 5405 | return; | ||
| 5406 | case POWER_DOMAIN_VGA: | ||
| 5407 | case POWER_DOMAIN_PIPE_B: | ||
| 5408 | case POWER_DOMAIN_PIPE_C: | ||
| 5409 | case POWER_DOMAIN_PIPE_A_PANEL_FITTER: | ||
| 5410 | case POWER_DOMAIN_PIPE_B_PANEL_FITTER: | ||
| 5411 | case POWER_DOMAIN_PIPE_C_PANEL_FITTER: | ||
| 5412 | case POWER_DOMAIN_TRANSCODER_A: | ||
| 5413 | case POWER_DOMAIN_TRANSCODER_B: | ||
| 5414 | case POWER_DOMAIN_TRANSCODER_C: | ||
| 5415 | spin_lock_irq(&power_well->lock); | ||
| 5416 | __intel_power_well_put(power_well); | ||
| 5417 | spin_unlock_irq(&power_well->lock); | ||
| 5418 | return; | ||
| 5419 | default: | ||
| 5420 | BUG(); | ||
| 5421 | } | ||
| 5422 | } | ||
| 5423 | |||
| 5332 | static struct i915_power_well *hsw_pwr; | 5424 | static struct i915_power_well *hsw_pwr; |
| 5333 | 5425 | ||
| 5334 | /* Display audio driver power well request */ | 5426 | /* Display audio driver power well request */ |
| @@ -5338,9 +5430,7 @@ void i915_request_power_well(void) | |||
| 5338 | return; | 5430 | return; |
| 5339 | 5431 | ||
| 5340 | spin_lock_irq(&hsw_pwr->lock); | 5432 | spin_lock_irq(&hsw_pwr->lock); |
| 5341 | if (!hsw_pwr->count++ && | 5433 | __intel_power_well_get(hsw_pwr); |
| 5342 | !hsw_pwr->i915_request) | ||
| 5343 | __intel_set_power_well(hsw_pwr->device, true); | ||
| 5344 | spin_unlock_irq(&hsw_pwr->lock); | 5434 | spin_unlock_irq(&hsw_pwr->lock); |
| 5345 | } | 5435 | } |
| 5346 | EXPORT_SYMBOL_GPL(i915_request_power_well); | 5436 | EXPORT_SYMBOL_GPL(i915_request_power_well); |
| @@ -5352,10 +5442,7 @@ void i915_release_power_well(void) | |||
| 5352 | return; | 5442 | return; |
| 5353 | 5443 | ||
| 5354 | spin_lock_irq(&hsw_pwr->lock); | 5444 | spin_lock_irq(&hsw_pwr->lock); |
| 5355 | WARN_ON(!hsw_pwr->count); | 5445 | __intel_power_well_put(hsw_pwr); |
| 5356 | if (!--hsw_pwr->count && | ||
| 5357 | !hsw_pwr->i915_request) | ||
| 5358 | __intel_set_power_well(hsw_pwr->device, false); | ||
| 5359 | spin_unlock_irq(&hsw_pwr->lock); | 5446 | spin_unlock_irq(&hsw_pwr->lock); |
| 5360 | } | 5447 | } |
| 5361 | EXPORT_SYMBOL_GPL(i915_release_power_well); | 5448 | EXPORT_SYMBOL_GPL(i915_release_power_well); |
| @@ -5390,15 +5477,37 @@ void intel_set_power_well(struct drm_device *dev, bool enable) | |||
| 5390 | return; | 5477 | return; |
| 5391 | 5478 | ||
| 5392 | spin_lock_irq(&power_well->lock); | 5479 | spin_lock_irq(&power_well->lock); |
| 5480 | |||
| 5481 | /* | ||
| 5482 | * This function will only ever contribute one | ||
| 5483 | * to the power well reference count. i915_request | ||
| 5484 | * is what tracks whether we have or have not | ||
| 5485 | * added the one to the reference count. | ||
| 5486 | */ | ||
| 5487 | if (power_well->i915_request == enable) | ||
| 5488 | goto out; | ||
| 5489 | |||
| 5393 | power_well->i915_request = enable; | 5490 | power_well->i915_request = enable; |
| 5394 | 5491 | ||
| 5395 | /* only reject "disable" power well request */ | 5492 | if (enable) |
| 5396 | if (power_well->count && !enable) { | 5493 | __intel_power_well_get(power_well); |
| 5397 | spin_unlock_irq(&power_well->lock); | 5494 | else |
| 5495 | __intel_power_well_put(power_well); | ||
| 5496 | |||
| 5497 | out: | ||
| 5498 | spin_unlock_irq(&power_well->lock); | ||
| 5499 | } | ||
| 5500 | |||
| 5501 | void intel_resume_power_well(struct drm_device *dev) | ||
| 5502 | { | ||
| 5503 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 5504 | struct i915_power_well *power_well = &dev_priv->power_well; | ||
| 5505 | |||
| 5506 | if (!HAS_POWER_WELL(dev)) | ||
| 5398 | return; | 5507 | return; |
| 5399 | } | ||
| 5400 | 5508 | ||
| 5401 | __intel_set_power_well(dev, enable); | 5509 | spin_lock_irq(&power_well->lock); |
| 5510 | __intel_set_power_well(dev, power_well->count > 0); | ||
| 5402 | spin_unlock_irq(&power_well->lock); | 5511 | spin_unlock_irq(&power_well->lock); |
| 5403 | } | 5512 | } |
| 5404 | 5513 | ||
| @@ -5417,6 +5526,7 @@ void intel_init_power_well(struct drm_device *dev) | |||
| 5417 | 5526 | ||
| 5418 | /* For now, we need the power well to be always enabled. */ | 5527 | /* For now, we need the power well to be always enabled. */ |
| 5419 | intel_set_power_well(dev, true); | 5528 | intel_set_power_well(dev, true); |
| 5529 | intel_resume_power_well(dev); | ||
| 5420 | 5530 | ||
| 5421 | /* We're taking over the BIOS, so clear any requests made by it since | 5531 | /* We're taking over the BIOS, so clear any requests made by it since |
| 5422 | * the driver is in charge now. */ | 5532 | * the driver is in charge now. */ |
