aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorRodrigo Vivi <rodrigo.vivi@gmail.com>2013-07-11 17:45:00 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-07-18 04:17:21 -0400
commit3f51e4713fc57ab0fc225c3f0e67578a53c24a11 (patch)
tree805ccec916c12cc168dfb34a8bd07d957d69e654 /drivers/gpu
parente91fd8c6dec2ffa903b4f695fce4b9d7248ed2d5 (diff)
drm/i915: Match all PSR mode entry conditions before enabling it.
v2: Prefer seq_puts to seq_printf by Paulo Zanoni. v3: small changes like avoiding calling dp_to_dig_port twice as noticed by Paulo Zanoni. v4: Avoiding reading non-existent registers - noticed by Paulo on first psr debugfs patch. v5: Accepting more suggestions from Paulo: * check sw interlace flag instead of i915_read * introduce PSR_S3D_ENABLED to avoid forgeting it whenever added. Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@gmail.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Shobhit Kumar <shobhit.kumar@intel.com> [danvet: Fix up debugfs output (spotted by Paulo) and rip out the power well check since we really can't do that in a race-free manner, so it's bogus.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c42
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h13
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h7
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c67
4 files changed, 123 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 65619e6fde86..973f2727d703 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1550,17 +1550,49 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
1550 struct drm_info_node *node = m->private; 1550 struct drm_info_node *node = m->private;
1551 struct drm_device *dev = node->minor->dev; 1551 struct drm_device *dev = node->minor->dev;
1552 struct drm_i915_private *dev_priv = dev->dev_private; 1552 struct drm_i915_private *dev_priv = dev->dev_private;
1553 u32 psrctl, psrstat, psrperf; 1553 u32 psrstat, psrperf;
1554 1554
1555 if (!IS_HASWELL(dev)) { 1555 if (!IS_HASWELL(dev)) {
1556 seq_puts(m, "PSR not supported on this platform\n"); 1556 seq_puts(m, "PSR not supported on this platform\n");
1557 } else if (IS_HASWELL(dev) && I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE) {
1558 seq_puts(m, "PSR enabled\n");
1559 } else {
1560 seq_puts(m, "PSR disabled: ");
1561 switch (dev_priv->no_psr_reason) {
1562 case PSR_NO_SOURCE:
1563 seq_puts(m, "not supported on this platform");
1564 break;
1565 case PSR_NO_SINK:
1566 seq_puts(m, "not supported by panel");
1567 break;
1568 case PSR_CRTC_NOT_ACTIVE:
1569 seq_puts(m, "crtc not active");
1570 break;
1571 case PSR_PWR_WELL_ENABLED:
1572 seq_puts(m, "power well enabled");
1573 break;
1574 case PSR_NOT_TILED:
1575 seq_puts(m, "not tiled");
1576 break;
1577 case PSR_SPRITE_ENABLED:
1578 seq_puts(m, "sprite enabled");
1579 break;
1580 case PSR_S3D_ENABLED:
1581 seq_puts(m, "stereo 3d enabled");
1582 break;
1583 case PSR_INTERLACED_ENABLED:
1584 seq_puts(m, "interlaced enabled");
1585 break;
1586 case PSR_HSW_NOT_DDIA:
1587 seq_puts(m, "HSW ties PSR to DDI A (eDP)");
1588 break;
1589 default:
1590 seq_puts(m, "unknown reason");
1591 }
1592 seq_puts(m, "\n");
1557 return 0; 1593 return 0;
1558 } 1594 }
1559 1595
1560 psrctl = I915_READ(EDP_PSR_CTL);
1561 seq_printf(m, "PSR Enabled: %s\n",
1562 yesno(psrctl & EDP_PSR_ENABLE));
1563
1564 psrstat = I915_READ(EDP_PSR_STATUS_CTL); 1596 psrstat = I915_READ(EDP_PSR_STATUS_CTL);
1565 1597
1566 seq_puts(m, "PSR Current State: "); 1598 seq_puts(m, "PSR Current State: ");
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bd1b95ea6a28..21d55f855d16 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -593,6 +593,17 @@ struct i915_fbc {
593 } no_fbc_reason; 593 } no_fbc_reason;
594}; 594};
595 595
596enum no_psr_reason {
597 PSR_NO_SOURCE, /* Not supported on platform */
598 PSR_NO_SINK, /* Not supported by panel */
599 PSR_CRTC_NOT_ACTIVE,
600 PSR_PWR_WELL_ENABLED,
601 PSR_NOT_TILED,
602 PSR_SPRITE_ENABLED,
603 PSR_S3D_ENABLED,
604 PSR_INTERLACED_ENABLED,
605 PSR_HSW_NOT_DDIA,
606};
596 607
597enum intel_pch { 608enum intel_pch {
598 PCH_NONE = 0, /* No PCH present */ 609 PCH_NONE = 0, /* No PCH present */
@@ -1173,6 +1184,8 @@ typedef struct drm_i915_private {
1173 /* Haswell power well */ 1184 /* Haswell power well */
1174 struct i915_power_well power_well; 1185 struct i915_power_well power_well;
1175 1186
1187 enum no_psr_reason no_psr_reason;
1188
1176 struct i915_gpu_error gpu_error; 1189 struct i915_gpu_error gpu_error;
1177 1190
1178 struct drm_i915_gem_object *vlv_pctx; 1191 struct drm_i915_gem_object *vlv_pctx;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index bb898bfe053d..1d710966983e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4150,6 +4150,13 @@
4150#define HSW_TVIDEO_DIP_VSC_DATA(trans) \ 4150#define HSW_TVIDEO_DIP_VSC_DATA(trans) \
4151 _TRANSCODER(trans, HSW_VIDEO_DIP_VSC_DATA_A, HSW_VIDEO_DIP_VSC_DATA_B) 4151 _TRANSCODER(trans, HSW_VIDEO_DIP_VSC_DATA_A, HSW_VIDEO_DIP_VSC_DATA_B)
4152 4152
4153#define HSW_STEREO_3D_CTL_A 0x70020
4154#define S3D_ENABLE (1<<31)
4155#define HSW_STEREO_3D_CTL_B 0x71020
4156
4157#define HSW_STEREO_3D_CTL(trans) \
4158 _TRANSCODER(trans, HSW_STEREO_3D_CTL_A, HSW_STEREO_3D_CTL_A)
4159
4153#define _PCH_TRANS_HTOTAL_B 0xe1000 4160#define _PCH_TRANS_HTOTAL_B 0xe1000
4154#define _PCH_TRANS_HBLANK_B 0xe1004 4161#define _PCH_TRANS_HBLANK_B 0xe1004
4155#define _PCH_TRANS_HSYNC_B 0xe1008 4162#define _PCH_TRANS_HSYNC_B 0xe1008
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index bb3593db42e9..3ce1b872935e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1492,11 +1492,76 @@ static void intel_edp_psr_enable_source(struct intel_dp *intel_dp)
1492 EDP_PSR_ENABLE); 1492 EDP_PSR_ENABLE);
1493} 1493}
1494 1494
1495static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp)
1496{
1497 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
1498 struct drm_device *dev = dig_port->base.base.dev;
1499 struct drm_i915_private *dev_priv = dev->dev_private;
1500 struct drm_crtc *crtc = dig_port->base.base.crtc;
1501 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1502 struct drm_i915_gem_object *obj = to_intel_framebuffer(crtc->fb)->obj;
1503 struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
1504
1505 if (!IS_HASWELL(dev)) {
1506 DRM_DEBUG_KMS("PSR not supported on this platform\n");
1507 dev_priv->no_psr_reason = PSR_NO_SOURCE;
1508 return false;
1509 }
1510
1511 if ((intel_encoder->type != INTEL_OUTPUT_EDP) ||
1512 (dig_port->port != PORT_A)) {
1513 DRM_DEBUG_KMS("HSW ties PSR to DDI A (eDP)\n");
1514 dev_priv->no_psr_reason = PSR_HSW_NOT_DDIA;
1515 return false;
1516 }
1517
1518 if (!is_edp_psr(intel_dp)) {
1519 DRM_DEBUG_KMS("PSR not supported by this panel\n");
1520 dev_priv->no_psr_reason = PSR_NO_SINK;
1521 return false;
1522 }
1523
1524 if (!intel_crtc->active || !crtc->fb || !crtc->mode.clock) {
1525 DRM_DEBUG_KMS("crtc not active for PSR\n");
1526 dev_priv->no_psr_reason = PSR_CRTC_NOT_ACTIVE;
1527 return false;
1528 }
1529
1530 if (obj->tiling_mode != I915_TILING_X ||
1531 obj->fence_reg == I915_FENCE_REG_NONE) {
1532 DRM_DEBUG_KMS("PSR condition failed: fb not tiled or fenced\n");
1533 dev_priv->no_psr_reason = PSR_NOT_TILED;
1534 return false;
1535 }
1536
1537 if (I915_READ(SPRCTL(intel_crtc->pipe)) & SPRITE_ENABLE) {
1538 DRM_DEBUG_KMS("PSR condition failed: Sprite is Enabled\n");
1539 dev_priv->no_psr_reason = PSR_SPRITE_ENABLED;
1540 return false;
1541 }
1542
1543 if (I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config.cpu_transcoder)) &
1544 S3D_ENABLE) {
1545 DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n");
1546 dev_priv->no_psr_reason = PSR_S3D_ENABLED;
1547 return false;
1548 }
1549
1550 if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
1551 DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n");
1552 dev_priv->no_psr_reason = PSR_INTERLACED_ENABLED;
1553 return false;
1554 }
1555
1556 return true;
1557}
1558
1495void intel_edp_psr_enable(struct intel_dp *intel_dp) 1559void intel_edp_psr_enable(struct intel_dp *intel_dp)
1496{ 1560{
1497 struct drm_device *dev = intel_dp_to_dev(intel_dp); 1561 struct drm_device *dev = intel_dp_to_dev(intel_dp);
1498 1562
1499 if (!is_edp_psr(intel_dp) || intel_edp_is_psr_enabled(dev)) 1563 if (!intel_edp_psr_match_conditions(intel_dp) ||
1564 intel_edp_is_psr_enabled(dev))
1500 return; 1565 return;
1501 1566
1502 /* Setup PSR once */ 1567 /* Setup PSR once */