On Thu, Oct 20, 2011 at 03:15:09PM -0200, Eugeni Dodonov wrote: > This is mostly similar to Ironlake, with some register changes and > additional tricks. > > Jesse mentioned that it would make more sense to move those bits into > ivb-specific functions instead of making this work within ironlake ones, > so I added the corresponding functions and setup their pointers > accordingly. > > v2: Now the correct patch. > > Signed-off-by: Eugeni Dodonov <eugeni.dodonov at intel.com> Anyone got an opinion on whether this is worth it power-consumption wise? fbc has been a bit of a disaster and we have it disabled almost everywhere ... -Daniel > --- > drivers/gpu/drm/i915/i915_drv.c | 2 +- > drivers/gpu/drm/i915/i915_reg.h | 14 ++++++ > drivers/gpu/drm/i915/intel_display.c | 83 ++++++++++++++++++++++++++++++++- > 3 files changed, 95 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index f07e425..a4300b7 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -233,7 +233,7 @@ static const struct intel_device_info intel_ivybridge_d_info = { > static const struct intel_device_info intel_ivybridge_m_info = { > .is_ivybridge = 1, .gen = 7, .is_mobile = 1, > .need_gfx_hws = 1, .has_hotplug = 1, > - .has_fbc = 0, /* FBC is not enabled on Ivybridge mobile yet */ > + .has_fbc = 1, /* Attempt at enabling FBC on IvyBridge mobile */ > .has_bsd_ring = 1, > .has_blt_ring = 1, > }; > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 542453f..4d1ce26 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -627,6 +627,7 @@ > #define ILK_DISPLAY_CHICKEN1 0x42000 > #define ILK_FBCQ_DIS (1<<22) > #define ILK_PABSTRETCH_DIS (1<<21) > +#define IVB_DPR_VS_FBCQ_DIS (1<<22) > > > /* > @@ -638,6 +639,19 @@ > #define SNB_CPU_FENCE_ENABLE (1<<29) > #define DPFC_CPU_FENCE_OFFSET 0x100104 > > +/* > + * Framebuffer compression for IVB > + * > + * Mostly similar to ILK with some changes > + */ > + > +#define IVB_RESERVED (0x0FFFFF00) > + > +/* Controlled via ILK_DPFC_CONTROL */ > +#define IVB_FBC_CTL_PLANEA (0<<29) > +#define IVB_FBC_CTL_PLANEB (1<<29) > +#define IVB_FBC_CTL_PLANEC (2<<29) > +#define IVB_FBC_CPU_FENCE_ENABLE (1<<28) > > /* > * GPIO regs > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 04411ad..de77249 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -1657,6 +1657,77 @@ static bool ironlake_fbc_enabled(struct drm_device *dev) > return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; > } > > +static void ivb_enable_fbc(struct drm_crtc *crtc, unsigned long interval) > +{ > + struct drm_device *dev = crtc->dev; > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct drm_framebuffer *fb = crtc->fb; > + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); > + struct drm_i915_gem_object *obj = intel_fb->obj; > + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); > + unsigned long stall_watermark = 200; > + u32 dpfc_ctl; > + > + dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); > + dpfc_ctl &= IVB_RESERVED; > + /* Workarounds */ > + I915_WRITE(ILK_DISPLAY_CHICKEN1, > + I915_READ(ILK_DISPLAY_CHICKEN1) | > + IVB_DPR_VS_FBCQ_DIS); > + I915_WRITE(ILK_DSPCLK_GATE, > + I915_READ(ILK_DSPCLK_GATE) | > + ILK_DPFC_DIS2 | > + ILK_CLK_FBC); > + /* IVL has 3 pipes */ > + switch (intel_crtc->plane) { > + case 0: > + dpfc_ctl |= IVB_FBC_CTL_PLANEA; > + break; > + case 1: > + dpfc_ctl |= IVB_FBC_CTL_PLANEB; > + break; > + case 2: > + dpfc_ctl |= IVB_FBC_CTL_PLANEC; > + break; > + } > + /* fence enablement */ > + dpfc_ctl |= (IVB_FBC_CPU_FENCE_ENABLE | obj->fence_reg); > + dpfc_ctl |= DPFC_CTL_LIMIT_1X; > + I915_WRITE(ILK_DPFC_CHICKEN, DPFC_HT_MODIFY); > + > + I915_WRITE(ILK_DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | > + (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | > + (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); > + I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); > + I915_WRITE(ILK_FBC_RT_BASE, obj->gtt_offset | ILK_FBC_RT_VALID); > + /* enable it... */ > + I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); > + > + DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); > +} > + > +static void ivb_disable_fbc(struct drm_device *dev) > +{ > + struct drm_i915_private *dev_priv = dev->dev_private; > + u32 dpfc_ctl; > + > + /* Disable compression */ > + dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); > + if (dpfc_ctl & DPFC_CTL_EN) { > + dpfc_ctl &= ~DPFC_CTL_EN; > + I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); > + > + DRM_DEBUG_KMS("disabled FBC\n"); > + } > +} > + > +static bool ivb_fbc_enabled(struct drm_device *dev) > +{ > + struct drm_i915_private *dev_priv = dev->dev_private; > + > + return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; > +} > + > bool intel_fbc_enabled(struct drm_device *dev) > { > struct drm_i915_private *dev_priv = dev->dev_private; > @@ -8138,9 +8209,15 @@ static void intel_init_display(struct drm_device *dev) > > if (I915_HAS_FBC(dev)) { > if (HAS_PCH_SPLIT(dev)) { > - dev_priv->display.fbc_enabled = ironlake_fbc_enabled; > - dev_priv->display.enable_fbc = ironlake_enable_fbc; > - dev_priv->display.disable_fbc = ironlake_disable_fbc; > + if (IS_GEN7(dev)) { > + dev_priv->display.fbc_enabled = ivb_fbc_enabled; > + dev_priv->display.enable_fbc = ivb_enable_fbc; > + dev_priv->display.disable_fbc = ivb_disable_fbc; > + } else { > + dev_priv->display.fbc_enabled = ironlake_fbc_enabled; > + dev_priv->display.enable_fbc = ironlake_enable_fbc; > + dev_priv->display.disable_fbc = ironlake_disable_fbc; > + } > } else if (IS_GM45(dev)) { > dev_priv->display.fbc_enabled = g4x_fbc_enabled; > dev_priv->display.enable_fbc = g4x_enable_fbc; > -- > 1.7.6.4 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Mail: daniel at ffwll.ch Mobile: +41 (0)79 365 57 48