linux/drivers/gpu/drm/i915/intel_psr.c
/**
 * intel_psr_flush - Flush PSR
 * @dev_priv: i915 device
 * @frontbuffer_bits: frontbuffer plane tracking bits
 * @origin: which operation caused the flush
 *
 * Since the hardware frontbuffer tracking has gaps we need to integrate
 * with the software frontbuffer tracking. This function gets called every
 * time frontbuffer rendering has completed and flushed out to memory. PSR
 * can be enabled again if no other frontbuffer relevant to PSR is dirty.
 *
 * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits.
 */
Flush PSR
@dev_priv: i915 device
@frontbuffer_bits: frontbuffer plane tracking bits
@origin: which operation caused the flush

Since the hardware frontbuffer tracking has gaps we need to integrate
with the software frontbuffer tracking. This function gets called every
time frontbuffer rendering has completed and flushed out to memory. PSR
can be enabled again if no other frontbuffer relevant to PSR is dirty.

Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits.
Flush PSR @dev_priv : i915 device @frontbuffer_bits : frontbuffer plane tracking bits @origin : which operation caused the flush Since the hardware frontbuffer tracking has gaps we need to integrate with the software frontbuffer tracking . This function gets called every time frontbuffer rendering has completed and flushed out to memory . PSR can be enabled again if no other frontbuffer relevant to PSR is dirty . Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits .
void intel_psr_flush(struct drm_i915_private *dev_priv,
		     unsigned frontbuffer_bits, enum fb_op_origin origin)
{
	struct drm_crtc *crtc;
	enum pipe pipe;
	if (!CAN_PSR(dev_priv))
		return;
	if (origin == ORIGIN_FLIP)
		return;
	mutex_lock(&dev_priv->psr.lock);
	if (!dev_priv->psr.enabled) {
		mutex_unlock(&dev_priv->psr.lock);
		return;
	}
	crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
	pipe = to_intel_crtc(crtc)->pipe;
	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
	dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits;
	if (frontbuffer_bits) {
		if (dev_priv->psr.psr2_enabled) {
			intel_psr_exit(dev_priv);
		} else {
			I915_WRITE(CURSURFLIVE(pipe), 0);
		}
	}
	if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits)
		schedule_work(&dev_priv->psr.work);
	mutex_unlock(&dev_priv->psr.lock);
}
void intel_psr_flush ( struct drm_i915_private * dev_priv , unsigned frontbuffer_bits , enum fb_op_origin origin ) { struct drm_crtc * crtc ; enum pipe pipe ; if ( ! CAN_PSR ( dev_priv ) ) return ; if ( origin == ORIGIN_FLIP ) return ; mutex_lock ( & dev_priv -> psr . lock ) ; if ( ! dev_priv -> psr . enabled ) { mutex_unlock ( & dev_priv -> psr . lock ) ; return ; } crtc = dp_to_dig_port ( dev_priv -> psr . enabled ) -> base . base . crtc ; pipe = to_intel_crtc ( crtc ) -> pipe ; frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK ( pipe ) ; dev_priv -> psr . busy_frontbuffer_bits &= ~ frontbuffer_bits ; if ( frontbuffer_bits ) { if ( dev_priv -> psr . psr2_enabled ) { intel_psr_exit ( dev_priv ) ; } else { I915_WRITE ( CURSURFLIVE ( pipe ) , 0 ) ; } } if ( ! dev_priv -> psr . active && ! dev_priv -> psr . busy_frontbuffer_bits ) schedule_work ( & dev_priv -> psr . work ) ; mutex_unlock ( & dev_priv -> psr . lock ) ; }
intel_psr_flush - Flush PSR
 @dev_priv: i915 device
 @frontbuffer_bits: frontbuffer plane tracking bits
 @origin: which operation caused the flush
intel_psr_flush - Flush PSR @dev_priv : i915 device @frontbuffer_bits : frontbuffer plane tracking bits @origin : which operation caused the flush
/* By definition flush = invalidate + flush */ /*
			 * Display WA #0884: all
			 * This documented WA for bxt can be safely applied
			 * broadly so we can force HW tracking to exit PSR
			 * instead of disabling and re-enabling.
			 * Workaround tells us to write 0 to CUR_SURFLIVE_A,
			 * but it makes more sense write to the current active
			 * pipe.
			 */