<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>