1*2c9916cdSFrançois Tigeot /* 2*2c9916cdSFrançois Tigeot * Copyright © 2014 Intel Corporation 3*2c9916cdSFrançois Tigeot * 4*2c9916cdSFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 5*2c9916cdSFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 6*2c9916cdSFrançois Tigeot * to deal in the Software without restriction, including without limitation 7*2c9916cdSFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8*2c9916cdSFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 9*2c9916cdSFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 10*2c9916cdSFrançois Tigeot * 11*2c9916cdSFrançois Tigeot * The above copyright notice and this permission notice (including the next 12*2c9916cdSFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the 13*2c9916cdSFrançois Tigeot * Software. 14*2c9916cdSFrançois Tigeot * 15*2c9916cdSFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16*2c9916cdSFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17*2c9916cdSFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18*2c9916cdSFrançois Tigeot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19*2c9916cdSFrançois Tigeot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20*2c9916cdSFrançois Tigeot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21*2c9916cdSFrançois Tigeot * DEALINGS IN THE SOFTWARE. 22*2c9916cdSFrançois Tigeot * 23*2c9916cdSFrançois Tigeot * Authors: 24*2c9916cdSFrançois Tigeot * Daniel Vetter <daniel.vetter@ffwll.ch> 25*2c9916cdSFrançois Tigeot */ 26*2c9916cdSFrançois Tigeot 27*2c9916cdSFrançois Tigeot /** 28*2c9916cdSFrançois Tigeot * DOC: frontbuffer tracking 29*2c9916cdSFrançois Tigeot * 30*2c9916cdSFrançois Tigeot * Many features require us to track changes to the currently active 31*2c9916cdSFrançois Tigeot * frontbuffer, especially rendering targeted at the frontbuffer. 32*2c9916cdSFrançois Tigeot * 33*2c9916cdSFrançois Tigeot * To be able to do so GEM tracks frontbuffers using a bitmask for all possible 34*2c9916cdSFrançois Tigeot * frontbuffer slots through i915_gem_track_fb(). The function in this file are 35*2c9916cdSFrançois Tigeot * then called when the contents of the frontbuffer are invalidated, when 36*2c9916cdSFrançois Tigeot * frontbuffer rendering has stopped again to flush out all the changes and when 37*2c9916cdSFrançois Tigeot * the frontbuffer is exchanged with a flip. Subsystems interested in 38*2c9916cdSFrançois Tigeot * frontbuffer changes (e.g. PSR, FBC, DRRS) should directly put their callbacks 39*2c9916cdSFrançois Tigeot * into the relevant places and filter for the frontbuffer slots that they are 40*2c9916cdSFrançois Tigeot * interested int. 41*2c9916cdSFrançois Tigeot * 42*2c9916cdSFrançois Tigeot * On a high level there are two types of powersaving features. The first one 43*2c9916cdSFrançois Tigeot * work like a special cache (FBC and PSR) and are interested when they should 44*2c9916cdSFrançois Tigeot * stop caching and when to restart caching. This is done by placing callbacks 45*2c9916cdSFrançois Tigeot * into the invalidate and the flush functions: At invalidate the caching must 46*2c9916cdSFrançois Tigeot * be stopped and at flush time it can be restarted. And maybe they need to know 47*2c9916cdSFrançois Tigeot * when the frontbuffer changes (e.g. when the hw doesn't initiate an invalidate 48*2c9916cdSFrançois Tigeot * and flush on its own) which can be achieved with placing callbacks into the 49*2c9916cdSFrançois Tigeot * flip functions. 50*2c9916cdSFrançois Tigeot * 51*2c9916cdSFrançois Tigeot * The other type of display power saving feature only cares about busyness 52*2c9916cdSFrançois Tigeot * (e.g. DRRS). In that case all three (invalidate, flush and flip) indicate 53*2c9916cdSFrançois Tigeot * busyness. There is no direct way to detect idleness. Instead an idle timer 54*2c9916cdSFrançois Tigeot * work delayed work should be started from the flush and flip functions and 55*2c9916cdSFrançois Tigeot * cancelled as soon as busyness is detected. 56*2c9916cdSFrançois Tigeot * 57*2c9916cdSFrançois Tigeot * Note that there's also an older frontbuffer activity tracking scheme which 58*2c9916cdSFrançois Tigeot * just tracks general activity. This is done by the various mark_busy and 59*2c9916cdSFrançois Tigeot * mark_idle functions. For display power management features using these 60*2c9916cdSFrançois Tigeot * functions is deprecated and should be avoided. 61*2c9916cdSFrançois Tigeot */ 62*2c9916cdSFrançois Tigeot 63*2c9916cdSFrançois Tigeot #include <drm/drmP.h> 64*2c9916cdSFrançois Tigeot 65*2c9916cdSFrançois Tigeot #include "intel_drv.h" 66*2c9916cdSFrançois Tigeot #include "i915_drv.h" 67*2c9916cdSFrançois Tigeot 68*2c9916cdSFrançois Tigeot static void intel_increase_pllclock(struct drm_device *dev, 69*2c9916cdSFrançois Tigeot enum i915_pipe pipe) 70*2c9916cdSFrançois Tigeot { 71*2c9916cdSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 72*2c9916cdSFrançois Tigeot int dpll_reg = DPLL(pipe); 73*2c9916cdSFrançois Tigeot int dpll; 74*2c9916cdSFrançois Tigeot 75*2c9916cdSFrançois Tigeot if (!HAS_GMCH_DISPLAY(dev)) 76*2c9916cdSFrançois Tigeot return; 77*2c9916cdSFrançois Tigeot 78*2c9916cdSFrançois Tigeot if (!dev_priv->lvds_downclock_avail) 79*2c9916cdSFrançois Tigeot return; 80*2c9916cdSFrançois Tigeot 81*2c9916cdSFrançois Tigeot dpll = I915_READ(dpll_reg); 82*2c9916cdSFrançois Tigeot if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) { 83*2c9916cdSFrançois Tigeot DRM_DEBUG_DRIVER("upclocking LVDS\n"); 84*2c9916cdSFrançois Tigeot 85*2c9916cdSFrançois Tigeot assert_panel_unlocked(dev_priv, pipe); 86*2c9916cdSFrançois Tigeot 87*2c9916cdSFrançois Tigeot dpll &= ~DISPLAY_RATE_SELECT_FPA1; 88*2c9916cdSFrançois Tigeot I915_WRITE(dpll_reg, dpll); 89*2c9916cdSFrançois Tigeot intel_wait_for_vblank(dev, pipe); 90*2c9916cdSFrançois Tigeot 91*2c9916cdSFrançois Tigeot dpll = I915_READ(dpll_reg); 92*2c9916cdSFrançois Tigeot if (dpll & DISPLAY_RATE_SELECT_FPA1) 93*2c9916cdSFrançois Tigeot DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); 94*2c9916cdSFrançois Tigeot } 95*2c9916cdSFrançois Tigeot } 96*2c9916cdSFrançois Tigeot 97*2c9916cdSFrançois Tigeot /** 98*2c9916cdSFrançois Tigeot * intel_mark_fb_busy - mark given planes as busy 99*2c9916cdSFrançois Tigeot * @dev: DRM device 100*2c9916cdSFrançois Tigeot * @frontbuffer_bits: bits for the affected planes 101*2c9916cdSFrançois Tigeot * @ring: optional ring for asynchronous commands 102*2c9916cdSFrançois Tigeot * 103*2c9916cdSFrançois Tigeot * This function gets called every time the screen contents change. It can be 104*2c9916cdSFrançois Tigeot * used to keep e.g. the update rate at the nominal refresh rate with DRRS. 105*2c9916cdSFrançois Tigeot */ 106*2c9916cdSFrançois Tigeot static void intel_mark_fb_busy(struct drm_device *dev, 107*2c9916cdSFrançois Tigeot unsigned frontbuffer_bits, 108*2c9916cdSFrançois Tigeot struct intel_engine_cs *ring) 109*2c9916cdSFrançois Tigeot { 110*2c9916cdSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 111*2c9916cdSFrançois Tigeot enum i915_pipe pipe; 112*2c9916cdSFrançois Tigeot 113*2c9916cdSFrançois Tigeot if (!i915.powersave) 114*2c9916cdSFrançois Tigeot return; 115*2c9916cdSFrançois Tigeot 116*2c9916cdSFrançois Tigeot for_each_pipe(dev_priv, pipe) { 117*2c9916cdSFrançois Tigeot if (!(frontbuffer_bits & INTEL_FRONTBUFFER_ALL_MASK(pipe))) 118*2c9916cdSFrançois Tigeot continue; 119*2c9916cdSFrançois Tigeot 120*2c9916cdSFrançois Tigeot intel_increase_pllclock(dev, pipe); 121*2c9916cdSFrançois Tigeot if (ring && intel_fbc_enabled(dev)) 122*2c9916cdSFrançois Tigeot ring->fbc_dirty = true; 123*2c9916cdSFrançois Tigeot } 124*2c9916cdSFrançois Tigeot } 125*2c9916cdSFrançois Tigeot 126*2c9916cdSFrançois Tigeot /** 127*2c9916cdSFrançois Tigeot * intel_fb_obj_invalidate - invalidate frontbuffer object 128*2c9916cdSFrançois Tigeot * @obj: GEM object to invalidate 129*2c9916cdSFrançois Tigeot * @ring: set for asynchronous rendering 130*2c9916cdSFrançois Tigeot * 131*2c9916cdSFrançois Tigeot * This function gets called every time rendering on the given object starts and 132*2c9916cdSFrançois Tigeot * frontbuffer caching (fbc, low refresh rate for DRRS, panel self refresh) must 133*2c9916cdSFrançois Tigeot * be invalidated. If @ring is non-NULL any subsequent invalidation will be delayed 134*2c9916cdSFrançois Tigeot * until the rendering completes or a flip on this frontbuffer plane is 135*2c9916cdSFrançois Tigeot * scheduled. 136*2c9916cdSFrançois Tigeot */ 137*2c9916cdSFrançois Tigeot void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, 138*2c9916cdSFrançois Tigeot struct intel_engine_cs *ring) 139*2c9916cdSFrançois Tigeot { 140*2c9916cdSFrançois Tigeot struct drm_device *dev = obj->base.dev; 141*2c9916cdSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 142*2c9916cdSFrançois Tigeot 143*2c9916cdSFrançois Tigeot WARN_ON(!mutex_is_locked(&dev->struct_mutex)); 144*2c9916cdSFrançois Tigeot 145*2c9916cdSFrançois Tigeot if (!obj->frontbuffer_bits) 146*2c9916cdSFrançois Tigeot return; 147*2c9916cdSFrançois Tigeot 148*2c9916cdSFrançois Tigeot if (ring) { 149*2c9916cdSFrançois Tigeot mutex_lock(&dev_priv->fb_tracking.lock); 150*2c9916cdSFrançois Tigeot dev_priv->fb_tracking.busy_bits 151*2c9916cdSFrançois Tigeot |= obj->frontbuffer_bits; 152*2c9916cdSFrançois Tigeot dev_priv->fb_tracking.flip_bits 153*2c9916cdSFrançois Tigeot &= ~obj->frontbuffer_bits; 154*2c9916cdSFrançois Tigeot mutex_unlock(&dev_priv->fb_tracking.lock); 155*2c9916cdSFrançois Tigeot } 156*2c9916cdSFrançois Tigeot 157*2c9916cdSFrançois Tigeot intel_mark_fb_busy(dev, obj->frontbuffer_bits, ring); 158*2c9916cdSFrançois Tigeot 159*2c9916cdSFrançois Tigeot intel_psr_invalidate(dev, obj->frontbuffer_bits); 160*2c9916cdSFrançois Tigeot intel_edp_drrs_invalidate(dev, obj->frontbuffer_bits); 161*2c9916cdSFrançois Tigeot } 162*2c9916cdSFrançois Tigeot 163*2c9916cdSFrançois Tigeot /** 164*2c9916cdSFrançois Tigeot * intel_frontbuffer_flush - flush frontbuffer 165*2c9916cdSFrançois Tigeot * @dev: DRM device 166*2c9916cdSFrançois Tigeot * @frontbuffer_bits: frontbuffer plane tracking bits 167*2c9916cdSFrançois Tigeot * 168*2c9916cdSFrançois Tigeot * This function gets called every time rendering on the given planes has 169*2c9916cdSFrançois Tigeot * completed and frontbuffer caching can be started again. Flushes will get 170*2c9916cdSFrançois Tigeot * delayed if they're blocked by some outstanding asynchronous rendering. 171*2c9916cdSFrançois Tigeot * 172*2c9916cdSFrançois Tigeot * Can be called without any locks held. 173*2c9916cdSFrançois Tigeot */ 174*2c9916cdSFrançois Tigeot void intel_frontbuffer_flush(struct drm_device *dev, 175*2c9916cdSFrançois Tigeot unsigned frontbuffer_bits) 176*2c9916cdSFrançois Tigeot { 177*2c9916cdSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 178*2c9916cdSFrançois Tigeot 179*2c9916cdSFrançois Tigeot /* Delay flushing when rings are still busy.*/ 180*2c9916cdSFrançois Tigeot mutex_lock(&dev_priv->fb_tracking.lock); 181*2c9916cdSFrançois Tigeot frontbuffer_bits &= ~dev_priv->fb_tracking.busy_bits; 182*2c9916cdSFrançois Tigeot mutex_unlock(&dev_priv->fb_tracking.lock); 183*2c9916cdSFrançois Tigeot 184*2c9916cdSFrançois Tigeot intel_mark_fb_busy(dev, frontbuffer_bits, NULL); 185*2c9916cdSFrançois Tigeot 186*2c9916cdSFrançois Tigeot intel_edp_drrs_flush(dev, frontbuffer_bits); 187*2c9916cdSFrançois Tigeot intel_psr_flush(dev, frontbuffer_bits); 188*2c9916cdSFrançois Tigeot 189*2c9916cdSFrançois Tigeot /* 190*2c9916cdSFrançois Tigeot * FIXME: Unconditional fbc flushing here is a rather gross hack and 191*2c9916cdSFrançois Tigeot * needs to be reworked into a proper frontbuffer tracking scheme like 192*2c9916cdSFrançois Tigeot * psr employs. 193*2c9916cdSFrançois Tigeot */ 194*2c9916cdSFrançois Tigeot if (dev_priv->fbc.need_sw_cache_clean) { 195*2c9916cdSFrançois Tigeot dev_priv->fbc.need_sw_cache_clean = false; 196*2c9916cdSFrançois Tigeot bdw_fbc_sw_flush(dev, FBC_REND_CACHE_CLEAN); 197*2c9916cdSFrançois Tigeot } 198*2c9916cdSFrançois Tigeot } 199*2c9916cdSFrançois Tigeot 200*2c9916cdSFrançois Tigeot /** 201*2c9916cdSFrançois Tigeot * intel_fb_obj_flush - flush frontbuffer object 202*2c9916cdSFrançois Tigeot * @obj: GEM object to flush 203*2c9916cdSFrançois Tigeot * @retire: set when retiring asynchronous rendering 204*2c9916cdSFrançois Tigeot * 205*2c9916cdSFrançois Tigeot * This function gets called every time rendering on the given object has 206*2c9916cdSFrançois Tigeot * completed and frontbuffer caching can be started again. If @retire is true 207*2c9916cdSFrançois Tigeot * then any delayed flushes will be unblocked. 208*2c9916cdSFrançois Tigeot */ 209*2c9916cdSFrançois Tigeot void intel_fb_obj_flush(struct drm_i915_gem_object *obj, 210*2c9916cdSFrançois Tigeot bool retire) 211*2c9916cdSFrançois Tigeot { 212*2c9916cdSFrançois Tigeot struct drm_device *dev = obj->base.dev; 213*2c9916cdSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 214*2c9916cdSFrançois Tigeot unsigned frontbuffer_bits; 215*2c9916cdSFrançois Tigeot 216*2c9916cdSFrançois Tigeot WARN_ON(!mutex_is_locked(&dev->struct_mutex)); 217*2c9916cdSFrançois Tigeot 218*2c9916cdSFrançois Tigeot if (!obj->frontbuffer_bits) 219*2c9916cdSFrançois Tigeot return; 220*2c9916cdSFrançois Tigeot 221*2c9916cdSFrançois Tigeot frontbuffer_bits = obj->frontbuffer_bits; 222*2c9916cdSFrançois Tigeot 223*2c9916cdSFrançois Tigeot if (retire) { 224*2c9916cdSFrançois Tigeot mutex_lock(&dev_priv->fb_tracking.lock); 225*2c9916cdSFrançois Tigeot /* Filter out new bits since rendering started. */ 226*2c9916cdSFrançois Tigeot frontbuffer_bits &= dev_priv->fb_tracking.busy_bits; 227*2c9916cdSFrançois Tigeot 228*2c9916cdSFrançois Tigeot dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; 229*2c9916cdSFrançois Tigeot mutex_unlock(&dev_priv->fb_tracking.lock); 230*2c9916cdSFrançois Tigeot } 231*2c9916cdSFrançois Tigeot 232*2c9916cdSFrançois Tigeot intel_frontbuffer_flush(dev, frontbuffer_bits); 233*2c9916cdSFrançois Tigeot } 234*2c9916cdSFrançois Tigeot 235*2c9916cdSFrançois Tigeot /** 236*2c9916cdSFrançois Tigeot * intel_frontbuffer_flip_prepare - prepare asynchronous frontbuffer flip 237*2c9916cdSFrançois Tigeot * @dev: DRM device 238*2c9916cdSFrançois Tigeot * @frontbuffer_bits: frontbuffer plane tracking bits 239*2c9916cdSFrançois Tigeot * 240*2c9916cdSFrançois Tigeot * This function gets called after scheduling a flip on @obj. The actual 241*2c9916cdSFrançois Tigeot * frontbuffer flushing will be delayed until completion is signalled with 242*2c9916cdSFrançois Tigeot * intel_frontbuffer_flip_complete. If an invalidate happens in between this 243*2c9916cdSFrançois Tigeot * flush will be cancelled. 244*2c9916cdSFrançois Tigeot * 245*2c9916cdSFrançois Tigeot * Can be called without any locks held. 246*2c9916cdSFrançois Tigeot */ 247*2c9916cdSFrançois Tigeot void intel_frontbuffer_flip_prepare(struct drm_device *dev, 248*2c9916cdSFrançois Tigeot unsigned frontbuffer_bits) 249*2c9916cdSFrançois Tigeot { 250*2c9916cdSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 251*2c9916cdSFrançois Tigeot 252*2c9916cdSFrançois Tigeot mutex_lock(&dev_priv->fb_tracking.lock); 253*2c9916cdSFrançois Tigeot dev_priv->fb_tracking.flip_bits |= frontbuffer_bits; 254*2c9916cdSFrançois Tigeot /* Remove stale busy bits due to the old buffer. */ 255*2c9916cdSFrançois Tigeot dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; 256*2c9916cdSFrançois Tigeot mutex_unlock(&dev_priv->fb_tracking.lock); 257*2c9916cdSFrançois Tigeot } 258*2c9916cdSFrançois Tigeot 259*2c9916cdSFrançois Tigeot /** 260*2c9916cdSFrançois Tigeot * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flip 261*2c9916cdSFrançois Tigeot * @dev: DRM device 262*2c9916cdSFrançois Tigeot * @frontbuffer_bits: frontbuffer plane tracking bits 263*2c9916cdSFrançois Tigeot * 264*2c9916cdSFrançois Tigeot * This function gets called after the flip has been latched and will complete 265*2c9916cdSFrançois Tigeot * on the next vblank. It will execute the flush if it hasn't been cancelled yet. 266*2c9916cdSFrançois Tigeot * 267*2c9916cdSFrançois Tigeot * Can be called without any locks held. 268*2c9916cdSFrançois Tigeot */ 269*2c9916cdSFrançois Tigeot void intel_frontbuffer_flip_complete(struct drm_device *dev, 270*2c9916cdSFrançois Tigeot unsigned frontbuffer_bits) 271*2c9916cdSFrançois Tigeot { 272*2c9916cdSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 273*2c9916cdSFrançois Tigeot 274*2c9916cdSFrançois Tigeot mutex_lock(&dev_priv->fb_tracking.lock); 275*2c9916cdSFrançois Tigeot /* Mask any cancelled flips. */ 276*2c9916cdSFrançois Tigeot frontbuffer_bits &= dev_priv->fb_tracking.flip_bits; 277*2c9916cdSFrançois Tigeot dev_priv->fb_tracking.flip_bits &= ~frontbuffer_bits; 278*2c9916cdSFrançois Tigeot mutex_unlock(&dev_priv->fb_tracking.lock); 279*2c9916cdSFrançois Tigeot 280*2c9916cdSFrançois Tigeot intel_frontbuffer_flush(dev, frontbuffer_bits); 281*2c9916cdSFrançois Tigeot } 282