After writing to the plane control reg we need to write to the surface reg to trigger the double buffered register latch.
v2: write DSPADDR too to cover pre-965 chipsets v3: use flush_display_plane instead, that's what it's for Signed-off-by: Jesse Barnes <[email protected]> --- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_reg.h | 7 ++ drivers/gpu/drm/i915/intel_display.c | 144 ++++++++++++++++++++++++---------- 4 files changed, 111 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ce045a8..60e4b9e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -62,7 +62,7 @@ module_param_named(semaphores, i915_semaphores, int, 0600); MODULE_PARM_DESC(semaphores, "Use semaphores for inter-ring sync (default: false)"); -unsigned int i915_enable_rc6 __read_mostly = 0; +unsigned int i915_enable_rc6 __read_mostly = 1; module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); MODULE_PARM_DESC(i915_enable_rc6, "Enable power-saving render C-state 6 (default: true)"); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 78cdd15..4f24e72 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -337,6 +337,8 @@ typedef struct drm_i915_private { int cfb_y; struct intel_fbc_work *fbc_work; + int planes_enabled; + struct intel_opregion opregion; /* overlay */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7377ae4..ae28549 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3081,6 +3081,13 @@ #define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2) #define TRANS_AUTOTRAIN_GEN_STALL_DIS (1<<31) +#define SOUTH_CHICKEN1 0xc2000 +#define FDIA_PHASE_SYNC_OVR (1<<19) +#define FDIA_PHASE_SYNC_EN (1<<18) +#define FDIB_PHASE_SYNC_OVR (1<<17) +#define FDIB_PHASE_SYNC_EN (1<<16) +#define FDIC_PHASE_SYNC_OVR (1<<15) +#define FDIC_PHASE_SYNC_EN (1<<14) #define SOUTH_CHICKEN2 0xc2004 #define DPLS_EDP_PPS_FIX_DIS (1<<0) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 32ffde2..8bf6c6f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1309,8 +1309,8 @@ static void intel_enable_plane(struct drm_i915_private *dev_priv, static void intel_flush_display_plane(struct drm_i915_private *dev_priv, enum plane plane) { - u32 reg = DSPADDR(plane); - I915_WRITE(reg, I915_READ(reg)); + I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane))); + I915_WRITE(DSPSURF(plane), I915_READ(DSPSURF(plane))); } /** @@ -1370,7 +1370,7 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, val = I915_READ(reg); if (ADPA_PIPE_ENABLED(val, pipe)) I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); - +#if 0 reg = PCH_LVDS; val = I915_READ(reg); if (LVDS_PIPE_ENABLED(val, pipe)) { @@ -1378,7 +1378,7 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, POSTING_READ(reg); udelay(100); } - +#endif disable_pch_hdmi(dev_priv, pipe, HDMIB); disable_pch_hdmi(dev_priv, pipe, HDMIC); disable_pch_hdmi(dev_priv, pipe, HDMID); @@ -2295,6 +2295,23 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR); I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR | FDI_RX_PHASE_SYNC_POINTER_EN); + } else if (HAS_PCH_CPT(dev)) { + u32 flags; + switch (pipe) { + case 0: + flags = FDIA_PHASE_SYNC_OVR | FDIA_PHASE_SYNC_EN; + break; + case 2: + flags = FDIA_PHASE_SYNC_OVR | FDIA_PHASE_SYNC_EN; + break; + case 3: + flags = FDIA_PHASE_SYNC_OVR | FDIA_PHASE_SYNC_EN; + break; + default: + break; + } + I915_WRITE(SOUTH_CHICKEN1, flags); /* once to unlock... */ + I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to enable */ } reg = FDI_RX_IIR(pipe); @@ -2652,6 +2669,23 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc) I915_WRITE(FDI_RX_CHICKEN(pipe), I915_READ(FDI_RX_CHICKEN(pipe) & ~FDI_RX_PHASE_SYNC_POINTER_EN)); + } else if (HAS_PCH_CPT(dev)) { + u32 flags; + switch (pipe) { + case 0: + flags = FDIA_PHASE_SYNC_OVR; + break; + case 2: + flags = FDIA_PHASE_SYNC_OVR; + break; + case 3: + flags = FDIA_PHASE_SYNC_OVR; + break; + default: + break; + } + I915_WRITE(SOUTH_CHICKEN1, flags); /* once to unlock... */ + I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to enable */ } /* still set train pattern 1 */ @@ -2919,6 +2953,10 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) /* disable TRANS_DP_CTL */ reg = TRANS_DP_CTL(pipe); temp = I915_READ(reg); + temp &= ~TRANS_DP_PORT_SEL_MASK; + temp |= TRANS_DP_PORT_SEL_NONE; + I915_WRITE(reg, temp); + intel_wait_for_vblank(dev, pipe); temp &= ~(TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK); temp |= TRANS_DP_PORT_SEL_NONE; I915_WRITE(reg, temp); @@ -4328,51 +4366,20 @@ static void ironlake_update_wm(struct drm_device *dev) */ } -static void sandybridge_update_wm(struct drm_device *dev) +static void snb_disable_lpwm(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ - int fbc_wm, plane_wm, cursor_wm; - unsigned int enabled; - enabled = 0; - if (g4x_compute_wm0(dev, 0, - &sandybridge_display_wm_info, latency, - &sandybridge_cursor_wm_info, latency, - &plane_wm, &cursor_wm)) { - I915_WRITE(WM0_PIPEA_ILK, - (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); - DRM_DEBUG_KMS("FIFO watermarks For pipe A -" - " plane %d, " "cursor: %d\n", - plane_wm, cursor_wm); - enabled |= 1; - } - - if (g4x_compute_wm0(dev, 1, - &sandybridge_display_wm_info, latency, - &sandybridge_cursor_wm_info, latency, - &plane_wm, &cursor_wm)) { - I915_WRITE(WM0_PIPEB_ILK, - (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); - DRM_DEBUG_KMS("FIFO watermarks For pipe B -" - " plane %d, cursor: %d\n", - plane_wm, cursor_wm); - enabled |= 2; - } - - /* - * Calculate and update the self-refresh watermark only when one - * display plane is used. - * - * SNB support 3 levels of watermark. - * - * WM1/WM2/WM2 watermarks have to be enabled in the ascending order, - * and disabled in the descending order - * - */ I915_WRITE(WM3_LP_ILK, 0); I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); +} + +void snb_enable_lpwm(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int fbc_wm, plane_wm, cursor_wm; + int enabled = dev_priv->planes_enabled; if (!single_plane_enabled(enabled)) return; @@ -4424,6 +4431,55 @@ static void sandybridge_update_wm(struct drm_device *dev) cursor_wm); } +static void sandybridge_update_wm(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ + int plane_wm, cursor_wm; + unsigned int enabled; + + enabled = 0; + if (g4x_compute_wm0(dev, 0, + &sandybridge_display_wm_info, latency, + &sandybridge_cursor_wm_info, latency, + &plane_wm, &cursor_wm)) { + I915_WRITE(WM0_PIPEA_ILK, + (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); + DRM_DEBUG_KMS("FIFO watermarks For pipe A -" + " plane %d, " "cursor: %d\n", + plane_wm, cursor_wm); + enabled |= 1; + } + + if (g4x_compute_wm0(dev, 1, + &sandybridge_display_wm_info, latency, + &sandybridge_cursor_wm_info, latency, + &plane_wm, &cursor_wm)) { + I915_WRITE(WM0_PIPEB_ILK, + (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); + DRM_DEBUG_KMS("FIFO watermarks For pipe B -" + " plane %d, cursor: %d\n", + plane_wm, cursor_wm); + enabled |= 2; + } + + /* + * Calculate and update the self-refresh watermark only when one + * display plane is used. + * + * SNB support 3 levels of watermark. + * + * WM1/WM2/WM2 watermarks have to be enabled in the ascending order, + * and disabled in the descending order + * + */ + snb_disable_lpwm(dev); + + dev_priv->planes_enabled = enabled; + + snb_enable_lpwm(dev); +} + /** * intel_update_watermarks - update FIFO watermark values based on current modes * @@ -5515,6 +5571,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, drm_vblank_post_modeset(dev, pipe); + intel_crtc->dpms_mode = DRM_MODE_DPMS_ON; + return ret; } -- 1.7.4.1 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
