aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorPaulo Zanoni <paulo.r.zanoni@intel.com>2012-10-01 17:10:53 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-10-02 07:24:37 -0400
commitb0e77b9c6b2fc21ec2e3d8b54edf8757a7c6a8dd (patch)
treeb683f553f6deaaee484cdfd9782a001fe9263351 /drivers/gpu/drm/i915/intel_display.c
parent749052fba650a644b29ed2ae35cd985f736401b3 (diff)
drm/i915: extract intel_set_pipe_timings from crtc_mode_set
Version 2: call intel_set_pipe_timings from both i9xx_crtc_mode_set and ironlake_crtc_mode_set, instead of just ironlake, as requested by Daniel Vetter. The problem caused by calling this function from i9xx_crtc_mode_set too is that now on i9xx we write to PIPESRC before writing to DSPSIZE and DSPPOS. I could not find any evidence in our documentation that this won't work, and the docs actually say the pipe registers should be set before the plane registers. Version 3: don't remove pipeconf bits on i9xx_crtc_mode_set. Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> 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.c124
1 files changed, 54 insertions, 70 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ed0dcea4a727..6cf0d003d715 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4290,6 +4290,55 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
4290 I915_WRITE(DPLL(pipe), dpll); 4290 I915_WRITE(DPLL(pipe), dpll);
4291} 4291}
4292 4292
4293static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
4294 struct drm_display_mode *mode,
4295 struct drm_display_mode *adjusted_mode)
4296{
4297 struct drm_device *dev = intel_crtc->base.dev;
4298 struct drm_i915_private *dev_priv = dev->dev_private;
4299 enum pipe pipe = intel_crtc->pipe;
4300 uint32_t vsyncshift;
4301
4302 if (!IS_GEN2(dev) && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
4303 /* the chip adds 2 halflines automatically */
4304 adjusted_mode->crtc_vtotal -= 1;
4305 adjusted_mode->crtc_vblank_end -= 1;
4306 vsyncshift = adjusted_mode->crtc_hsync_start
4307 - adjusted_mode->crtc_htotal / 2;
4308 } else {
4309 vsyncshift = 0;
4310 }
4311
4312 if (INTEL_INFO(dev)->gen > 3)
4313 I915_WRITE(VSYNCSHIFT(pipe), vsyncshift);
4314
4315 I915_WRITE(HTOTAL(pipe),
4316 (adjusted_mode->crtc_hdisplay - 1) |
4317 ((adjusted_mode->crtc_htotal - 1) << 16));
4318 I915_WRITE(HBLANK(pipe),
4319 (adjusted_mode->crtc_hblank_start - 1) |
4320 ((adjusted_mode->crtc_hblank_end - 1) << 16));
4321 I915_WRITE(HSYNC(pipe),
4322 (adjusted_mode->crtc_hsync_start - 1) |
4323 ((adjusted_mode->crtc_hsync_end - 1) << 16));
4324
4325 I915_WRITE(VTOTAL(pipe),
4326 (adjusted_mode->crtc_vdisplay - 1) |
4327 ((adjusted_mode->crtc_vtotal - 1) << 16));
4328 I915_WRITE(VBLANK(pipe),
4329 (adjusted_mode->crtc_vblank_start - 1) |
4330 ((adjusted_mode->crtc_vblank_end - 1) << 16));
4331 I915_WRITE(VSYNC(pipe),
4332 (adjusted_mode->crtc_vsync_start - 1) |
4333 ((adjusted_mode->crtc_vsync_end - 1) << 16));
4334
4335 /* pipesrc controls the size that is scaled from, which should
4336 * always be the user's requested size.
4337 */
4338 I915_WRITE(PIPESRC(pipe),
4339 ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
4340}
4341
4293static int i9xx_crtc_mode_set(struct drm_crtc *crtc, 4342static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
4294 struct drm_display_mode *mode, 4343 struct drm_display_mode *mode,
4295 struct drm_display_mode *adjusted_mode, 4344 struct drm_display_mode *adjusted_mode,
@@ -4303,7 +4352,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
4303 int plane = intel_crtc->plane; 4352 int plane = intel_crtc->plane;
4304 int refclk, num_connectors = 0; 4353 int refclk, num_connectors = 0;
4305 intel_clock_t clock, reduced_clock; 4354 intel_clock_t clock, reduced_clock;
4306 u32 dspcntr, pipeconf, vsyncshift; 4355 u32 dspcntr, pipeconf;
4307 bool ok, has_reduced_clock = false, is_sdvo = false; 4356 bool ok, has_reduced_clock = false, is_sdvo = false;
4308 bool is_lvds = false, is_tv = false, is_dp = false; 4357 bool is_lvds = false, is_tv = false, is_dp = false;
4309 struct intel_encoder *encoder; 4358 struct intel_encoder *encoder;
@@ -4438,40 +4487,12 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
4438 4487
4439 pipeconf &= ~PIPECONF_INTERLACE_MASK; 4488 pipeconf &= ~PIPECONF_INTERLACE_MASK;
4440 if (!IS_GEN2(dev) && 4489 if (!IS_GEN2(dev) &&
4441 adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { 4490 adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
4442 pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; 4491 pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
4443 /* the chip adds 2 halflines automatically */ 4492 else
4444 adjusted_mode->crtc_vtotal -= 1;
4445 adjusted_mode->crtc_vblank_end -= 1;
4446 vsyncshift = adjusted_mode->crtc_hsync_start
4447 - adjusted_mode->crtc_htotal/2;
4448 } else {
4449 pipeconf |= PIPECONF_PROGRESSIVE; 4493 pipeconf |= PIPECONF_PROGRESSIVE;
4450 vsyncshift = 0;
4451 }
4452
4453 if (!IS_GEN3(dev))
4454 I915_WRITE(VSYNCSHIFT(pipe), vsyncshift);
4455 4494
4456 I915_WRITE(HTOTAL(pipe), 4495 intel_set_pipe_timings(intel_crtc, mode, adjusted_mode);
4457 (adjusted_mode->crtc_hdisplay - 1) |
4458 ((adjusted_mode->crtc_htotal - 1) << 16));
4459 I915_WRITE(HBLANK(pipe),
4460 (adjusted_mode->crtc_hblank_start - 1) |
4461 ((adjusted_mode->crtc_hblank_end - 1) << 16));
4462 I915_WRITE(HSYNC(pipe),
4463 (adjusted_mode->crtc_hsync_start - 1) |
4464 ((adjusted_mode->crtc_hsync_end - 1) << 16));
4465
4466 I915_WRITE(VTOTAL(pipe),
4467 (adjusted_mode->crtc_vdisplay - 1) |
4468 ((adjusted_mode->crtc_vtotal - 1) << 16));
4469 I915_WRITE(VBLANK(pipe),
4470 (adjusted_mode->crtc_vblank_start - 1) |
4471 ((adjusted_mode->crtc_vblank_end - 1) << 16));
4472 I915_WRITE(VSYNC(pipe),
4473 (adjusted_mode->crtc_vsync_start - 1) |
4474 ((adjusted_mode->crtc_vsync_end - 1) << 16));
4475 4496
4476 /* pipesrc and dspsize control the size that is scaled from, 4497 /* pipesrc and dspsize control the size that is scaled from,
4477 * which should always be the user's requested size. 4498 * which should always be the user's requested size.
@@ -4480,8 +4501,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
4480 ((mode->vdisplay - 1) << 16) | 4501 ((mode->vdisplay - 1) << 16) |
4481 (mode->hdisplay - 1)); 4502 (mode->hdisplay - 1));
4482 I915_WRITE(DSPPOS(plane), 0); 4503 I915_WRITE(DSPPOS(plane), 0);
4483 I915_WRITE(PIPESRC(pipe),
4484 ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
4485 4504
4486 I915_WRITE(PIPECONF(pipe), pipeconf); 4505 I915_WRITE(PIPECONF(pipe), pipeconf);
4487 POSTING_READ(PIPECONF(pipe)); 4506 POSTING_READ(PIPECONF(pipe));
@@ -5087,42 +5106,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
5087 } 5106 }
5088 } 5107 }
5089 5108
5090 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { 5109 intel_set_pipe_timings(intel_crtc, mode, adjusted_mode);
5091 /* the chip adds 2 halflines automatically */
5092 adjusted_mode->crtc_vtotal -= 1;
5093 adjusted_mode->crtc_vblank_end -= 1;
5094 I915_WRITE(VSYNCSHIFT(pipe),
5095 adjusted_mode->crtc_hsync_start
5096 - adjusted_mode->crtc_htotal/2);
5097 } else {
5098 I915_WRITE(VSYNCSHIFT(pipe), 0);
5099 }
5100
5101 I915_WRITE(HTOTAL(pipe),
5102 (adjusted_mode->crtc_hdisplay - 1) |
5103 ((adjusted_mode->crtc_htotal - 1) << 16));
5104 I915_WRITE(HBLANK(pipe),
5105 (adjusted_mode->crtc_hblank_start - 1) |
5106 ((adjusted_mode->crtc_hblank_end - 1) << 16));
5107 I915_WRITE(HSYNC(pipe),
5108 (adjusted_mode->crtc_hsync_start - 1) |
5109 ((adjusted_mode->crtc_hsync_end - 1) << 16));
5110
5111 I915_WRITE(VTOTAL(pipe),
5112 (adjusted_mode->crtc_vdisplay - 1) |
5113 ((adjusted_mode->crtc_vtotal - 1) << 16));
5114 I915_WRITE(VBLANK(pipe),
5115 (adjusted_mode->crtc_vblank_start - 1) |
5116 ((adjusted_mode->crtc_vblank_end - 1) << 16));
5117 I915_WRITE(VSYNC(pipe),
5118 (adjusted_mode->crtc_vsync_start - 1) |
5119 ((adjusted_mode->crtc_vsync_end - 1) << 16));
5120
5121 /* pipesrc controls the size that is scaled from, which should
5122 * always be the user's requested size.
5123 */
5124 I915_WRITE(PIPESRC(pipe),
5125 ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
5126 5110
5127 ironlake_set_m_n(crtc, mode, adjusted_mode); 5111 ironlake_set_m_n(crtc, mode, adjusted_mode);
5128 5112