diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3369f829f46f..7eabdf056afb 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1384,6 +1384,7 @@ #define _VSYNC_A 0x60014 #define _PIPEASRC 0x6001c #define _BCLRPAT_A 0x60020 +#define _VSYNCSHIFT_A 0x60028 /* Pipe B timing regs */ #define _HTOTAL_B 0x61000 @@ -1394,6 +1395,8 @@ #define _VSYNC_B 0x61014 #define _PIPEBSRC 0x6101c #define _BCLRPAT_B 0x61020 +#define _VSYNCSHIFT_B 0x61028 + #define HTOTAL(pipe) _PIPE(pipe, _HTOTAL_A, _HTOTAL_B) #define HBLANK(pipe) _PIPE(pipe, _HBLANK_A, _HBLANK_B) @@ -1402,6 +1405,7 @@ #define VBLANK(pipe) _PIPE(pipe, _VBLANK_A, _VBLANK_B) #define VSYNC(pipe) _PIPE(pipe, _VSYNC_A, _VSYNC_B) #define BCLRPAT(pipe) _PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B) +#define VSYNCSHIFT(pipe) _PIPE(pipe, _VSYNCSHIFT_A, _VSYNCSHIFT_B) /* VGA port control */ #define ADPA 0x61100 @@ -3284,6 +3288,7 @@ #define _TRANS_VSYNC_A 0xe0014 #define TRANS_VSYNC_END_SHIFT 16 #define TRANS_VSYNC_START_SHIFT 0 +#define _TRANS_VSYNCSHIFT_A 0xe0028 #define _TRANSA_DATA_M1 0xe0030 #define _TRANSA_DATA_N1 0xe0034 @@ -3314,6 +3319,7 @@ #define _TRANS_VTOTAL_B 0xe100c #define _TRANS_VBLANK_B 0xe1010 #define _TRANS_VSYNC_B 0xe1014 +#define _TRANS_VSYNCSHIFT_B 0xe1028 #define TRANS_HTOTAL(pipe) _PIPE(pipe, _TRANS_HTOTAL_A, _TRANS_HTOTAL_B) #define TRANS_HBLANK(pipe) _PIPE(pipe, _TRANS_HBLANK_A, _TRANS_HBLANK_B) @@ -3321,6 +3327,8 @@ #define TRANS_VTOTAL(pipe) _PIPE(pipe, _TRANS_VTOTAL_A, _TRANS_VTOTAL_B) #define TRANS_VBLANK(pipe) _PIPE(pipe, _TRANS_VBLANK_A, _TRANS_VBLANK_B) #define TRANS_VSYNC(pipe) _PIPE(pipe, _TRANS_VSYNC_A, _TRANS_VSYNC_B) +#define TRANS_VSYNCSHIFT(pipe) _PIPE(pipe, _TRANS_VSYNCSHIFT_A, \ + _TRANS_VSYNCSHIFT_B) #define _TRANSB_DATA_M1 0xe1030 #define _TRANSB_DATA_N1 0xe1034 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1fde35d53608..34c63459c484 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2973,6 +2973,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) I915_WRITE(TRANS_VTOTAL(pipe), I915_READ(VTOTAL(pipe))); I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe))); I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); + I915_WRITE(TRANS_VSYNCSHIFT(pipe), I915_READ(VSYNCSHIFT(pipe))); intel_fdi_normal_train(crtc); @@ -5103,7 +5104,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, int plane = intel_crtc->plane; int refclk, num_connectors = 0; intel_clock_t clock, reduced_clock; - u32 dpll, dspcntr, pipeconf; + u32 dpll, dspcntr, pipeconf, vsyncshift; bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; struct drm_mode_config *mode_config = &dev->mode_config; @@ -5391,8 +5392,15 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, /* the chip adds 2 halflines automatically */ adjusted_mode->crtc_vtotal -= 1; adjusted_mode->crtc_vblank_end -= 1; - } else + vsyncshift = adjusted_mode->crtc_hsync_start + - adjusted_mode->crtc_htotal/2; + } else { pipeconf |= PIPECONF_PROGRESSIVE; + vsyncshift = 0; + } + + if (!IS_GEN3(dev)) + I915_WRITE(VSYNCSHIFT(pipe), vsyncshift); I915_WRITE(HTOTAL(pipe), (adjusted_mode->crtc_hdisplay - 1) | @@ -5980,8 +5988,13 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, /* the chip adds 2 halflines automatically */ adjusted_mode->crtc_vtotal -= 1; adjusted_mode->crtc_vblank_end -= 1; - } else + I915_WRITE(VSYNCSHIFT(pipe), + adjusted_mode->crtc_hsync_start + - adjusted_mode->crtc_htotal/2); + } else { pipeconf |= PIPECONF_PROGRESSIVE; + I915_WRITE(VSYNCSHIFT(pipe), 0); + } I915_WRITE(HTOTAL(pipe), (adjusted_mode->crtc_hdisplay - 1) |