12c9916cdSFrançois Tigeot /* 22c9916cdSFrançois Tigeot * Copyright © 2014 Intel Corporation 32c9916cdSFrançois Tigeot * 42c9916cdSFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 52c9916cdSFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 62c9916cdSFrançois Tigeot * to deal in the Software without restriction, including without limitation 72c9916cdSFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 82c9916cdSFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 92c9916cdSFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 102c9916cdSFrançois Tigeot * 112c9916cdSFrançois Tigeot * The above copyright notice and this permission notice (including the next 122c9916cdSFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the 132c9916cdSFrançois Tigeot * Software. 142c9916cdSFrançois Tigeot * 152c9916cdSFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 162c9916cdSFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 172c9916cdSFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 182c9916cdSFrançois Tigeot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 192c9916cdSFrançois Tigeot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 202c9916cdSFrançois Tigeot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 212c9916cdSFrançois Tigeot * DEALINGS IN THE SOFTWARE. 222c9916cdSFrançois Tigeot */ 232c9916cdSFrançois Tigeot 242c9916cdSFrançois Tigeot /** 252c9916cdSFrançois Tigeot * DOC: Frame Buffer Compression (FBC) 262c9916cdSFrançois Tigeot * 272c9916cdSFrançois Tigeot * FBC tries to save memory bandwidth (and so power consumption) by 282c9916cdSFrançois Tigeot * compressing the amount of memory used by the display. It is total 292c9916cdSFrançois Tigeot * transparent to user space and completely handled in the kernel. 302c9916cdSFrançois Tigeot * 312c9916cdSFrançois Tigeot * The benefits of FBC are mostly visible with solid backgrounds and 322c9916cdSFrançois Tigeot * variation-less patterns. It comes from keeping the memory footprint small 332c9916cdSFrançois Tigeot * and having fewer memory pages opened and accessed for refreshing the display. 342c9916cdSFrançois Tigeot * 352c9916cdSFrançois Tigeot * i915 is responsible to reserve stolen memory for FBC and configure its 362c9916cdSFrançois Tigeot * offset on proper registers. The hardware takes care of all 372c9916cdSFrançois Tigeot * compress/decompress. However there are many known cases where we have to 382c9916cdSFrançois Tigeot * forcibly disable it to allow proper screen updates. 392c9916cdSFrançois Tigeot */ 402c9916cdSFrançois Tigeot 412c9916cdSFrançois Tigeot #include "intel_drv.h" 422c9916cdSFrançois Tigeot #include "i915_drv.h" 432c9916cdSFrançois Tigeot 44352ff8bdSFrançois Tigeot static inline bool fbc_supported(struct drm_i915_private *dev_priv) 45352ff8bdSFrançois Tigeot { 46c0e85e96SFrançois Tigeot return HAS_FBC(dev_priv); 47aee94f86SFrançois Tigeot } 48aee94f86SFrançois Tigeot 49aee94f86SFrançois Tigeot static inline bool fbc_on_pipe_a_only(struct drm_i915_private *dev_priv) 50aee94f86SFrançois Tigeot { 51aee94f86SFrançois Tigeot return IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8; 52aee94f86SFrançois Tigeot } 53aee94f86SFrançois Tigeot 54aee94f86SFrançois Tigeot static inline bool fbc_on_plane_a_only(struct drm_i915_private *dev_priv) 55aee94f86SFrançois Tigeot { 56aee94f86SFrançois Tigeot return INTEL_INFO(dev_priv)->gen < 4; 57352ff8bdSFrançois Tigeot } 58352ff8bdSFrançois Tigeot 59c0e85e96SFrançois Tigeot static inline bool no_fbc_on_multiple_pipes(struct drm_i915_private *dev_priv) 60c0e85e96SFrançois Tigeot { 61c0e85e96SFrançois Tigeot return INTEL_INFO(dev_priv)->gen <= 3; 62c0e85e96SFrançois Tigeot } 63c0e85e96SFrançois Tigeot 64352ff8bdSFrançois Tigeot /* 65352ff8bdSFrançois Tigeot * In some platforms where the CRTC's x:0/y:0 coordinates doesn't match the 66352ff8bdSFrançois Tigeot * frontbuffer's x:0/y:0 coordinates we lie to the hardware about the plane's 67352ff8bdSFrançois Tigeot * origin so the x and y offsets can actually fit the registers. As a 68352ff8bdSFrançois Tigeot * consequence, the fence doesn't really start exactly at the display plane 69352ff8bdSFrançois Tigeot * address we program because it starts at the real start of the buffer, so we 70352ff8bdSFrançois Tigeot * have to take this into consideration here. 71352ff8bdSFrançois Tigeot */ 72352ff8bdSFrançois Tigeot static unsigned int get_crtc_fence_y_offset(struct intel_crtc *crtc) 73352ff8bdSFrançois Tigeot { 74352ff8bdSFrançois Tigeot return crtc->base.y - crtc->adjusted_y; 75352ff8bdSFrançois Tigeot } 76352ff8bdSFrançois Tigeot 77aee94f86SFrançois Tigeot /* 78aee94f86SFrançois Tigeot * For SKL+, the plane source size used by the hardware is based on the value we 79aee94f86SFrançois Tigeot * write to the PLANE_SIZE register. For BDW-, the hardware looks at the value 80aee94f86SFrançois Tigeot * we wrote to PIPESRC. 81aee94f86SFrançois Tigeot */ 82c0e85e96SFrançois Tigeot static void intel_fbc_get_plane_source_size(struct intel_fbc_state_cache *cache, 83aee94f86SFrançois Tigeot int *width, int *height) 84aee94f86SFrançois Tigeot { 85aee94f86SFrançois Tigeot int w, h; 86aee94f86SFrançois Tigeot 87c0e85e96SFrançois Tigeot if (intel_rotation_90_or_270(cache->plane.rotation)) { 88c0e85e96SFrançois Tigeot w = cache->plane.src_h; 89c0e85e96SFrançois Tigeot h = cache->plane.src_w; 90aee94f86SFrançois Tigeot } else { 91c0e85e96SFrançois Tigeot w = cache->plane.src_w; 92c0e85e96SFrançois Tigeot h = cache->plane.src_h; 93aee94f86SFrançois Tigeot } 94aee94f86SFrançois Tigeot 95aee94f86SFrançois Tigeot if (width) 96aee94f86SFrançois Tigeot *width = w; 97aee94f86SFrançois Tigeot if (height) 98aee94f86SFrançois Tigeot *height = h; 99aee94f86SFrançois Tigeot } 100aee94f86SFrançois Tigeot 101c0e85e96SFrançois Tigeot static int intel_fbc_calculate_cfb_size(struct drm_i915_private *dev_priv, 102c0e85e96SFrançois Tigeot struct intel_fbc_state_cache *cache) 103aee94f86SFrançois Tigeot { 104aee94f86SFrançois Tigeot int lines; 105aee94f86SFrançois Tigeot 106c0e85e96SFrançois Tigeot intel_fbc_get_plane_source_size(cache, NULL, &lines); 107bf017597SFrançois Tigeot if (INTEL_GEN(dev_priv) == 7) 108aee94f86SFrançois Tigeot lines = min(lines, 2048); 109bf017597SFrançois Tigeot else if (INTEL_GEN(dev_priv) >= 8) 110bf017597SFrançois Tigeot lines = min(lines, 2560); 111aee94f86SFrançois Tigeot 112aee94f86SFrançois Tigeot /* Hardware needs the full buffer stride, not just the active area. */ 113c0e85e96SFrançois Tigeot return lines * cache->fb.stride; 114aee94f86SFrançois Tigeot } 115aee94f86SFrançois Tigeot 116aee94f86SFrançois Tigeot static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv) 1172c9916cdSFrançois Tigeot { 1182c9916cdSFrançois Tigeot u32 fbc_ctl; 1192c9916cdSFrançois Tigeot 1202c9916cdSFrançois Tigeot /* Disable compression */ 1212c9916cdSFrançois Tigeot fbc_ctl = I915_READ(FBC_CONTROL); 1222c9916cdSFrançois Tigeot if ((fbc_ctl & FBC_CTL_EN) == 0) 1232c9916cdSFrançois Tigeot return; 1242c9916cdSFrançois Tigeot 1252c9916cdSFrançois Tigeot fbc_ctl &= ~FBC_CTL_EN; 1262c9916cdSFrançois Tigeot I915_WRITE(FBC_CONTROL, fbc_ctl); 1272c9916cdSFrançois Tigeot 1282c9916cdSFrançois Tigeot /* Wait for compressing bit to clear */ 1291487f786SFrançois Tigeot if (intel_wait_for_register(dev_priv, 1301487f786SFrançois Tigeot FBC_STATUS, FBC_STAT_COMPRESSING, 0, 1311487f786SFrançois Tigeot 10)) { 1322c9916cdSFrançois Tigeot DRM_DEBUG_KMS("FBC idle timed out\n"); 1332c9916cdSFrançois Tigeot return; 1342c9916cdSFrançois Tigeot } 1352c9916cdSFrançois Tigeot } 1362c9916cdSFrançois Tigeot 137c0e85e96SFrançois Tigeot static void i8xx_fbc_activate(struct drm_i915_private *dev_priv) 1382c9916cdSFrançois Tigeot { 139c0e85e96SFrançois Tigeot struct intel_fbc_reg_params *params = &dev_priv->fbc.params; 1402c9916cdSFrançois Tigeot int cfb_pitch; 1412c9916cdSFrançois Tigeot int i; 1422c9916cdSFrançois Tigeot u32 fbc_ctl; 1432c9916cdSFrançois Tigeot 144477eb7f9SFrançois Tigeot /* Note: fbc.threshold == 1 for i8xx */ 145c0e85e96SFrançois Tigeot cfb_pitch = params->cfb_size / FBC_LL_SIZE; 146c0e85e96SFrançois Tigeot if (params->fb.stride < cfb_pitch) 147c0e85e96SFrançois Tigeot cfb_pitch = params->fb.stride; 1482c9916cdSFrançois Tigeot 1492c9916cdSFrançois Tigeot /* FBC_CTL wants 32B or 64B units */ 150a05eeebfSFrançois Tigeot if (IS_GEN2(dev_priv)) 1512c9916cdSFrançois Tigeot cfb_pitch = (cfb_pitch / 32) - 1; 1522c9916cdSFrançois Tigeot else 1532c9916cdSFrançois Tigeot cfb_pitch = (cfb_pitch / 64) - 1; 1542c9916cdSFrançois Tigeot 1552c9916cdSFrançois Tigeot /* Clear old tags */ 1562c9916cdSFrançois Tigeot for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++) 157352ff8bdSFrançois Tigeot I915_WRITE(FBC_TAG(i), 0); 1582c9916cdSFrançois Tigeot 159a05eeebfSFrançois Tigeot if (IS_GEN4(dev_priv)) { 1602c9916cdSFrançois Tigeot u32 fbc_ctl2; 1612c9916cdSFrançois Tigeot 1622c9916cdSFrançois Tigeot /* Set it up... */ 1632c9916cdSFrançois Tigeot fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE; 164c0e85e96SFrançois Tigeot fbc_ctl2 |= FBC_CTL_PLANE(params->crtc.plane); 1652c9916cdSFrançois Tigeot I915_WRITE(FBC_CONTROL2, fbc_ctl2); 166c0e85e96SFrançois Tigeot I915_WRITE(FBC_FENCE_OFF, params->crtc.fence_y_offset); 1672c9916cdSFrançois Tigeot } 1682c9916cdSFrançois Tigeot 1692c9916cdSFrançois Tigeot /* enable it... */ 1702c9916cdSFrançois Tigeot fbc_ctl = I915_READ(FBC_CONTROL); 1712c9916cdSFrançois Tigeot fbc_ctl &= 0x3fff << FBC_CTL_INTERVAL_SHIFT; 1722c9916cdSFrançois Tigeot fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC; 173a05eeebfSFrançois Tigeot if (IS_I945GM(dev_priv)) 1742c9916cdSFrançois Tigeot fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ 1752c9916cdSFrançois Tigeot fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; 176c0e85e96SFrançois Tigeot fbc_ctl |= params->fb.fence_reg; 1772c9916cdSFrançois Tigeot I915_WRITE(FBC_CONTROL, fbc_ctl); 1782c9916cdSFrançois Tigeot } 1792c9916cdSFrançois Tigeot 180aee94f86SFrançois Tigeot static bool i8xx_fbc_is_active(struct drm_i915_private *dev_priv) 1812c9916cdSFrançois Tigeot { 1822c9916cdSFrançois Tigeot return I915_READ(FBC_CONTROL) & FBC_CTL_EN; 1832c9916cdSFrançois Tigeot } 1842c9916cdSFrançois Tigeot 185c0e85e96SFrançois Tigeot static void g4x_fbc_activate(struct drm_i915_private *dev_priv) 1862c9916cdSFrançois Tigeot { 187c0e85e96SFrançois Tigeot struct intel_fbc_reg_params *params = &dev_priv->fbc.params; 1882c9916cdSFrançois Tigeot u32 dpfc_ctl; 1892c9916cdSFrançois Tigeot 190c0e85e96SFrançois Tigeot dpfc_ctl = DPFC_CTL_PLANE(params->crtc.plane) | DPFC_SR_EN; 191c0e85e96SFrançois Tigeot if (drm_format_plane_cpp(params->fb.pixel_format, 0) == 2) 1922c9916cdSFrançois Tigeot dpfc_ctl |= DPFC_CTL_LIMIT_2X; 1932c9916cdSFrançois Tigeot else 1942c9916cdSFrançois Tigeot dpfc_ctl |= DPFC_CTL_LIMIT_1X; 195c0e85e96SFrançois Tigeot dpfc_ctl |= DPFC_CTL_FENCE_EN | params->fb.fence_reg; 1962c9916cdSFrançois Tigeot 197c0e85e96SFrançois Tigeot I915_WRITE(DPFC_FENCE_YOFF, params->crtc.fence_y_offset); 1982c9916cdSFrançois Tigeot 1992c9916cdSFrançois Tigeot /* enable it... */ 2002c9916cdSFrançois Tigeot I915_WRITE(DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); 2012c9916cdSFrançois Tigeot } 2022c9916cdSFrançois Tigeot 203aee94f86SFrançois Tigeot static void g4x_fbc_deactivate(struct drm_i915_private *dev_priv) 2042c9916cdSFrançois Tigeot { 2052c9916cdSFrançois Tigeot u32 dpfc_ctl; 2062c9916cdSFrançois Tigeot 2072c9916cdSFrançois Tigeot /* Disable compression */ 2082c9916cdSFrançois Tigeot dpfc_ctl = I915_READ(DPFC_CONTROL); 2092c9916cdSFrançois Tigeot if (dpfc_ctl & DPFC_CTL_EN) { 2102c9916cdSFrançois Tigeot dpfc_ctl &= ~DPFC_CTL_EN; 2112c9916cdSFrançois Tigeot I915_WRITE(DPFC_CONTROL, dpfc_ctl); 2122c9916cdSFrançois Tigeot } 2132c9916cdSFrançois Tigeot } 2142c9916cdSFrançois Tigeot 215aee94f86SFrançois Tigeot static bool g4x_fbc_is_active(struct drm_i915_private *dev_priv) 2162c9916cdSFrançois Tigeot { 2172c9916cdSFrançois Tigeot return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; 2182c9916cdSFrançois Tigeot } 2192c9916cdSFrançois Tigeot 220aee94f86SFrançois Tigeot /* This function forces a CFB recompression through the nuke operation. */ 221aee94f86SFrançois Tigeot static void intel_fbc_recompress(struct drm_i915_private *dev_priv) 2222c9916cdSFrançois Tigeot { 223477eb7f9SFrançois Tigeot I915_WRITE(MSG_FBC_REND_STATE, FBC_REND_NUKE); 224477eb7f9SFrançois Tigeot POSTING_READ(MSG_FBC_REND_STATE); 2252c9916cdSFrançois Tigeot } 2262c9916cdSFrançois Tigeot 227c0e85e96SFrançois Tigeot static void ilk_fbc_activate(struct drm_i915_private *dev_priv) 2282c9916cdSFrançois Tigeot { 229c0e85e96SFrançois Tigeot struct intel_fbc_reg_params *params = &dev_priv->fbc.params; 2302c9916cdSFrançois Tigeot u32 dpfc_ctl; 231a05eeebfSFrançois Tigeot int threshold = dev_priv->fbc.threshold; 2322c9916cdSFrançois Tigeot 233c0e85e96SFrançois Tigeot dpfc_ctl = DPFC_CTL_PLANE(params->crtc.plane); 234c0e85e96SFrançois Tigeot if (drm_format_plane_cpp(params->fb.pixel_format, 0) == 2) 235a05eeebfSFrançois Tigeot threshold++; 2362c9916cdSFrançois Tigeot 237a05eeebfSFrançois Tigeot switch (threshold) { 2382c9916cdSFrançois Tigeot case 4: 2392c9916cdSFrançois Tigeot case 3: 2402c9916cdSFrançois Tigeot dpfc_ctl |= DPFC_CTL_LIMIT_4X; 2412c9916cdSFrançois Tigeot break; 2422c9916cdSFrançois Tigeot case 2: 2432c9916cdSFrançois Tigeot dpfc_ctl |= DPFC_CTL_LIMIT_2X; 2442c9916cdSFrançois Tigeot break; 2452c9916cdSFrançois Tigeot case 1: 2462c9916cdSFrançois Tigeot dpfc_ctl |= DPFC_CTL_LIMIT_1X; 2472c9916cdSFrançois Tigeot break; 2482c9916cdSFrançois Tigeot } 2492c9916cdSFrançois Tigeot dpfc_ctl |= DPFC_CTL_FENCE_EN; 250a05eeebfSFrançois Tigeot if (IS_GEN5(dev_priv)) 251c0e85e96SFrançois Tigeot dpfc_ctl |= params->fb.fence_reg; 2522c9916cdSFrançois Tigeot 253c0e85e96SFrançois Tigeot I915_WRITE(ILK_DPFC_FENCE_YOFF, params->crtc.fence_y_offset); 254c0e85e96SFrançois Tigeot I915_WRITE(ILK_FBC_RT_BASE, params->fb.ggtt_offset | ILK_FBC_RT_VALID); 2552c9916cdSFrançois Tigeot /* enable it... */ 2562c9916cdSFrançois Tigeot I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); 2572c9916cdSFrançois Tigeot 258a05eeebfSFrançois Tigeot if (IS_GEN6(dev_priv)) { 2592c9916cdSFrançois Tigeot I915_WRITE(SNB_DPFC_CTL_SA, 260c0e85e96SFrançois Tigeot SNB_CPU_FENCE_ENABLE | params->fb.fence_reg); 261c0e85e96SFrançois Tigeot I915_WRITE(DPFC_CPU_FENCE_OFFSET, params->crtc.fence_y_offset); 2622c9916cdSFrançois Tigeot } 2632c9916cdSFrançois Tigeot 264aee94f86SFrançois Tigeot intel_fbc_recompress(dev_priv); 2652c9916cdSFrançois Tigeot } 2662c9916cdSFrançois Tigeot 267aee94f86SFrançois Tigeot static void ilk_fbc_deactivate(struct drm_i915_private *dev_priv) 2682c9916cdSFrançois Tigeot { 2692c9916cdSFrançois Tigeot u32 dpfc_ctl; 2702c9916cdSFrançois Tigeot 2712c9916cdSFrançois Tigeot /* Disable compression */ 2722c9916cdSFrançois Tigeot dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); 2732c9916cdSFrançois Tigeot if (dpfc_ctl & DPFC_CTL_EN) { 2742c9916cdSFrançois Tigeot dpfc_ctl &= ~DPFC_CTL_EN; 2752c9916cdSFrançois Tigeot I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); 2762c9916cdSFrançois Tigeot } 2772c9916cdSFrançois Tigeot } 2782c9916cdSFrançois Tigeot 279aee94f86SFrançois Tigeot static bool ilk_fbc_is_active(struct drm_i915_private *dev_priv) 2802c9916cdSFrançois Tigeot { 2812c9916cdSFrançois Tigeot return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; 2822c9916cdSFrançois Tigeot } 2832c9916cdSFrançois Tigeot 284c0e85e96SFrançois Tigeot static void gen7_fbc_activate(struct drm_i915_private *dev_priv) 2852c9916cdSFrançois Tigeot { 286c0e85e96SFrançois Tigeot struct intel_fbc_reg_params *params = &dev_priv->fbc.params; 2872c9916cdSFrançois Tigeot u32 dpfc_ctl; 288a05eeebfSFrançois Tigeot int threshold = dev_priv->fbc.threshold; 2892c9916cdSFrançois Tigeot 290a05eeebfSFrançois Tigeot dpfc_ctl = 0; 291a05eeebfSFrançois Tigeot if (IS_IVYBRIDGE(dev_priv)) 292c0e85e96SFrançois Tigeot dpfc_ctl |= IVB_DPFC_CTL_PLANE(params->crtc.plane); 2932c9916cdSFrançois Tigeot 294c0e85e96SFrançois Tigeot if (drm_format_plane_cpp(params->fb.pixel_format, 0) == 2) 295a05eeebfSFrançois Tigeot threshold++; 296a05eeebfSFrançois Tigeot 297a05eeebfSFrançois Tigeot switch (threshold) { 2982c9916cdSFrançois Tigeot case 4: 2992c9916cdSFrançois Tigeot case 3: 3002c9916cdSFrançois Tigeot dpfc_ctl |= DPFC_CTL_LIMIT_4X; 3012c9916cdSFrançois Tigeot break; 3022c9916cdSFrançois Tigeot case 2: 3032c9916cdSFrançois Tigeot dpfc_ctl |= DPFC_CTL_LIMIT_2X; 3042c9916cdSFrançois Tigeot break; 3052c9916cdSFrançois Tigeot case 1: 3062c9916cdSFrançois Tigeot dpfc_ctl |= DPFC_CTL_LIMIT_1X; 3072c9916cdSFrançois Tigeot break; 3082c9916cdSFrançois Tigeot } 3092c9916cdSFrançois Tigeot 3102c9916cdSFrançois Tigeot dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN; 3112c9916cdSFrançois Tigeot 3122c9916cdSFrançois Tigeot if (dev_priv->fbc.false_color) 3132c9916cdSFrançois Tigeot dpfc_ctl |= FBC_CTL_FALSE_COLOR; 3142c9916cdSFrançois Tigeot 315a05eeebfSFrançois Tigeot if (IS_IVYBRIDGE(dev_priv)) { 3162c9916cdSFrançois Tigeot /* WaFbcAsynchFlipDisableFbcQueue:ivb */ 3172c9916cdSFrançois Tigeot I915_WRITE(ILK_DISPLAY_CHICKEN1, 3182c9916cdSFrançois Tigeot I915_READ(ILK_DISPLAY_CHICKEN1) | 3192c9916cdSFrançois Tigeot ILK_FBCQ_DIS); 320352ff8bdSFrançois Tigeot } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 3212c9916cdSFrançois Tigeot /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ 322c0e85e96SFrançois Tigeot I915_WRITE(CHICKEN_PIPESL_1(params->crtc.pipe), 323c0e85e96SFrançois Tigeot I915_READ(CHICKEN_PIPESL_1(params->crtc.pipe)) | 3242c9916cdSFrançois Tigeot HSW_FBCQ_DIS); 3252c9916cdSFrançois Tigeot } 3262c9916cdSFrançois Tigeot 327352ff8bdSFrançois Tigeot I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); 328352ff8bdSFrançois Tigeot 3292c9916cdSFrançois Tigeot I915_WRITE(SNB_DPFC_CTL_SA, 330c0e85e96SFrançois Tigeot SNB_CPU_FENCE_ENABLE | params->fb.fence_reg); 331c0e85e96SFrançois Tigeot I915_WRITE(DPFC_CPU_FENCE_OFFSET, params->crtc.fence_y_offset); 3322c9916cdSFrançois Tigeot 333aee94f86SFrançois Tigeot intel_fbc_recompress(dev_priv); 3342c9916cdSFrançois Tigeot } 3352c9916cdSFrançois Tigeot 336c0e85e96SFrançois Tigeot static bool intel_fbc_hw_is_active(struct drm_i915_private *dev_priv) 337c0e85e96SFrançois Tigeot { 338c0e85e96SFrançois Tigeot if (INTEL_INFO(dev_priv)->gen >= 5) 339c0e85e96SFrançois Tigeot return ilk_fbc_is_active(dev_priv); 340c0e85e96SFrançois Tigeot else if (IS_GM45(dev_priv)) 341c0e85e96SFrançois Tigeot return g4x_fbc_is_active(dev_priv); 342c0e85e96SFrançois Tigeot else 343c0e85e96SFrançois Tigeot return i8xx_fbc_is_active(dev_priv); 344c0e85e96SFrançois Tigeot } 345c0e85e96SFrançois Tigeot 346c0e85e96SFrançois Tigeot static void intel_fbc_hw_activate(struct drm_i915_private *dev_priv) 347c0e85e96SFrançois Tigeot { 348c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 349c0e85e96SFrançois Tigeot 350c0e85e96SFrançois Tigeot fbc->active = true; 351c0e85e96SFrançois Tigeot 352c0e85e96SFrançois Tigeot if (INTEL_INFO(dev_priv)->gen >= 7) 353c0e85e96SFrançois Tigeot gen7_fbc_activate(dev_priv); 354c0e85e96SFrançois Tigeot else if (INTEL_INFO(dev_priv)->gen >= 5) 355c0e85e96SFrançois Tigeot ilk_fbc_activate(dev_priv); 356c0e85e96SFrançois Tigeot else if (IS_GM45(dev_priv)) 357c0e85e96SFrançois Tigeot g4x_fbc_activate(dev_priv); 358c0e85e96SFrançois Tigeot else 359c0e85e96SFrançois Tigeot i8xx_fbc_activate(dev_priv); 360c0e85e96SFrançois Tigeot } 361c0e85e96SFrançois Tigeot 362c0e85e96SFrançois Tigeot static void intel_fbc_hw_deactivate(struct drm_i915_private *dev_priv) 363c0e85e96SFrançois Tigeot { 364c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 365c0e85e96SFrançois Tigeot 366c0e85e96SFrançois Tigeot fbc->active = false; 367c0e85e96SFrançois Tigeot 368c0e85e96SFrançois Tigeot if (INTEL_INFO(dev_priv)->gen >= 5) 369c0e85e96SFrançois Tigeot ilk_fbc_deactivate(dev_priv); 370c0e85e96SFrançois Tigeot else if (IS_GM45(dev_priv)) 371c0e85e96SFrançois Tigeot g4x_fbc_deactivate(dev_priv); 372c0e85e96SFrançois Tigeot else 373c0e85e96SFrançois Tigeot i8xx_fbc_deactivate(dev_priv); 374c0e85e96SFrançois Tigeot } 375c0e85e96SFrançois Tigeot 3762c9916cdSFrançois Tigeot /** 377aee94f86SFrançois Tigeot * intel_fbc_is_active - Is FBC active? 378a05eeebfSFrançois Tigeot * @dev_priv: i915 device instance 3792c9916cdSFrançois Tigeot * 3802c9916cdSFrançois Tigeot * This function is used to verify the current state of FBC. 3811487f786SFrançois Tigeot * 3822c9916cdSFrançois Tigeot * FIXME: This should be tracked in the plane config eventually 3832c9916cdSFrançois Tigeot * instead of queried at runtime for most callers. 3842c9916cdSFrançois Tigeot */ 385aee94f86SFrançois Tigeot bool intel_fbc_is_active(struct drm_i915_private *dev_priv) 3862c9916cdSFrançois Tigeot { 387aee94f86SFrançois Tigeot return dev_priv->fbc.active; 3882c9916cdSFrançois Tigeot } 3892c9916cdSFrançois Tigeot 3902c9916cdSFrançois Tigeot static void intel_fbc_work_fn(struct work_struct *__work) 3912c9916cdSFrançois Tigeot { 392aee94f86SFrançois Tigeot struct drm_i915_private *dev_priv = 393aee94f86SFrançois Tigeot container_of(__work, struct drm_i915_private, fbc.work.work); 394c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 395c0e85e96SFrançois Tigeot struct intel_fbc_work *work = &fbc->work; 396c0e85e96SFrançois Tigeot struct intel_crtc *crtc = fbc->crtc; 397303bf270SFrançois Tigeot struct drm_vblank_crtc *vblank = &dev_priv->drm.vblank[crtc->pipe]; 398c0e85e96SFrançois Tigeot 399c0e85e96SFrançois Tigeot if (drm_crtc_vblank_get(&crtc->base)) { 400c0e85e96SFrançois Tigeot DRM_ERROR("vblank not available for FBC on pipe %c\n", 401c0e85e96SFrançois Tigeot pipe_name(crtc->pipe)); 402c0e85e96SFrançois Tigeot 403c0e85e96SFrançois Tigeot mutex_lock(&fbc->lock); 404c0e85e96SFrançois Tigeot work->scheduled = false; 405c0e85e96SFrançois Tigeot mutex_unlock(&fbc->lock); 406c0e85e96SFrançois Tigeot return; 407c0e85e96SFrançois Tigeot } 4082c9916cdSFrançois Tigeot 409aee94f86SFrançois Tigeot retry: 4102c9916cdSFrançois Tigeot /* Delay the actual enabling to let pageflipping cease and the 4112c9916cdSFrançois Tigeot * display to settle before starting the compression. Note that 4122c9916cdSFrançois Tigeot * this delay also serves a second purpose: it allows for a 4132c9916cdSFrançois Tigeot * vblank to pass after disabling the FBC before we attempt 4142c9916cdSFrançois Tigeot * to modify the control registers. 4152c9916cdSFrançois Tigeot * 4162c9916cdSFrançois Tigeot * WaFbcWaitForVBlankBeforeEnable:ilk,snb 417c0e85e96SFrançois Tigeot * 418c0e85e96SFrançois Tigeot * It is also worth mentioning that since work->scheduled_vblank can be 419c0e85e96SFrançois Tigeot * updated multiple times by the other threads, hitting the timeout is 420c0e85e96SFrançois Tigeot * not an error condition. We'll just end up hitting the "goto retry" 421c0e85e96SFrançois Tigeot * case below. 4222c9916cdSFrançois Tigeot */ 423c0e85e96SFrançois Tigeot wait_event_timeout(vblank->queue, 424c0e85e96SFrançois Tigeot drm_crtc_vblank_count(&crtc->base) != work->scheduled_vblank, 425c0e85e96SFrançois Tigeot msecs_to_jiffies(50)); 426aee94f86SFrançois Tigeot 427c0e85e96SFrançois Tigeot mutex_lock(&fbc->lock); 428aee94f86SFrançois Tigeot 429aee94f86SFrançois Tigeot /* Were we cancelled? */ 430aee94f86SFrançois Tigeot if (!work->scheduled) 431aee94f86SFrançois Tigeot goto out; 432aee94f86SFrançois Tigeot 433aee94f86SFrançois Tigeot /* Were we delayed again while this function was sleeping? */ 434c0e85e96SFrançois Tigeot if (drm_crtc_vblank_count(&crtc->base) == work->scheduled_vblank) { 435c0e85e96SFrançois Tigeot mutex_unlock(&fbc->lock); 436aee94f86SFrançois Tigeot goto retry; 4372c9916cdSFrançois Tigeot } 4382c9916cdSFrançois Tigeot 439c0e85e96SFrançois Tigeot intel_fbc_hw_activate(dev_priv); 440aee94f86SFrançois Tigeot 441aee94f86SFrançois Tigeot work->scheduled = false; 442aee94f86SFrançois Tigeot 443aee94f86SFrançois Tigeot out: 444c0e85e96SFrançois Tigeot mutex_unlock(&fbc->lock); 445c0e85e96SFrançois Tigeot drm_crtc_vblank_put(&crtc->base); 446aee94f86SFrançois Tigeot } 447aee94f86SFrançois Tigeot 448aee94f86SFrançois Tigeot static void intel_fbc_schedule_activation(struct intel_crtc *crtc) 449aee94f86SFrançois Tigeot { 450303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 451c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 452c0e85e96SFrançois Tigeot struct intel_fbc_work *work = &fbc->work; 453aee94f86SFrançois Tigeot 454c0e85e96SFrançois Tigeot WARN_ON(!mutex_is_locked(&fbc->lock)); 455aee94f86SFrançois Tigeot 456c0e85e96SFrançois Tigeot if (drm_crtc_vblank_get(&crtc->base)) { 457c0e85e96SFrançois Tigeot DRM_ERROR("vblank not available for FBC on pipe %c\n", 458c0e85e96SFrançois Tigeot pipe_name(crtc->pipe)); 459c0e85e96SFrançois Tigeot return; 460c0e85e96SFrançois Tigeot } 461c0e85e96SFrançois Tigeot 462c0e85e96SFrançois Tigeot /* It is useless to call intel_fbc_cancel_work() or cancel_work() in 463c0e85e96SFrançois Tigeot * this function since we're not releasing fbc.lock, so it won't have an 464c0e85e96SFrançois Tigeot * opportunity to grab it to discover that it was cancelled. So we just 465c0e85e96SFrançois Tigeot * update the expected jiffy count. */ 466aee94f86SFrançois Tigeot work->scheduled = true; 467c0e85e96SFrançois Tigeot work->scheduled_vblank = drm_crtc_vblank_count(&crtc->base); 468c0e85e96SFrançois Tigeot drm_crtc_vblank_put(&crtc->base); 469aee94f86SFrançois Tigeot 470aee94f86SFrançois Tigeot schedule_work(&work->work); 471aee94f86SFrançois Tigeot } 472aee94f86SFrançois Tigeot 473c0e85e96SFrançois Tigeot static void intel_fbc_deactivate(struct drm_i915_private *dev_priv) 4742c9916cdSFrançois Tigeot { 475c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 4762c9916cdSFrançois Tigeot 477c0e85e96SFrançois Tigeot WARN_ON(!mutex_is_locked(&fbc->lock)); 4782c9916cdSFrançois Tigeot 479c0e85e96SFrançois Tigeot /* Calling cancel_work() here won't help due to the fact that the work 480c0e85e96SFrançois Tigeot * function grabs fbc->lock. Just set scheduled to false so the work 481c0e85e96SFrançois Tigeot * function can know it was cancelled. */ 482c0e85e96SFrançois Tigeot fbc->work.scheduled = false; 483c0e85e96SFrançois Tigeot 484c0e85e96SFrançois Tigeot if (fbc->active) 485c0e85e96SFrançois Tigeot intel_fbc_hw_deactivate(dev_priv); 486a05eeebfSFrançois Tigeot } 487a05eeebfSFrançois Tigeot 4881487f786SFrançois Tigeot static bool multiple_pipes_ok(struct intel_crtc *crtc, 4891487f786SFrançois Tigeot struct intel_plane_state *plane_state) 490a05eeebfSFrançois Tigeot { 4911487f786SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 492c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 493c0e85e96SFrançois Tigeot enum i915_pipe pipe = crtc->pipe; 494a05eeebfSFrançois Tigeot 495c0e85e96SFrançois Tigeot /* Don't even bother tracking anything we don't need. */ 496c0e85e96SFrançois Tigeot if (!no_fbc_on_multiple_pipes(dev_priv)) 497a05eeebfSFrançois Tigeot return true; 498a05eeebfSFrançois Tigeot 4991487f786SFrançois Tigeot if (plane_state->visible) 500c0e85e96SFrançois Tigeot fbc->visible_pipes_mask |= (1 << pipe); 501c0e85e96SFrançois Tigeot else 502c0e85e96SFrançois Tigeot fbc->visible_pipes_mask &= ~(1 << pipe); 503a05eeebfSFrançois Tigeot 504c0e85e96SFrançois Tigeot return (fbc->visible_pipes_mask & ~(1 << pipe)) != 0; 505a05eeebfSFrançois Tigeot } 506a05eeebfSFrançois Tigeot 507a05eeebfSFrançois Tigeot static int find_compression_threshold(struct drm_i915_private *dev_priv, 508a05eeebfSFrançois Tigeot struct drm_mm_node *node, 509a05eeebfSFrançois Tigeot int size, 510a05eeebfSFrançois Tigeot int fb_cpp) 511a05eeebfSFrançois Tigeot { 5128621f407SFrançois Tigeot struct i915_ggtt *ggtt = &dev_priv->ggtt; 513a05eeebfSFrançois Tigeot int compression_threshold = 1; 514a05eeebfSFrançois Tigeot int ret; 515352ff8bdSFrançois Tigeot u64 end; 516352ff8bdSFrançois Tigeot 517352ff8bdSFrançois Tigeot /* The FBC hardware for BDW/SKL doesn't have access to the stolen 518352ff8bdSFrançois Tigeot * reserved range size, so it always assumes the maximum (8mb) is used. 519352ff8bdSFrançois Tigeot * If we enable FBC using a CFB on that memory range we'll get FIFO 520352ff8bdSFrançois Tigeot * underruns, even if that range is not reserved by the BIOS. */ 521aee94f86SFrançois Tigeot if (IS_BROADWELL(dev_priv) || 522aee94f86SFrançois Tigeot IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) 5238621f407SFrançois Tigeot end = ggtt->stolen_size - 8 * 1024 * 1024; 524352ff8bdSFrançois Tigeot else 5258621f407SFrançois Tigeot end = ggtt->stolen_usable_size; 526a05eeebfSFrançois Tigeot 527a05eeebfSFrançois Tigeot /* HACK: This code depends on what we will do in *_enable_fbc. If that 528a05eeebfSFrançois Tigeot * code changes, this code needs to change as well. 529a05eeebfSFrançois Tigeot * 530a05eeebfSFrançois Tigeot * The enable_fbc code will attempt to use one of our 2 compression 531a05eeebfSFrançois Tigeot * thresholds, therefore, in that case, we only have 1 resort. 532a05eeebfSFrançois Tigeot */ 533a05eeebfSFrançois Tigeot 534a05eeebfSFrançois Tigeot /* Try to over-allocate to reduce reallocations and fragmentation. */ 535352ff8bdSFrançois Tigeot ret = i915_gem_stolen_insert_node_in_range(dev_priv, node, size <<= 1, 536352ff8bdSFrançois Tigeot 4096, 0, end); 537a05eeebfSFrançois Tigeot if (ret == 0) 538a05eeebfSFrançois Tigeot return compression_threshold; 539a05eeebfSFrançois Tigeot 540a05eeebfSFrançois Tigeot again: 541a05eeebfSFrançois Tigeot /* HW's ability to limit the CFB is 1:4 */ 542a05eeebfSFrançois Tigeot if (compression_threshold > 4 || 543a05eeebfSFrançois Tigeot (fb_cpp == 2 && compression_threshold == 2)) 544a05eeebfSFrançois Tigeot return 0; 545a05eeebfSFrançois Tigeot 546352ff8bdSFrançois Tigeot ret = i915_gem_stolen_insert_node_in_range(dev_priv, node, size >>= 1, 547352ff8bdSFrançois Tigeot 4096, 0, end); 548a05eeebfSFrançois Tigeot if (ret && INTEL_INFO(dev_priv)->gen <= 4) { 549a05eeebfSFrançois Tigeot return 0; 550a05eeebfSFrançois Tigeot } else if (ret) { 551a05eeebfSFrançois Tigeot compression_threshold <<= 1; 552a05eeebfSFrançois Tigeot goto again; 553a05eeebfSFrançois Tigeot } else { 554a05eeebfSFrançois Tigeot return compression_threshold; 555a05eeebfSFrançois Tigeot } 556a05eeebfSFrançois Tigeot } 557a05eeebfSFrançois Tigeot 558aee94f86SFrançois Tigeot static int intel_fbc_alloc_cfb(struct intel_crtc *crtc) 559a05eeebfSFrançois Tigeot { 560303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 561c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 562aee94f86SFrançois Tigeot struct drm_mm_node *compressed_llb = NULL; 563aee94f86SFrançois Tigeot int size, fb_cpp, ret; 564aee94f86SFrançois Tigeot 565c0e85e96SFrançois Tigeot WARN_ON(drm_mm_node_allocated(&fbc->compressed_fb)); 566aee94f86SFrançois Tigeot 567c0e85e96SFrançois Tigeot size = intel_fbc_calculate_cfb_size(dev_priv, &fbc->state_cache); 568c0e85e96SFrançois Tigeot fb_cpp = drm_format_plane_cpp(fbc->state_cache.fb.pixel_format, 0); 569a05eeebfSFrançois Tigeot 570c0e85e96SFrançois Tigeot ret = find_compression_threshold(dev_priv, &fbc->compressed_fb, 571a05eeebfSFrançois Tigeot size, fb_cpp); 572a05eeebfSFrançois Tigeot if (!ret) 573a05eeebfSFrançois Tigeot goto err_llb; 574a05eeebfSFrançois Tigeot else if (ret > 1) { 575a05eeebfSFrançois Tigeot 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"); 576a05eeebfSFrançois Tigeot 577a05eeebfSFrançois Tigeot } 578a05eeebfSFrançois Tigeot 579c0e85e96SFrançois Tigeot fbc->threshold = ret; 580a05eeebfSFrançois Tigeot 581a05eeebfSFrançois Tigeot if (INTEL_INFO(dev_priv)->gen >= 5) 582c0e85e96SFrançois Tigeot I915_WRITE(ILK_DPFC_CB_BASE, fbc->compressed_fb.start); 583a05eeebfSFrançois Tigeot else if (IS_GM45(dev_priv)) { 584c0e85e96SFrançois Tigeot I915_WRITE(DPFC_CB_BASE, fbc->compressed_fb.start); 585a05eeebfSFrançois Tigeot } else { 586a05eeebfSFrançois Tigeot compressed_llb = kzalloc(sizeof(*compressed_llb), GFP_KERNEL); 587a05eeebfSFrançois Tigeot if (!compressed_llb) 588a05eeebfSFrançois Tigeot goto err_fb; 589a05eeebfSFrançois Tigeot 590a05eeebfSFrançois Tigeot ret = i915_gem_stolen_insert_node(dev_priv, compressed_llb, 591a05eeebfSFrançois Tigeot 4096, 4096); 592a05eeebfSFrançois Tigeot if (ret) 593a05eeebfSFrançois Tigeot goto err_fb; 594a05eeebfSFrançois Tigeot 595c0e85e96SFrançois Tigeot fbc->compressed_llb = compressed_llb; 596a05eeebfSFrançois Tigeot 597a05eeebfSFrançois Tigeot I915_WRITE(FBC_CFB_BASE, 598c0e85e96SFrançois Tigeot dev_priv->mm.stolen_base + fbc->compressed_fb.start); 599a05eeebfSFrançois Tigeot I915_WRITE(FBC_LL_BASE, 600a05eeebfSFrançois Tigeot dev_priv->mm.stolen_base + compressed_llb->start); 601a05eeebfSFrançois Tigeot } 602a05eeebfSFrançois Tigeot 603f77dbd6cSFrançois Tigeot DRM_DEBUG_KMS("reserved %llu bytes of contiguous stolen space for FBC, threshold: %d\n", 604c0e85e96SFrançois Tigeot fbc->compressed_fb.size, fbc->threshold); 605a05eeebfSFrançois Tigeot 606a05eeebfSFrançois Tigeot return 0; 607a05eeebfSFrançois Tigeot 608a05eeebfSFrançois Tigeot err_fb: 609a05eeebfSFrançois Tigeot kfree(compressed_llb); 610c0e85e96SFrançois Tigeot i915_gem_stolen_remove_node(dev_priv, &fbc->compressed_fb); 611a05eeebfSFrançois Tigeot err_llb: 612a05eeebfSFrançois Tigeot pr_info_once("drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size); 613a05eeebfSFrançois Tigeot return -ENOSPC; 614a05eeebfSFrançois Tigeot } 615a05eeebfSFrançois Tigeot 616a05eeebfSFrançois Tigeot static void __intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv) 617a05eeebfSFrançois Tigeot { 618c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 619a05eeebfSFrançois Tigeot 620c0e85e96SFrançois Tigeot if (drm_mm_node_allocated(&fbc->compressed_fb)) 621c0e85e96SFrançois Tigeot i915_gem_stolen_remove_node(dev_priv, &fbc->compressed_fb); 622c0e85e96SFrançois Tigeot 623c0e85e96SFrançois Tigeot if (fbc->compressed_llb) { 624c0e85e96SFrançois Tigeot i915_gem_stolen_remove_node(dev_priv, fbc->compressed_llb); 625c0e85e96SFrançois Tigeot kfree(fbc->compressed_llb); 626a05eeebfSFrançois Tigeot } 627a05eeebfSFrançois Tigeot } 628a05eeebfSFrançois Tigeot 629a05eeebfSFrançois Tigeot void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv) 630a05eeebfSFrançois Tigeot { 631c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 632c0e85e96SFrançois Tigeot 633352ff8bdSFrançois Tigeot if (!fbc_supported(dev_priv)) 634a05eeebfSFrançois Tigeot return; 635a05eeebfSFrançois Tigeot 636c0e85e96SFrançois Tigeot mutex_lock(&fbc->lock); 637a05eeebfSFrançois Tigeot __intel_fbc_cleanup_cfb(dev_priv); 638c0e85e96SFrançois Tigeot mutex_unlock(&fbc->lock); 639a05eeebfSFrançois Tigeot } 640a05eeebfSFrançois Tigeot 641352ff8bdSFrançois Tigeot static bool stride_is_valid(struct drm_i915_private *dev_priv, 642352ff8bdSFrançois Tigeot unsigned int stride) 643352ff8bdSFrançois Tigeot { 644352ff8bdSFrançois Tigeot /* These should have been caught earlier. */ 645352ff8bdSFrançois Tigeot WARN_ON(stride < 512); 646352ff8bdSFrançois Tigeot WARN_ON((stride & (64 - 1)) != 0); 647352ff8bdSFrançois Tigeot 648352ff8bdSFrançois Tigeot /* Below are the additional FBC restrictions. */ 649352ff8bdSFrançois Tigeot 650352ff8bdSFrançois Tigeot if (IS_GEN2(dev_priv) || IS_GEN3(dev_priv)) 651352ff8bdSFrançois Tigeot return stride == 4096 || stride == 8192; 652352ff8bdSFrançois Tigeot 653352ff8bdSFrançois Tigeot if (IS_GEN4(dev_priv) && !IS_G4X(dev_priv) && stride < 2048) 654352ff8bdSFrançois Tigeot return false; 655352ff8bdSFrançois Tigeot 656352ff8bdSFrançois Tigeot if (stride > 16384) 657352ff8bdSFrançois Tigeot return false; 658352ff8bdSFrançois Tigeot 659352ff8bdSFrançois Tigeot return true; 660352ff8bdSFrançois Tigeot } 661352ff8bdSFrançois Tigeot 662c0e85e96SFrançois Tigeot static bool pixel_format_is_valid(struct drm_i915_private *dev_priv, 663c0e85e96SFrançois Tigeot uint32_t pixel_format) 664352ff8bdSFrançois Tigeot { 665c0e85e96SFrançois Tigeot switch (pixel_format) { 666352ff8bdSFrançois Tigeot case DRM_FORMAT_XRGB8888: 667352ff8bdSFrançois Tigeot case DRM_FORMAT_XBGR8888: 668352ff8bdSFrançois Tigeot return true; 669352ff8bdSFrançois Tigeot case DRM_FORMAT_XRGB1555: 670352ff8bdSFrançois Tigeot case DRM_FORMAT_RGB565: 671352ff8bdSFrançois Tigeot /* 16bpp not supported on gen2 */ 672c0e85e96SFrançois Tigeot if (IS_GEN2(dev_priv)) 673352ff8bdSFrançois Tigeot return false; 674352ff8bdSFrançois Tigeot /* WaFbcOnly1to1Ratio:ctg */ 675352ff8bdSFrançois Tigeot if (IS_G4X(dev_priv)) 676352ff8bdSFrançois Tigeot return false; 677352ff8bdSFrançois Tigeot return true; 678352ff8bdSFrançois Tigeot default: 679352ff8bdSFrançois Tigeot return false; 680352ff8bdSFrançois Tigeot } 681352ff8bdSFrançois Tigeot } 682352ff8bdSFrançois Tigeot 683352ff8bdSFrançois Tigeot /* 684352ff8bdSFrançois Tigeot * For some reason, the hardware tracking starts looking at whatever we 685352ff8bdSFrançois Tigeot * programmed as the display plane base address register. It does not look at 686352ff8bdSFrançois Tigeot * the X and Y offset registers. That's why we look at the crtc->adjusted{x,y} 687352ff8bdSFrançois Tigeot * variables instead of just looking at the pipe/plane size. 688352ff8bdSFrançois Tigeot */ 689352ff8bdSFrançois Tigeot static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) 690352ff8bdSFrançois Tigeot { 691303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 692c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 693352ff8bdSFrançois Tigeot unsigned int effective_w, effective_h, max_w, max_h; 694352ff8bdSFrançois Tigeot 695352ff8bdSFrançois Tigeot if (INTEL_INFO(dev_priv)->gen >= 8 || IS_HASWELL(dev_priv)) { 696352ff8bdSFrançois Tigeot max_w = 4096; 697352ff8bdSFrançois Tigeot max_h = 4096; 698352ff8bdSFrançois Tigeot } else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) { 699352ff8bdSFrançois Tigeot max_w = 4096; 700352ff8bdSFrançois Tigeot max_h = 2048; 701352ff8bdSFrançois Tigeot } else { 702352ff8bdSFrançois Tigeot max_w = 2048; 703352ff8bdSFrançois Tigeot max_h = 1536; 704352ff8bdSFrançois Tigeot } 705352ff8bdSFrançois Tigeot 706c0e85e96SFrançois Tigeot intel_fbc_get_plane_source_size(&fbc->state_cache, &effective_w, 707c0e85e96SFrançois Tigeot &effective_h); 708352ff8bdSFrançois Tigeot effective_w += crtc->adjusted_x; 709352ff8bdSFrançois Tigeot effective_h += crtc->adjusted_y; 710352ff8bdSFrançois Tigeot 711352ff8bdSFrançois Tigeot return effective_w <= max_w && effective_h <= max_h; 712a05eeebfSFrançois Tigeot } 713a05eeebfSFrançois Tigeot 7141487f786SFrançois Tigeot static void intel_fbc_update_state_cache(struct intel_crtc *crtc, 7151487f786SFrançois Tigeot struct intel_crtc_state *crtc_state, 7161487f786SFrançois Tigeot struct intel_plane_state *plane_state) 7172c9916cdSFrançois Tigeot { 718303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 719c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 720c0e85e96SFrançois Tigeot struct intel_fbc_state_cache *cache = &fbc->state_cache; 721c0e85e96SFrançois Tigeot struct drm_framebuffer *fb = plane_state->base.fb; 7222c9916cdSFrançois Tigeot struct drm_i915_gem_object *obj; 7232c9916cdSFrançois Tigeot 724c0e85e96SFrançois Tigeot cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags; 725c0e85e96SFrançois Tigeot if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) 726c0e85e96SFrançois Tigeot cache->crtc.hsw_bdw_pixel_rate = 727c0e85e96SFrançois Tigeot ilk_pipe_pixel_rate(crtc_state); 7282c9916cdSFrançois Tigeot 729c0e85e96SFrançois Tigeot cache->plane.rotation = plane_state->base.rotation; 730c0e85e96SFrançois Tigeot cache->plane.src_w = drm_rect_width(&plane_state->src) >> 16; 731c0e85e96SFrançois Tigeot cache->plane.src_h = drm_rect_height(&plane_state->src) >> 16; 732c0e85e96SFrançois Tigeot cache->plane.visible = plane_state->visible; 733c0e85e96SFrançois Tigeot 734c0e85e96SFrançois Tigeot if (!cache->plane.visible) 735aee94f86SFrançois Tigeot return; 736aee94f86SFrançois Tigeot 737c0e85e96SFrançois Tigeot obj = intel_fb_obj(fb); 738c0e85e96SFrançois Tigeot 739c0e85e96SFrançois Tigeot /* FIXME: We lack the proper locking here, so only run this on the 740c0e85e96SFrançois Tigeot * platforms that need. */ 7411487f786SFrançois Tigeot if (IS_GEN(dev_priv, 5, 6)) 742c0e85e96SFrançois Tigeot cache->fb.ilk_ggtt_offset = i915_gem_obj_ggtt_offset(obj); 743c0e85e96SFrançois Tigeot cache->fb.pixel_format = fb->pixel_format; 744c0e85e96SFrançois Tigeot cache->fb.stride = fb->pitches[0]; 745c0e85e96SFrançois Tigeot cache->fb.fence_reg = obj->fence_reg; 746c0e85e96SFrançois Tigeot cache->fb.tiling_mode = obj->tiling_mode; 747aee94f86SFrançois Tigeot } 748aee94f86SFrançois Tigeot 749c0e85e96SFrançois Tigeot static bool intel_fbc_can_activate(struct intel_crtc *crtc) 750c0e85e96SFrançois Tigeot { 751303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 752c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 753c0e85e96SFrançois Tigeot struct intel_fbc_state_cache *cache = &fbc->state_cache; 7542c9916cdSFrançois Tigeot 755c0e85e96SFrançois Tigeot if (!cache->plane.visible) { 756c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "primary plane not visible"; 757c0e85e96SFrançois Tigeot return false; 758c0e85e96SFrançois Tigeot } 759c0e85e96SFrançois Tigeot 760c0e85e96SFrançois Tigeot if ((cache->crtc.mode_flags & DRM_MODE_FLAG_INTERLACE) || 761c0e85e96SFrançois Tigeot (cache->crtc.mode_flags & DRM_MODE_FLAG_DBLSCAN)) { 762c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "incompatible mode"; 763c0e85e96SFrançois Tigeot return false; 7642c9916cdSFrançois Tigeot } 7652c9916cdSFrançois Tigeot 766aee94f86SFrançois Tigeot if (!intel_fbc_hw_tracking_covers_screen(crtc)) { 767c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "mode too large for compression"; 768c0e85e96SFrançois Tigeot return false; 7692c9916cdSFrançois Tigeot } 7702c9916cdSFrançois Tigeot 7712c9916cdSFrançois Tigeot /* The use of a CPU fence is mandatory in order to detect writes 7722c9916cdSFrançois Tigeot * by the CPU to the scanout and trigger updates to the FBC. 7732c9916cdSFrançois Tigeot */ 774c0e85e96SFrançois Tigeot if (cache->fb.tiling_mode != I915_TILING_X || 775c0e85e96SFrançois Tigeot cache->fb.fence_reg == I915_FENCE_REG_NONE) { 776c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "framebuffer not tiled or fenced"; 777c0e85e96SFrançois Tigeot return false; 7782c9916cdSFrançois Tigeot } 779a05eeebfSFrançois Tigeot if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_G4X(dev_priv) && 7801dedbd3bSFrançois Tigeot cache->plane.rotation != DRM_ROTATE_0) { 781c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "rotation unsupported"; 782c0e85e96SFrançois Tigeot return false; 7832c9916cdSFrançois Tigeot } 7842c9916cdSFrançois Tigeot 785c0e85e96SFrançois Tigeot if (!stride_is_valid(dev_priv, cache->fb.stride)) { 786c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "framebuffer stride not supported"; 787c0e85e96SFrançois Tigeot return false; 788352ff8bdSFrançois Tigeot } 789352ff8bdSFrançois Tigeot 790c0e85e96SFrançois Tigeot if (!pixel_format_is_valid(dev_priv, cache->fb.pixel_format)) { 791c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "pixel format is invalid"; 792c0e85e96SFrançois Tigeot return false; 793352ff8bdSFrançois Tigeot } 794352ff8bdSFrançois Tigeot 795352ff8bdSFrançois Tigeot /* WaFbcExceedCdClockThreshold:hsw,bdw */ 796352ff8bdSFrançois Tigeot if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) && 797c0e85e96SFrançois Tigeot cache->crtc.hsw_bdw_pixel_rate >= dev_priv->cdclk_freq * 95 / 100) { 798c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "pixel rate is too big"; 799c0e85e96SFrançois Tigeot return false; 800352ff8bdSFrançois Tigeot } 801352ff8bdSFrançois Tigeot 802aee94f86SFrançois Tigeot /* It is possible for the required CFB size change without a 803aee94f86SFrançois Tigeot * crtc->disable + crtc->enable since it is possible to change the 804aee94f86SFrançois Tigeot * stride without triggering a full modeset. Since we try to 805aee94f86SFrançois Tigeot * over-allocate the CFB, there's a chance we may keep FBC enabled even 806aee94f86SFrançois Tigeot * if this happens, but if we exceed the current CFB size we'll have to 807aee94f86SFrançois Tigeot * disable FBC. Notice that it would be possible to disable FBC, wait 808aee94f86SFrançois Tigeot * for a frame, free the stolen node, then try to reenable FBC in case 809aee94f86SFrançois Tigeot * we didn't get any invalidate/deactivate calls, but this would require 810aee94f86SFrançois Tigeot * a lot of tracking just for a specific case. If we conclude it's an 811aee94f86SFrançois Tigeot * important case, we can implement it later. */ 812c0e85e96SFrançois Tigeot if (intel_fbc_calculate_cfb_size(dev_priv, &fbc->state_cache) > 813c0e85e96SFrançois Tigeot fbc->compressed_fb.size * fbc->threshold) { 814c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "CFB requirements changed"; 815c0e85e96SFrançois Tigeot return false; 8162c9916cdSFrançois Tigeot } 8172c9916cdSFrançois Tigeot 818c0e85e96SFrançois Tigeot return true; 819c0e85e96SFrançois Tigeot } 820c0e85e96SFrançois Tigeot 821c0e85e96SFrançois Tigeot static bool intel_fbc_can_choose(struct intel_crtc *crtc) 822c0e85e96SFrançois Tigeot { 823303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 824c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 825c0e85e96SFrançois Tigeot 8261487f786SFrançois Tigeot if (intel_vgpu_active(dev_priv)) { 827c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "VGPU is active"; 828c0e85e96SFrançois Tigeot return false; 829c0e85e96SFrançois Tigeot } 830c0e85e96SFrançois Tigeot 831c0e85e96SFrançois Tigeot if (!i915.enable_fbc) { 832303bf270SFrançois Tigeot fbc->no_fbc_reason = "disabled per module param or by default"; 833c0e85e96SFrançois Tigeot return false; 834c0e85e96SFrançois Tigeot } 835c0e85e96SFrançois Tigeot 836c0e85e96SFrançois Tigeot if (fbc_on_pipe_a_only(dev_priv) && crtc->pipe != PIPE_A) { 837c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "no enabled pipes can have FBC"; 838c0e85e96SFrançois Tigeot return false; 839c0e85e96SFrançois Tigeot } 840c0e85e96SFrançois Tigeot 841c0e85e96SFrançois Tigeot if (fbc_on_plane_a_only(dev_priv) && crtc->plane != PLANE_A) { 842c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "no enabled planes can have FBC"; 843c0e85e96SFrançois Tigeot return false; 844c0e85e96SFrançois Tigeot } 845c0e85e96SFrançois Tigeot 846c0e85e96SFrançois Tigeot return true; 847c0e85e96SFrançois Tigeot } 848c0e85e96SFrançois Tigeot 849c0e85e96SFrançois Tigeot static void intel_fbc_get_reg_params(struct intel_crtc *crtc, 850c0e85e96SFrançois Tigeot struct intel_fbc_reg_params *params) 851c0e85e96SFrançois Tigeot { 852303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 853c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 854c0e85e96SFrançois Tigeot struct intel_fbc_state_cache *cache = &fbc->state_cache; 855c0e85e96SFrançois Tigeot 856c0e85e96SFrançois Tigeot /* Since all our fields are integer types, use memset here so the 857c0e85e96SFrançois Tigeot * comparison function can rely on memcmp because the padding will be 858c0e85e96SFrançois Tigeot * zero. */ 859c0e85e96SFrançois Tigeot memset(params, 0, sizeof(*params)); 860c0e85e96SFrançois Tigeot 861c0e85e96SFrançois Tigeot params->crtc.pipe = crtc->pipe; 862c0e85e96SFrançois Tigeot params->crtc.plane = crtc->plane; 863c0e85e96SFrançois Tigeot params->crtc.fence_y_offset = get_crtc_fence_y_offset(crtc); 864c0e85e96SFrançois Tigeot 865c0e85e96SFrançois Tigeot params->fb.pixel_format = cache->fb.pixel_format; 866c0e85e96SFrançois Tigeot params->fb.stride = cache->fb.stride; 867c0e85e96SFrançois Tigeot params->fb.fence_reg = cache->fb.fence_reg; 868c0e85e96SFrançois Tigeot 869c0e85e96SFrançois Tigeot params->cfb_size = intel_fbc_calculate_cfb_size(dev_priv, cache); 870c0e85e96SFrançois Tigeot 871c0e85e96SFrançois Tigeot params->fb.ggtt_offset = cache->fb.ilk_ggtt_offset; 872c0e85e96SFrançois Tigeot } 873c0e85e96SFrançois Tigeot 874c0e85e96SFrançois Tigeot static bool intel_fbc_reg_params_equal(struct intel_fbc_reg_params *params1, 875c0e85e96SFrançois Tigeot struct intel_fbc_reg_params *params2) 876c0e85e96SFrançois Tigeot { 877c0e85e96SFrançois Tigeot /* We can use this since intel_fbc_get_reg_params() does a memset. */ 878c0e85e96SFrançois Tigeot return memcmp(params1, params2, sizeof(*params1)) == 0; 879c0e85e96SFrançois Tigeot } 880c0e85e96SFrançois Tigeot 8811487f786SFrançois Tigeot void intel_fbc_pre_update(struct intel_crtc *crtc, 8821487f786SFrançois Tigeot struct intel_crtc_state *crtc_state, 8831487f786SFrançois Tigeot struct intel_plane_state *plane_state) 884c0e85e96SFrançois Tigeot { 885303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 886c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 887c0e85e96SFrançois Tigeot 888c0e85e96SFrançois Tigeot if (!fbc_supported(dev_priv)) 889c0e85e96SFrançois Tigeot return; 890c0e85e96SFrançois Tigeot 891c0e85e96SFrançois Tigeot mutex_lock(&fbc->lock); 892c0e85e96SFrançois Tigeot 8931487f786SFrançois Tigeot if (!multiple_pipes_ok(crtc, plane_state)) { 894c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "more than one pipe active"; 895c0e85e96SFrançois Tigeot goto deactivate; 896c0e85e96SFrançois Tigeot } 897c0e85e96SFrançois Tigeot 898c0e85e96SFrançois Tigeot if (!fbc->enabled || fbc->crtc != crtc) 899c0e85e96SFrançois Tigeot goto unlock; 900c0e85e96SFrançois Tigeot 9011487f786SFrançois Tigeot intel_fbc_update_state_cache(crtc, crtc_state, plane_state); 902c0e85e96SFrançois Tigeot 903c0e85e96SFrançois Tigeot deactivate: 904c0e85e96SFrançois Tigeot intel_fbc_deactivate(dev_priv); 905c0e85e96SFrançois Tigeot unlock: 906c0e85e96SFrançois Tigeot mutex_unlock(&fbc->lock); 907c0e85e96SFrançois Tigeot } 908c0e85e96SFrançois Tigeot 909c0e85e96SFrançois Tigeot static void __intel_fbc_post_update(struct intel_crtc *crtc) 910c0e85e96SFrançois Tigeot { 911303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 912c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 913c0e85e96SFrançois Tigeot struct intel_fbc_reg_params old_params; 914c0e85e96SFrançois Tigeot 915c0e85e96SFrançois Tigeot WARN_ON(!mutex_is_locked(&fbc->lock)); 916c0e85e96SFrançois Tigeot 917c0e85e96SFrançois Tigeot if (!fbc->enabled || fbc->crtc != crtc) 918c0e85e96SFrançois Tigeot return; 919c0e85e96SFrançois Tigeot 920c0e85e96SFrançois Tigeot if (!intel_fbc_can_activate(crtc)) { 921c0e85e96SFrançois Tigeot WARN_ON(fbc->active); 922c0e85e96SFrançois Tigeot return; 923c0e85e96SFrançois Tigeot } 924c0e85e96SFrançois Tigeot 925c0e85e96SFrançois Tigeot old_params = fbc->params; 926c0e85e96SFrançois Tigeot intel_fbc_get_reg_params(crtc, &fbc->params); 927c0e85e96SFrançois Tigeot 9282c9916cdSFrançois Tigeot /* If the scanout has not changed, don't modify the FBC settings. 9292c9916cdSFrançois Tigeot * Note that we make the fundamental assumption that the fb->obj 9302c9916cdSFrançois Tigeot * cannot be unpinned (and have its GTT offset and fence revoked) 9312c9916cdSFrançois Tigeot * without first being decoupled from the scanout and FBC disabled. 9322c9916cdSFrançois Tigeot */ 933c0e85e96SFrançois Tigeot if (fbc->active && 934c0e85e96SFrançois Tigeot intel_fbc_reg_params_equal(&old_params, &fbc->params)) 9352c9916cdSFrançois Tigeot return; 9362c9916cdSFrançois Tigeot 937c0e85e96SFrançois Tigeot intel_fbc_deactivate(dev_priv); 938aee94f86SFrançois Tigeot intel_fbc_schedule_activation(crtc); 939c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "FBC enabled (active or scheduled)"; 940a05eeebfSFrançois Tigeot } 941a05eeebfSFrançois Tigeot 942c0e85e96SFrançois Tigeot void intel_fbc_post_update(struct intel_crtc *crtc) 943a05eeebfSFrançois Tigeot { 944303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 945c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 946aee94f86SFrançois Tigeot 947352ff8bdSFrançois Tigeot if (!fbc_supported(dev_priv)) 948a05eeebfSFrançois Tigeot return; 949a05eeebfSFrançois Tigeot 950c0e85e96SFrançois Tigeot mutex_lock(&fbc->lock); 951c0e85e96SFrançois Tigeot __intel_fbc_post_update(crtc); 952c0e85e96SFrançois Tigeot mutex_unlock(&fbc->lock); 953c0e85e96SFrançois Tigeot } 954c0e85e96SFrançois Tigeot 955c0e85e96SFrançois Tigeot static unsigned int intel_fbc_get_frontbuffer_bit(struct intel_fbc *fbc) 956c0e85e96SFrançois Tigeot { 957c0e85e96SFrançois Tigeot if (fbc->enabled) 958c0e85e96SFrançois Tigeot return to_intel_plane(fbc->crtc->base.primary)->frontbuffer_bit; 959c0e85e96SFrançois Tigeot else 960c0e85e96SFrançois Tigeot return fbc->possible_framebuffer_bits; 9612c9916cdSFrançois Tigeot } 9622c9916cdSFrançois Tigeot 963477eb7f9SFrançois Tigeot void intel_fbc_invalidate(struct drm_i915_private *dev_priv, 964477eb7f9SFrançois Tigeot unsigned int frontbuffer_bits, 965477eb7f9SFrançois Tigeot enum fb_op_origin origin) 966477eb7f9SFrançois Tigeot { 967c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 968477eb7f9SFrançois Tigeot 969352ff8bdSFrançois Tigeot if (!fbc_supported(dev_priv)) 970a05eeebfSFrançois Tigeot return; 971a05eeebfSFrançois Tigeot 972c0e85e96SFrançois Tigeot if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP) 973477eb7f9SFrançois Tigeot return; 974477eb7f9SFrançois Tigeot 975c0e85e96SFrançois Tigeot mutex_lock(&fbc->lock); 976a05eeebfSFrançois Tigeot 977c0e85e96SFrançois Tigeot fbc->busy_bits |= intel_fbc_get_frontbuffer_bit(fbc) & frontbuffer_bits; 978477eb7f9SFrançois Tigeot 979c0e85e96SFrançois Tigeot if (fbc->enabled && fbc->busy_bits) 980c0e85e96SFrançois Tigeot intel_fbc_deactivate(dev_priv); 981477eb7f9SFrançois Tigeot 982c0e85e96SFrançois Tigeot mutex_unlock(&fbc->lock); 983477eb7f9SFrançois Tigeot } 984477eb7f9SFrançois Tigeot 985477eb7f9SFrançois Tigeot void intel_fbc_flush(struct drm_i915_private *dev_priv, 986a05eeebfSFrançois Tigeot unsigned int frontbuffer_bits, enum fb_op_origin origin) 987477eb7f9SFrançois Tigeot { 988c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 989c0e85e96SFrançois Tigeot 990352ff8bdSFrançois Tigeot if (!fbc_supported(dev_priv)) 991477eb7f9SFrançois Tigeot return; 992477eb7f9SFrançois Tigeot 993c0e85e96SFrançois Tigeot mutex_lock(&fbc->lock); 994a05eeebfSFrançois Tigeot 995c0e85e96SFrançois Tigeot fbc->busy_bits &= ~frontbuffer_bits; 996477eb7f9SFrançois Tigeot 9971487f786SFrançois Tigeot if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP) 9981487f786SFrançois Tigeot goto out; 9991487f786SFrançois Tigeot 1000c0e85e96SFrançois Tigeot if (!fbc->busy_bits && fbc->enabled && 1001c0e85e96SFrançois Tigeot (frontbuffer_bits & intel_fbc_get_frontbuffer_bit(fbc))) { 1002c0e85e96SFrançois Tigeot if (fbc->active) 1003aee94f86SFrançois Tigeot intel_fbc_recompress(dev_priv); 1004c0e85e96SFrançois Tigeot else 1005c0e85e96SFrançois Tigeot __intel_fbc_post_update(fbc->crtc); 1006c0e85e96SFrançois Tigeot } 1007c0e85e96SFrançois Tigeot 10081487f786SFrançois Tigeot out: 1009c0e85e96SFrançois Tigeot mutex_unlock(&fbc->lock); 1010c0e85e96SFrançois Tigeot } 1011c0e85e96SFrançois Tigeot 1012c0e85e96SFrançois Tigeot /** 1013c0e85e96SFrançois Tigeot * intel_fbc_choose_crtc - select a CRTC to enable FBC on 1014c0e85e96SFrançois Tigeot * @dev_priv: i915 device instance 1015c0e85e96SFrançois Tigeot * @state: the atomic state structure 1016c0e85e96SFrançois Tigeot * 1017c0e85e96SFrançois Tigeot * This function looks at the proposed state for CRTCs and planes, then chooses 1018c0e85e96SFrançois Tigeot * which pipe is going to have FBC by setting intel_crtc_state->enable_fbc to 1019c0e85e96SFrançois Tigeot * true. 1020c0e85e96SFrançois Tigeot * 1021c0e85e96SFrançois Tigeot * Later, intel_fbc_enable is going to look for state->enable_fbc and then maybe 1022c0e85e96SFrançois Tigeot * enable FBC for the chosen CRTC. If it does, it will set dev_priv->fbc.crtc. 1023c0e85e96SFrançois Tigeot */ 1024c0e85e96SFrançois Tigeot void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, 1025c0e85e96SFrançois Tigeot struct drm_atomic_state *state) 1026c0e85e96SFrançois Tigeot { 1027c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 1028c0e85e96SFrançois Tigeot struct drm_crtc *crtc; 1029c0e85e96SFrançois Tigeot struct drm_crtc_state *crtc_state; 1030c0e85e96SFrançois Tigeot struct drm_plane *plane; 1031c0e85e96SFrançois Tigeot struct drm_plane_state *plane_state; 1032c0e85e96SFrançois Tigeot bool fbc_crtc_present = false; 1033c0e85e96SFrançois Tigeot int i, j; 1034c0e85e96SFrançois Tigeot 1035c0e85e96SFrançois Tigeot mutex_lock(&fbc->lock); 1036c0e85e96SFrançois Tigeot 1037c0e85e96SFrançois Tigeot for_each_crtc_in_state(state, crtc, crtc_state, i) { 1038c0e85e96SFrançois Tigeot if (fbc->crtc == to_intel_crtc(crtc)) { 1039c0e85e96SFrançois Tigeot fbc_crtc_present = true; 1040c0e85e96SFrançois Tigeot break; 1041c0e85e96SFrançois Tigeot } 1042c0e85e96SFrançois Tigeot } 1043c0e85e96SFrançois Tigeot /* This atomic commit doesn't involve the CRTC currently tied to FBC. */ 1044c0e85e96SFrançois Tigeot if (!fbc_crtc_present && fbc->crtc != NULL) 1045c0e85e96SFrançois Tigeot goto out; 1046c0e85e96SFrançois Tigeot 1047c0e85e96SFrançois Tigeot /* Simply choose the first CRTC that is compatible and has a visible 1048c0e85e96SFrançois Tigeot * plane. We could go for fancier schemes such as checking the plane 1049c0e85e96SFrançois Tigeot * size, but this would just affect the few platforms that don't tie FBC 1050c0e85e96SFrançois Tigeot * to pipe or plane A. */ 1051c0e85e96SFrançois Tigeot for_each_plane_in_state(state, plane, plane_state, i) { 1052c0e85e96SFrançois Tigeot struct intel_plane_state *intel_plane_state = 1053c0e85e96SFrançois Tigeot to_intel_plane_state(plane_state); 1054c0e85e96SFrançois Tigeot 1055c0e85e96SFrançois Tigeot if (!intel_plane_state->visible) 1056c0e85e96SFrançois Tigeot continue; 1057c0e85e96SFrançois Tigeot 1058c0e85e96SFrançois Tigeot for_each_crtc_in_state(state, crtc, crtc_state, j) { 1059c0e85e96SFrançois Tigeot struct intel_crtc_state *intel_crtc_state = 1060c0e85e96SFrançois Tigeot to_intel_crtc_state(crtc_state); 1061c0e85e96SFrançois Tigeot 1062c0e85e96SFrançois Tigeot if (plane_state->crtc != crtc) 1063c0e85e96SFrançois Tigeot continue; 1064c0e85e96SFrançois Tigeot 1065c0e85e96SFrançois Tigeot if (!intel_fbc_can_choose(to_intel_crtc(crtc))) 1066c0e85e96SFrançois Tigeot break; 1067c0e85e96SFrançois Tigeot 1068c0e85e96SFrançois Tigeot intel_crtc_state->enable_fbc = true; 1069c0e85e96SFrançois Tigeot goto out; 1070aee94f86SFrançois Tigeot } 1071a05eeebfSFrançois Tigeot } 1072a05eeebfSFrançois Tigeot 1073c0e85e96SFrançois Tigeot out: 1074c0e85e96SFrançois Tigeot mutex_unlock(&fbc->lock); 1075477eb7f9SFrançois Tigeot } 1076477eb7f9SFrançois Tigeot 10772c9916cdSFrançois Tigeot /** 1078aee94f86SFrançois Tigeot * intel_fbc_enable: tries to enable FBC on the CRTC 1079aee94f86SFrançois Tigeot * @crtc: the CRTC 1080*87df8fc6SFrançois Tigeot * @crtc_state: corresponding &drm_crtc_state for @crtc 1081*87df8fc6SFrançois Tigeot * @plane_state: corresponding &drm_plane_state for the primary plane of @crtc 1082aee94f86SFrançois Tigeot * 1083c0e85e96SFrançois Tigeot * This function checks if the given CRTC was chosen for FBC, then enables it if 1084c0e85e96SFrançois Tigeot * possible. Notice that it doesn't activate FBC. It is valid to call 1085c0e85e96SFrançois Tigeot * intel_fbc_enable multiple times for the same pipe without an 1086c0e85e96SFrançois Tigeot * intel_fbc_disable in the middle, as long as it is deactivated. 1087aee94f86SFrançois Tigeot */ 10881487f786SFrançois Tigeot void intel_fbc_enable(struct intel_crtc *crtc, 10891487f786SFrançois Tigeot struct intel_crtc_state *crtc_state, 10901487f786SFrançois Tigeot struct intel_plane_state *plane_state) 1091aee94f86SFrançois Tigeot { 1092303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 1093c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 1094aee94f86SFrançois Tigeot 1095aee94f86SFrançois Tigeot if (!fbc_supported(dev_priv)) 1096aee94f86SFrançois Tigeot return; 1097aee94f86SFrançois Tigeot 1098c0e85e96SFrançois Tigeot mutex_lock(&fbc->lock); 1099aee94f86SFrançois Tigeot 1100c0e85e96SFrançois Tigeot if (fbc->enabled) { 1101c0e85e96SFrançois Tigeot WARN_ON(fbc->crtc == NULL); 1102c0e85e96SFrançois Tigeot if (fbc->crtc == crtc) { 11031487f786SFrançois Tigeot WARN_ON(!crtc_state->enable_fbc); 1104c0e85e96SFrançois Tigeot WARN_ON(fbc->active); 1105c0e85e96SFrançois Tigeot } 1106aee94f86SFrançois Tigeot goto out; 1107aee94f86SFrançois Tigeot } 1108aee94f86SFrançois Tigeot 11091487f786SFrançois Tigeot if (!crtc_state->enable_fbc) 1110aee94f86SFrançois Tigeot goto out; 1111aee94f86SFrançois Tigeot 1112c0e85e96SFrançois Tigeot WARN_ON(fbc->active); 1113c0e85e96SFrançois Tigeot WARN_ON(fbc->crtc != NULL); 1114aee94f86SFrançois Tigeot 11151487f786SFrançois Tigeot intel_fbc_update_state_cache(crtc, crtc_state, plane_state); 1116aee94f86SFrançois Tigeot if (intel_fbc_alloc_cfb(crtc)) { 1117c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "not enough stolen memory"; 1118aee94f86SFrançois Tigeot goto out; 1119aee94f86SFrançois Tigeot } 1120aee94f86SFrançois Tigeot 1121aee94f86SFrançois Tigeot DRM_DEBUG_KMS("Enabling FBC on pipe %c\n", pipe_name(crtc->pipe)); 1122c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "FBC enabled but not active yet\n"; 1123aee94f86SFrançois Tigeot 1124c0e85e96SFrançois Tigeot fbc->enabled = true; 1125c0e85e96SFrançois Tigeot fbc->crtc = crtc; 1126aee94f86SFrançois Tigeot out: 1127c0e85e96SFrançois Tigeot mutex_unlock(&fbc->lock); 1128aee94f86SFrançois Tigeot } 1129aee94f86SFrançois Tigeot 1130aee94f86SFrançois Tigeot /** 1131aee94f86SFrançois Tigeot * __intel_fbc_disable - disable FBC 1132aee94f86SFrançois Tigeot * @dev_priv: i915 device instance 1133aee94f86SFrançois Tigeot * 1134aee94f86SFrançois Tigeot * This is the low level function that actually disables FBC. Callers should 1135aee94f86SFrançois Tigeot * grab the FBC lock. 1136aee94f86SFrançois Tigeot */ 1137aee94f86SFrançois Tigeot static void __intel_fbc_disable(struct drm_i915_private *dev_priv) 1138aee94f86SFrançois Tigeot { 1139c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 1140c0e85e96SFrançois Tigeot struct intel_crtc *crtc = fbc->crtc; 1141aee94f86SFrançois Tigeot 1142c0e85e96SFrançois Tigeot WARN_ON(!mutex_is_locked(&fbc->lock)); 1143c0e85e96SFrançois Tigeot WARN_ON(!fbc->enabled); 1144c0e85e96SFrançois Tigeot WARN_ON(fbc->active); 1145c0e85e96SFrançois Tigeot WARN_ON(crtc->active); 1146aee94f86SFrançois Tigeot 1147aee94f86SFrançois Tigeot DRM_DEBUG_KMS("Disabling FBC on pipe %c\n", pipe_name(crtc->pipe)); 1148aee94f86SFrançois Tigeot 1149aee94f86SFrançois Tigeot __intel_fbc_cleanup_cfb(dev_priv); 1150aee94f86SFrançois Tigeot 1151c0e85e96SFrançois Tigeot fbc->enabled = false; 1152c0e85e96SFrançois Tigeot fbc->crtc = NULL; 1153aee94f86SFrançois Tigeot } 1154aee94f86SFrançois Tigeot 1155aee94f86SFrançois Tigeot /** 1156c0e85e96SFrançois Tigeot * intel_fbc_disable - disable FBC if it's associated with crtc 1157aee94f86SFrançois Tigeot * @crtc: the CRTC 1158aee94f86SFrançois Tigeot * 1159aee94f86SFrançois Tigeot * This function disables FBC if it's associated with the provided CRTC. 1160aee94f86SFrançois Tigeot */ 1161c0e85e96SFrançois Tigeot void intel_fbc_disable(struct intel_crtc *crtc) 1162aee94f86SFrançois Tigeot { 1163303bf270SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 1164c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 1165aee94f86SFrançois Tigeot 1166aee94f86SFrançois Tigeot if (!fbc_supported(dev_priv)) 1167aee94f86SFrançois Tigeot return; 1168aee94f86SFrançois Tigeot 1169c0e85e96SFrançois Tigeot mutex_lock(&fbc->lock); 1170c0e85e96SFrançois Tigeot if (fbc->crtc == crtc) { 1171c0e85e96SFrançois Tigeot WARN_ON(!fbc->enabled); 1172c0e85e96SFrançois Tigeot WARN_ON(fbc->active); 1173aee94f86SFrançois Tigeot __intel_fbc_disable(dev_priv); 1174aee94f86SFrançois Tigeot } 1175c0e85e96SFrançois Tigeot mutex_unlock(&fbc->lock); 1176c0e85e96SFrançois Tigeot 1177c0e85e96SFrançois Tigeot cancel_work_sync(&fbc->work.work); 1178aee94f86SFrançois Tigeot } 1179aee94f86SFrançois Tigeot 1180aee94f86SFrançois Tigeot /** 1181c0e85e96SFrançois Tigeot * intel_fbc_global_disable - globally disable FBC 1182aee94f86SFrançois Tigeot * @dev_priv: i915 device instance 1183aee94f86SFrançois Tigeot * 1184aee94f86SFrançois Tigeot * This function disables FBC regardless of which CRTC is associated with it. 1185aee94f86SFrançois Tigeot */ 1186c0e85e96SFrançois Tigeot void intel_fbc_global_disable(struct drm_i915_private *dev_priv) 1187aee94f86SFrançois Tigeot { 1188c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 1189c0e85e96SFrançois Tigeot 1190aee94f86SFrançois Tigeot if (!fbc_supported(dev_priv)) 1191aee94f86SFrançois Tigeot return; 1192aee94f86SFrançois Tigeot 1193c0e85e96SFrançois Tigeot mutex_lock(&fbc->lock); 1194c0e85e96SFrançois Tigeot if (fbc->enabled) 1195aee94f86SFrançois Tigeot __intel_fbc_disable(dev_priv); 1196c0e85e96SFrançois Tigeot mutex_unlock(&fbc->lock); 1197c0e85e96SFrançois Tigeot 1198c0e85e96SFrançois Tigeot cancel_work_sync(&fbc->work.work); 1199c0e85e96SFrançois Tigeot } 1200c0e85e96SFrançois Tigeot 1201c0e85e96SFrançois Tigeot /** 1202c0e85e96SFrançois Tigeot * intel_fbc_init_pipe_state - initialize FBC's CRTC visibility tracking 1203c0e85e96SFrançois Tigeot * @dev_priv: i915 device instance 1204c0e85e96SFrançois Tigeot * 1205c0e85e96SFrançois Tigeot * The FBC code needs to track CRTC visibility since the older platforms can't 1206c0e85e96SFrançois Tigeot * have FBC enabled while multiple pipes are used. This function does the 1207c0e85e96SFrançois Tigeot * initial setup at driver load to make sure FBC is matching the real hardware. 1208c0e85e96SFrançois Tigeot */ 1209c0e85e96SFrançois Tigeot void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv) 1210c0e85e96SFrançois Tigeot { 1211c0e85e96SFrançois Tigeot struct intel_crtc *crtc; 1212c0e85e96SFrançois Tigeot 1213c0e85e96SFrançois Tigeot /* Don't even bother tracking anything if we don't need. */ 1214c0e85e96SFrançois Tigeot if (!no_fbc_on_multiple_pipes(dev_priv)) 1215c0e85e96SFrançois Tigeot return; 1216c0e85e96SFrançois Tigeot 1217303bf270SFrançois Tigeot for_each_intel_crtc(&dev_priv->drm, crtc) 1218c0e85e96SFrançois Tigeot if (intel_crtc_active(&crtc->base) && 1219c0e85e96SFrançois Tigeot to_intel_plane_state(crtc->base.primary->state)->visible) 1220c0e85e96SFrançois Tigeot dev_priv->fbc.visible_pipes_mask |= (1 << crtc->pipe); 1221aee94f86SFrançois Tigeot } 1222aee94f86SFrançois Tigeot 12231487f786SFrançois Tigeot /* 12241487f786SFrançois Tigeot * The DDX driver changes its behavior depending on the value it reads from 12251487f786SFrançois Tigeot * i915.enable_fbc, so sanitize it by translating the default value into either 12261487f786SFrançois Tigeot * 0 or 1 in order to allow it to know what's going on. 12271487f786SFrançois Tigeot * 12281487f786SFrançois Tigeot * Notice that this is done at driver initialization and we still allow user 12291487f786SFrançois Tigeot * space to change the value during runtime without sanitizing it again. IGT 12301487f786SFrançois Tigeot * relies on being able to change i915.enable_fbc at runtime. 12311487f786SFrançois Tigeot */ 12321487f786SFrançois Tigeot static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv) 12331487f786SFrançois Tigeot { 12341487f786SFrançois Tigeot if (i915.enable_fbc >= 0) 12351487f786SFrançois Tigeot return !!i915.enable_fbc; 12361487f786SFrançois Tigeot 1237bf017597SFrançois Tigeot if (!HAS_FBC(dev_priv)) 1238bf017597SFrançois Tigeot return 0; 1239bf017597SFrançois Tigeot 12401487f786SFrançois Tigeot if (IS_BROADWELL(dev_priv)) 12411487f786SFrançois Tigeot return 1; 12421487f786SFrançois Tigeot 12431487f786SFrançois Tigeot return 0; 12441487f786SFrançois Tigeot } 12451487f786SFrançois Tigeot 1246bf017597SFrançois Tigeot static bool need_fbc_vtd_wa(struct drm_i915_private *dev_priv) 1247bf017597SFrançois Tigeot { 1248bf017597SFrançois Tigeot #ifdef CONFIG_INTEL_IOMMU 1249bf017597SFrançois Tigeot /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */ 1250bf017597SFrançois Tigeot if (intel_iommu_gfx_mapped && 1251bf017597SFrançois Tigeot (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))) { 1252bf017597SFrançois Tigeot DRM_INFO("Disabling framebuffer compression (FBC) to prevent screen flicker with VT-d enabled\n"); 1253bf017597SFrançois Tigeot return true; 1254bf017597SFrançois Tigeot } 1255bf017597SFrançois Tigeot #endif 1256bf017597SFrançois Tigeot 1257bf017597SFrançois Tigeot return false; 1258bf017597SFrançois Tigeot } 1259bf017597SFrançois Tigeot 1260aee94f86SFrançois Tigeot /** 12612c9916cdSFrançois Tigeot * intel_fbc_init - Initialize FBC 12622c9916cdSFrançois Tigeot * @dev_priv: the i915 device 12632c9916cdSFrançois Tigeot * 12642c9916cdSFrançois Tigeot * This function might be called during PM init process. 12652c9916cdSFrançois Tigeot */ 12662c9916cdSFrançois Tigeot void intel_fbc_init(struct drm_i915_private *dev_priv) 12672c9916cdSFrançois Tigeot { 1268c0e85e96SFrançois Tigeot struct intel_fbc *fbc = &dev_priv->fbc; 1269477eb7f9SFrançois Tigeot enum i915_pipe pipe; 1270477eb7f9SFrançois Tigeot 1271c0e85e96SFrançois Tigeot INIT_WORK(&fbc->work.work, intel_fbc_work_fn); 1272c0e85e96SFrançois Tigeot lockinit(&fbc->lock, "i915fl", 0, LK_CANRECURSE); 1273c0e85e96SFrançois Tigeot fbc->enabled = false; 1274c0e85e96SFrançois Tigeot fbc->active = false; 1275c0e85e96SFrançois Tigeot fbc->work.scheduled = false; 1276a05eeebfSFrançois Tigeot 1277bf017597SFrançois Tigeot if (need_fbc_vtd_wa(dev_priv)) 1278bf017597SFrançois Tigeot mkwrite_device_info(dev_priv)->has_fbc = false; 1279bf017597SFrançois Tigeot 12801487f786SFrançois Tigeot i915.enable_fbc = intel_sanitize_fbc_option(dev_priv); 12811487f786SFrançois Tigeot DRM_DEBUG_KMS("Sanitized enable_fbc value: %d\n", i915.enable_fbc); 12821487f786SFrançois Tigeot 12832c9916cdSFrançois Tigeot if (!HAS_FBC(dev_priv)) { 1284c0e85e96SFrançois Tigeot fbc->no_fbc_reason = "unsupported by this chipset"; 12852c9916cdSFrançois Tigeot return; 12862c9916cdSFrançois Tigeot } 12872c9916cdSFrançois Tigeot 1288477eb7f9SFrançois Tigeot for_each_pipe(dev_priv, pipe) { 1289c0e85e96SFrançois Tigeot fbc->possible_framebuffer_bits |= 1290477eb7f9SFrançois Tigeot INTEL_FRONTBUFFER_PRIMARY(pipe); 1291477eb7f9SFrançois Tigeot 1292aee94f86SFrançois Tigeot if (fbc_on_pipe_a_only(dev_priv)) 1293477eb7f9SFrançois Tigeot break; 1294477eb7f9SFrançois Tigeot } 1295477eb7f9SFrançois Tigeot 12962c9916cdSFrançois Tigeot /* This value was pulled out of someone's hat */ 1297c0e85e96SFrançois Tigeot if (INTEL_INFO(dev_priv)->gen <= 4 && !IS_GM45(dev_priv)) 12982c9916cdSFrançois Tigeot I915_WRITE(FBC_CONTROL, 500 << FBC_CTL_INTERVAL_SHIFT); 12992c9916cdSFrançois Tigeot 1300aee94f86SFrançois Tigeot /* We still don't have any sort of hardware state readout for FBC, so 1301aee94f86SFrançois Tigeot * deactivate it in case the BIOS activated it to make sure software 1302aee94f86SFrançois Tigeot * matches the hardware state. */ 1303c0e85e96SFrançois Tigeot if (intel_fbc_hw_is_active(dev_priv)) 1304c0e85e96SFrançois Tigeot intel_fbc_hw_deactivate(dev_priv); 13052c9916cdSFrançois Tigeot } 1306