<div dir="ltr">Jani, please ignore the 4th patch on this series and merge the 3 I've reviewed and tested already.<div><br></div><div>They are essential to allow FBC work on BDW without changing bios configuration and allow PC7 residency.</div>
<div><br></div><div>Thanks,</div><div>Rodrigo.</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jun 30, 2014 at 10:41 AM, Rodrigo Vivi <span dir="ltr"><<a href="mailto:rodrigo.vivi@intel.com" target="_blank">rodrigo.vivi@intel.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Ben Widawsky <<a href="mailto:benjamin.widawsky@intel.com">benjamin.widawsky@intel.com</a>><br>
<div class=""><br>
The GEN FBC unit provides the ability to set a low pass on frames it<br>
attempts to compress. If a frame is less than a certain amount<br>
compressibility (2:1, 4:1) it will not bother. This allows the driver to<br>
reduce the size it requests out of stolen memory.<br>
<br>
Unluckily, a few months ago, Ville actually began using this feature for<br>
framebuffers that are 16bpp (not sure why not 8bpp). In those cases, we<br>
are already using this mechanism for a different purpose, and so we can<br>
only achieve one further level of compression (2:1 -> 4:1)<br>
<br>
FBC GEN1, ie. pre-G45 is ignored.<br>
<br>
The cleverness of the patch is Art's. The bugs are mine.<br>
<br>
</div>v2: Update message and including missing threshold case 3 (Spotted by Arthur).<br>
<br>
Reviewedby: Rodrigo Vivi <<a href="mailto:rodrigo.vivi@intel.com">rodrigo.vivi@intel.com</a>><br>
<div class="">Cc: Art Runyan <<a href="mailto:arthur.j.runyan@intel.com">arthur.j.runyan@intel.com</a>><br>
Signed-off-by: Ben Widawsky <<a href="mailto:ben@bwidawsk.net">ben@bwidawsk.net</a>><br>
</div>Signed-off-by: Rodrigo Vivi <<a href="mailto:rodrigo.vivi@intel.com">rodrigo.vivi@intel.com</a>><br>
<div class="">---<br>
 drivers/gpu/drm/i915/i915_drv.h        |  3 +-<br>
 drivers/gpu/drm/i915/i915_gem_stolen.c | 54 +++++++++++++++++++++++++---------<br>
</div> drivers/gpu/drm/i915/intel_pm.c        | 30 +++++++++++++++++--<br>
 3 files changed, 69 insertions(+), 18 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h<br>
index 5b7aed2..9953ea8 100644<br>
--- a/drivers/gpu/drm/i915/i915_drv.h<br>
+++ b/drivers/gpu/drm/i915/i915_drv.h<br>
@@ -600,6 +600,7 @@ struct intel_context {<br>
<div class=""><br>
 struct i915_fbc {<br>
        unsigned long size;<br>
+       unsigned threshold;<br>
        unsigned int fb_id;<br>
        enum plane plane;<br>
        int y;<br>
</div>@@ -2489,7 +2490,7 @@ static inline void i915_gem_chipset_flush(struct drm_device *dev)<br>
<div class=""><br>
 /* i915_gem_stolen.c */<br>
 int i915_gem_init_stolen(struct drm_device *dev);<br>
-int i915_gem_stolen_setup_compression(struct drm_device *dev, int size);<br>
+int i915_gem_stolen_setup_compression(struct drm_device *dev, int size, int fb_cpp);<br>
 void i915_gem_stolen_cleanup_compression(struct drm_device *dev);<br>
 void i915_gem_cleanup_stolen(struct drm_device *dev);<br>
 struct drm_i915_gem_object *<br>
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c<br>
</div>index a86b331..b695d18 100644<br>
<div><div class="h5">--- a/drivers/gpu/drm/i915/i915_gem_stolen.c<br>
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c<br>
@@ -105,35 +105,61 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev)<br>
<br>
 static int find_compression_threshold(struct drm_device *dev,<br>
                                      struct drm_mm_node *node,<br>
-                                     int size)<br>
+                                     int size,<br>
+                                     int fb_cpp)<br>
 {<br>
        struct drm_i915_private *dev_priv = dev->dev_private;<br>
-       const int compression_threshold = 1;<br>
+       int compression_threshold = 1;<br>
        int ret;<br>
<br>
-       /* Try to over-allocate to reduce reallocations and fragmentation */<br>
+       /* HACK: This code depends on what we will do in *_enable_fbc. If that<br>
+        * code changes, this code needs to change as well.<br>
+        *<br>
+        * The enable_fbc code will attempt to use one of our 2 compression<br>
+        * thresholds, therefore, in that case, we only have 1 resort.<br>
+        */<br>
+<br>
+       /* Try to over-allocate to reduce reallocations and fragmentation. */<br>
        ret = drm_mm_insert_node(&dev_priv->mm.stolen, node,<br>
                                 size <<= 1, 4096, DRM_MM_SEARCH_DEFAULT);<br>
-       if (ret)<br>
-               ret = drm_mm_insert_node(&dev_priv->mm.stolen, node,<br>
-                                        size >>= 1, 4096,<br>
-                                        DRM_MM_SEARCH_DEFAULT);<br>
-       if (ret)<br>
+       if (ret == 0)<br>
+               return compression_threshold;<br>
+<br>
+again:<br>
+       /* HW's ability to limit the CFB is 1:4 */<br>
+       if (compression_threshold > 4 ||<br>
+           (fb_cpp == 2 && compression_threshold == 2))<br>
                return 0;<br>
-       else<br>
+<br>
+       ret = drm_mm_insert_node(&dev_priv->mm.stolen, node,<br>
+                                size >>= 1, 4096,<br>
+                                DRM_MM_SEARCH_DEFAULT);<br>
+       if (ret && INTEL_INFO(dev)->gen <= 4) {<br>
+               return 0;<br>
+       } else if (ret) {<br>
+               compression_threshold <<= 1;<br>
+               goto again;<br>
+       } else {<br>
                return compression_threshold;<br>
+       }<br>
 }<br>
<br>
-static int i915_setup_compression(struct drm_device *dev, int size)<br>
+static int i915_setup_compression(struct drm_device *dev, int size, int fb_cpp)<br>
 {<br>
        struct drm_i915_private *dev_priv = dev->dev_private;<br>
        struct drm_mm_node *uninitialized_var(compressed_llb);<br>
        int ret;<br>
<br>
        ret = find_compression_threshold(dev, &dev_priv->fbc.compressed_fb,<br>
-                                        size);<br>
+                                        size, fb_cpp);<br>
        if (!ret)<br>
                goto err_llb;<br>
+       else if (ret > 1) {<br>
</div></div>+               DRM_INFO("Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n");<br>
<div class="">+<br>
+       }<br>
+<br>
+       dev_priv->fbc.threshold = ret;<br>
<br>
        if (HAS_PCH_SPLIT(dev))<br>
                I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->fbc.compressed_fb.start);<br>
@@ -157,7 +183,7 @@ static int i915_setup_compression(struct drm_device *dev, int size)<br>
                           dev_priv->mm.stolen_base + compressed_llb->start);<br>
        }<br>
<br>
-       dev_priv->fbc.size = size;<br>
+       dev_priv->fbc.size = size / dev_priv->fbc.threshold;<br>
<br>
        DRM_DEBUG_KMS("reserved %d bytes of contiguous stolen space for FBC\n",<br>
                      size);<br>
@@ -172,7 +198,7 @@ err_llb:<br>
        return -ENOSPC;<br>
 }<br>
<br>
-int i915_gem_stolen_setup_compression(struct drm_device *dev, int size)<br>
+int i915_gem_stolen_setup_compression(struct drm_device *dev, int size, int fb_cpp)<br>
 {<br>
        struct drm_i915_private *dev_priv = dev->dev_private;<br>
<br>
@@ -185,7 +211,7 @@ int i915_gem_stolen_setup_compression(struct drm_device *dev, int size)<br>
        /* Release any current block */<br>
        i915_gem_stolen_cleanup_compression(dev);<br>
<br>
-       return i915_setup_compression(dev, size);<br>
+       return i915_setup_compression(dev, size, fb_cpp);<br>
 }<br>
<br>
 void i915_gem_stolen_cleanup_compression(struct drm_device *dev)<br>
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c<br>
</div>index a90fdbd..4fcb2f7 100644<br>
--- a/drivers/gpu/drm/i915/intel_pm.c<br>
+++ b/drivers/gpu/drm/i915/intel_pm.c<br>
@@ -229,9 +229,20 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc)<br>
<div class=""><br>
        dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane);<br>
        if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)<br>
+               dev_priv->fbc.threshold++;<br>
+<br>
+       switch (dev_priv->fbc.threshold) {<br>
+       case 4:<br>
+       case 3:<br>
+               dpfc_ctl |= DPFC_CTL_LIMIT_4X;<br>
+               break;<br>
+       case 2:<br>
                dpfc_ctl |= DPFC_CTL_LIMIT_2X;<br>
-       else<br>
+               break;<br>
+       case 1:<br>
                dpfc_ctl |= DPFC_CTL_LIMIT_1X;<br>
+               break;<br>
+       }<br>
</div><div class="">        dpfc_ctl |= DPFC_CTL_FENCE_EN;<br>
        if (IS_GEN5(dev))<br>
                dpfc_ctl |= obj->fence_reg;<br>
</div>@@ -285,9 +296,21 @@ static void gen7_enable_fbc(struct drm_crtc *crtc)<br>
<br>
        dpfc_ctl = IVB_DPFC_CTL_PLANE(intel_crtc->plane);<br>
<div class="">        if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)<br>
+               dev_priv->fbc.threshold++;<br>
+<br>
+       switch (dev_priv->fbc.threshold) {<br>
+       case 4:<br>
+       case 3:<br>
+               dpfc_ctl |= DPFC_CTL_LIMIT_4X;<br>
+               break;<br>
+       case 2:<br>
                dpfc_ctl |= DPFC_CTL_LIMIT_2X;<br>
-       else<br>
+               break;<br>
+       case 1:<br>
                dpfc_ctl |= DPFC_CTL_LIMIT_1X;<br>
+               break;<br>
+       }<br>
</div><div class="">+<br>
        dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN;<br>
<br>
        I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);<br>
</div>@@ -566,7 +589,8 @@ void intel_update_fbc(struct drm_device *dev)<br>
<div class="">        if (in_dbg_master())<br>
                goto out_disable;<br>
<br>
-       if (i915_gem_stolen_setup_compression(dev, intel_fb->obj->base.size)) {<br>
+       if (i915_gem_stolen_setup_compression(dev, intel_fb->obj->base.size,<br>
+                                             drm_format_plane_cpp(fb->pixel_format, 0))) {<br>
                if (set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL))<br>
                        DRM_DEBUG_KMS("framebuffer too large, disabling compression\n");<br>
                goto out_disable;<br>
--<br>
</div>1.9.1<br>
<div class="HOEnZb"><div class="h5"><br>
_______________________________________________<br>
Intel-gfx mailing list<br>
<a href="mailto:Intel-gfx@lists.freedesktop.org">Intel-gfx@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/intel-gfx" target="_blank">http://lists.freedesktop.org/mailman/listinfo/intel-gfx</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div>Rodrigo Vivi</div><div>Blog: <a href="http://blog.vivi.eng.br" target="_blank">http://blog.vivi.eng.br</a></div><div> </div>
</div>