aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-04-29 15:56:12 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-04-29 17:29:38 -0400
commit1bd1bd806037af04dd1d7bdd39b2b04090c10d2c (patch)
treeea4cfd7be346f089d7689d7f5e3e5902b25538c1 /drivers/gpu/drm/i915/intel_display.c
parent72419203cab9acf173956f5564639b0012cd2604 (diff)
drm/i915: hw state readout support for pipe timings
This does duplicate the logic in intel_crtc_mode_get a bit, but the issue is that we also should handle interlace modes and other insanity correctly. Hence I've opted for a sligthly more elaborate route where we first read out the crtc timings for the adjusted mode, and then optionally (not sure if we really need it) compute the modeline from that. v2: Also read out the pipe source dimensions into the requested mode. v3: Rebase on top of the moved cpu_transcoder. v4: Simplify CHECK_FLAGS logic as suggested by Chris Wilson. Also properly #undef that macro again. Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> (v3) [danvet: Use the existing mask for interlaced bits, spotted by Mika.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f442e0bc8e9f..9b0d6b03aa1c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4721,6 +4721,45 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
4721 ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); 4721 ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
4722} 4722}
4723 4723
4724static void intel_get_pipe_timings(struct intel_crtc *crtc,
4725 struct intel_crtc_config *pipe_config)
4726{
4727 struct drm_device *dev = crtc->base.dev;
4728 struct drm_i915_private *dev_priv = dev->dev_private;
4729 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
4730 uint32_t tmp;
4731
4732 tmp = I915_READ(HTOTAL(cpu_transcoder));
4733 pipe_config->adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
4734 pipe_config->adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
4735 tmp = I915_READ(HBLANK(cpu_transcoder));
4736 pipe_config->adjusted_mode.crtc_hblank_start = (tmp & 0xffff) + 1;
4737 pipe_config->adjusted_mode.crtc_hblank_end = ((tmp >> 16) & 0xffff) + 1;
4738 tmp = I915_READ(HSYNC(cpu_transcoder));
4739 pipe_config->adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
4740 pipe_config->adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
4741
4742 tmp = I915_READ(VTOTAL(cpu_transcoder));
4743 pipe_config->adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
4744 pipe_config->adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
4745 tmp = I915_READ(VBLANK(cpu_transcoder));
4746 pipe_config->adjusted_mode.crtc_vblank_start = (tmp & 0xffff) + 1;
4747 pipe_config->adjusted_mode.crtc_vblank_end = ((tmp >> 16) & 0xffff) + 1;
4748 tmp = I915_READ(VSYNC(cpu_transcoder));
4749 pipe_config->adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
4750 pipe_config->adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
4751
4752 if (I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK) {
4753 pipe_config->adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
4754 pipe_config->adjusted_mode.crtc_vtotal += 1;
4755 pipe_config->adjusted_mode.crtc_vblank_end += 1;
4756 }
4757
4758 tmp = I915_READ(PIPESRC(crtc->pipe));
4759 pipe_config->requested_mode.vdisplay = (tmp & 0xffff) + 1;
4760 pipe_config->requested_mode.hdisplay = ((tmp >> 16) & 0xffff) + 1;
4761}
4762
4724static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) 4763static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
4725{ 4764{
4726 struct drm_device *dev = intel_crtc->base.dev; 4765 struct drm_device *dev = intel_crtc->base.dev;
@@ -4937,6 +4976,8 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
4937 if (!(tmp & PIPECONF_ENABLE)) 4976 if (!(tmp & PIPECONF_ENABLE))
4938 return false; 4977 return false;
4939 4978
4979 intel_get_pipe_timings(crtc, pipe_config);
4980
4940 return true; 4981 return true;
4941} 4982}
4942 4983
@@ -5854,6 +5895,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
5854 ironlake_get_fdi_m_n_config(crtc, pipe_config); 5895 ironlake_get_fdi_m_n_config(crtc, pipe_config);
5855 } 5896 }
5856 5897
5898 intel_get_pipe_timings(crtc, pipe_config);
5899
5857 return true; 5900 return true;
5858} 5901}
5859 5902
@@ -6001,6 +6044,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
6001 ironlake_get_fdi_m_n_config(crtc, pipe_config); 6044 ironlake_get_fdi_m_n_config(crtc, pipe_config);
6002 } 6045 }
6003 6046
6047 intel_get_pipe_timings(crtc, pipe_config);
6048
6004 return true; 6049 return true;
6005} 6050}
6006 6051
@@ -7978,6 +8023,15 @@ intel_pipe_config_compare(struct intel_crtc_config *current_config,
7978 return false; \ 8023 return false; \
7979 } 8024 }
7980 8025
8026#define PIPE_CONF_CHECK_FLAGS(name, mask) \
8027 if ((current_config->name ^ pipe_config->name) & (mask)) { \
8028 DRM_ERROR("mismatch in " #name " " \
8029 "(expected %i, found %i)\n", \
8030 current_config->name & (mask), \
8031 pipe_config->name & (mask)); \
8032 return false; \
8033 }
8034
7981 PIPE_CONF_CHECK_I(has_pch_encoder); 8035 PIPE_CONF_CHECK_I(has_pch_encoder);
7982 PIPE_CONF_CHECK_I(fdi_lanes); 8036 PIPE_CONF_CHECK_I(fdi_lanes);
7983 PIPE_CONF_CHECK_I(fdi_m_n.gmch_m); 8037 PIPE_CONF_CHECK_I(fdi_m_n.gmch_m);
@@ -7986,7 +8040,28 @@ intel_pipe_config_compare(struct intel_crtc_config *current_config,
7986 PIPE_CONF_CHECK_I(fdi_m_n.link_n); 8040 PIPE_CONF_CHECK_I(fdi_m_n.link_n);
7987 PIPE_CONF_CHECK_I(fdi_m_n.tu); 8041 PIPE_CONF_CHECK_I(fdi_m_n.tu);
7988 8042
8043 PIPE_CONF_CHECK_I(adjusted_mode.crtc_hdisplay);
8044 PIPE_CONF_CHECK_I(adjusted_mode.crtc_htotal);
8045 PIPE_CONF_CHECK_I(adjusted_mode.crtc_hblank_start);
8046 PIPE_CONF_CHECK_I(adjusted_mode.crtc_hblank_end);
8047 PIPE_CONF_CHECK_I(adjusted_mode.crtc_hsync_start);
8048 PIPE_CONF_CHECK_I(adjusted_mode.crtc_hsync_end);
8049
8050 PIPE_CONF_CHECK_I(adjusted_mode.crtc_vdisplay);
8051 PIPE_CONF_CHECK_I(adjusted_mode.crtc_vtotal);
8052 PIPE_CONF_CHECK_I(adjusted_mode.crtc_vblank_start);
8053 PIPE_CONF_CHECK_I(adjusted_mode.crtc_vblank_end);
8054 PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_start);
8055 PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_end);
8056
8057 PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
8058 DRM_MODE_FLAG_INTERLACE);
8059
8060 PIPE_CONF_CHECK_I(requested_mode.hdisplay);
8061 PIPE_CONF_CHECK_I(requested_mode.vdisplay);
8062
7989#undef PIPE_CONF_CHECK_I 8063#undef PIPE_CONF_CHECK_I
8064#undef PIPE_CONF_CHECK_FLAGS
7990 8065
7991 return true; 8066 return true;
7992} 8067}