xref: /dragonfly/sys/dev/drm/i915/intel_psr.c (revision 3f2dd94a)
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: Panel Self Refresh (PSR/SRD)
262c9916cdSFrançois Tigeot  *
272c9916cdSFrançois Tigeot  * Since Haswell Display controller supports Panel Self-Refresh on display
282c9916cdSFrançois Tigeot  * panels witch have a remote frame buffer (RFB) implemented according to PSR
292c9916cdSFrançois Tigeot  * spec in eDP1.3. PSR feature allows the display to go to lower standby states
302c9916cdSFrançois Tigeot  * when system is idle but display is on as it eliminates display refresh
312c9916cdSFrançois Tigeot  * request to DDR memory completely as long as the frame buffer for that
322c9916cdSFrançois Tigeot  * display is unchanged.
332c9916cdSFrançois Tigeot  *
342c9916cdSFrançois Tigeot  * Panel Self Refresh must be supported by both Hardware (source) and
352c9916cdSFrançois Tigeot  * Panel (sink).
362c9916cdSFrançois Tigeot  *
372c9916cdSFrançois Tigeot  * PSR saves power by caching the framebuffer in the panel RFB, which allows us
382c9916cdSFrançois Tigeot  * to power down the link and memory controller. For DSI panels the same idea
392c9916cdSFrançois Tigeot  * is called "manual mode".
402c9916cdSFrançois Tigeot  *
412c9916cdSFrançois Tigeot  * The implementation uses the hardware-based PSR support which automatically
422c9916cdSFrançois Tigeot  * enters/exits self-refresh mode. The hardware takes care of sending the
432c9916cdSFrançois Tigeot  * required DP aux message and could even retrain the link (that part isn't
442c9916cdSFrançois Tigeot  * enabled yet though). The hardware also keeps track of any frontbuffer
452c9916cdSFrançois Tigeot  * changes to know when to exit self-refresh mode again. Unfortunately that
462c9916cdSFrançois Tigeot  * part doesn't work too well, hence why the i915 PSR support uses the
472c9916cdSFrançois Tigeot  * software frontbuffer tracking to make sure it doesn't miss a screen
482c9916cdSFrançois Tigeot  * update. For this integration intel_psr_invalidate() and intel_psr_flush()
492c9916cdSFrançois Tigeot  * get called by the frontbuffer tracking code. Note that because of locking
502c9916cdSFrançois Tigeot  * issues the self-refresh re-enable code is done from a work queue, which
512c9916cdSFrançois Tigeot  * must be correctly synchronized/cancelled when shutting down the pipe."
522c9916cdSFrançois Tigeot  */
532c9916cdSFrançois Tigeot 
542c9916cdSFrançois Tigeot #include <drm/drmP.h>
552c9916cdSFrançois Tigeot 
562c9916cdSFrançois Tigeot #include "intel_drv.h"
572c9916cdSFrançois Tigeot #include "i915_drv.h"
582c9916cdSFrançois Tigeot 
is_edp_psr(struct intel_dp * intel_dp)592c9916cdSFrançois Tigeot static bool is_edp_psr(struct intel_dp *intel_dp)
602c9916cdSFrançois Tigeot {
61*3f2dd94aSFrançois Tigeot 	if (!intel_dp_is_edp(intel_dp))
62*3f2dd94aSFrançois Tigeot 		return false;
63*3f2dd94aSFrançois Tigeot 
642c9916cdSFrançois Tigeot 	return intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED;
652c9916cdSFrançois Tigeot }
662c9916cdSFrançois Tigeot 
vlv_is_psr_active_on_pipe(struct drm_device * dev,int pipe)672c9916cdSFrançois Tigeot static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe)
682c9916cdSFrançois Tigeot {
69bf017597SFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
702c9916cdSFrançois Tigeot 	uint32_t val;
712c9916cdSFrançois Tigeot 
722c9916cdSFrançois Tigeot 	val = I915_READ(VLV_PSRSTAT(pipe)) &
732c9916cdSFrançois Tigeot 	      VLV_EDP_PSR_CURR_STATE_MASK;
742c9916cdSFrançois Tigeot 	return (val == VLV_EDP_PSR_ACTIVE_NORFB_UP) ||
752c9916cdSFrançois Tigeot 	       (val == VLV_EDP_PSR_ACTIVE_SF_UPDATE);
762c9916cdSFrançois Tigeot }
772c9916cdSFrançois Tigeot 
vlv_psr_setup_vsc(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state)78*3f2dd94aSFrançois Tigeot static void vlv_psr_setup_vsc(struct intel_dp *intel_dp,
79*3f2dd94aSFrançois Tigeot 			      const struct intel_crtc_state *crtc_state)
802c9916cdSFrançois Tigeot {
81*3f2dd94aSFrançois Tigeot 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
82*3f2dd94aSFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
832c9916cdSFrançois Tigeot 	uint32_t val;
842c9916cdSFrançois Tigeot 
852c9916cdSFrançois Tigeot 	/* VLV auto-generate VSC package as per EDP 1.3 spec, Table 3.10 */
86*3f2dd94aSFrançois Tigeot 	val  = I915_READ(VLV_VSCSDP(crtc->pipe));
872c9916cdSFrançois Tigeot 	val &= ~VLV_EDP_PSR_SDP_FREQ_MASK;
882c9916cdSFrançois Tigeot 	val |= VLV_EDP_PSR_SDP_FREQ_EVFRAME;
89*3f2dd94aSFrançois Tigeot 	I915_WRITE(VLV_VSCSDP(crtc->pipe), val);
902c9916cdSFrançois Tigeot }
912c9916cdSFrançois Tigeot 
hsw_psr_setup_vsc(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state)92*3f2dd94aSFrançois Tigeot static void hsw_psr_setup_vsc(struct intel_dp *intel_dp,
93*3f2dd94aSFrançois Tigeot 			      const struct intel_crtc_state *crtc_state)
9419c468b4SFrançois Tigeot {
95a85cb24fSFrançois Tigeot 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
96*3f2dd94aSFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
97*3f2dd94aSFrançois Tigeot 	struct edp_vsc_psr psr_vsc;
9819c468b4SFrançois Tigeot 
99*3f2dd94aSFrançois Tigeot 	if (dev_priv->psr.psr2_support) {
10019c468b4SFrançois Tigeot 		/* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */
10119c468b4SFrançois Tigeot 		memset(&psr_vsc, 0, sizeof(psr_vsc));
10219c468b4SFrançois Tigeot 		psr_vsc.sdp_header.HB0 = 0;
10319c468b4SFrançois Tigeot 		psr_vsc.sdp_header.HB1 = 0x7;
104a85cb24fSFrançois Tigeot 		if (dev_priv->psr.colorimetry_support &&
105a85cb24fSFrançois Tigeot 		    dev_priv->psr.y_cord_support) {
106a85cb24fSFrançois Tigeot 			psr_vsc.sdp_header.HB2 = 0x5;
107a85cb24fSFrançois Tigeot 			psr_vsc.sdp_header.HB3 = 0x13;
108a85cb24fSFrançois Tigeot 		} else if (dev_priv->psr.y_cord_support) {
109a85cb24fSFrançois Tigeot 			psr_vsc.sdp_header.HB2 = 0x4;
110a85cb24fSFrançois Tigeot 			psr_vsc.sdp_header.HB3 = 0xe;
111a85cb24fSFrançois Tigeot 		} else {
11219c468b4SFrançois Tigeot 			psr_vsc.sdp_header.HB2 = 0x3;
113a85cb24fSFrançois Tigeot 			psr_vsc.sdp_header.HB3 = 0xc;
114a85cb24fSFrançois Tigeot 		}
115*3f2dd94aSFrançois Tigeot 	} else {
1162c9916cdSFrançois Tigeot 		/* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */
1172c9916cdSFrançois Tigeot 		memset(&psr_vsc, 0, sizeof(psr_vsc));
1182c9916cdSFrançois Tigeot 		psr_vsc.sdp_header.HB0 = 0;
1192c9916cdSFrançois Tigeot 		psr_vsc.sdp_header.HB1 = 0x7;
1202c9916cdSFrançois Tigeot 		psr_vsc.sdp_header.HB2 = 0x2;
1212c9916cdSFrançois Tigeot 		psr_vsc.sdp_header.HB3 = 0x8;
122*3f2dd94aSFrançois Tigeot 	}
123*3f2dd94aSFrançois Tigeot 
124*3f2dd94aSFrançois Tigeot 	intel_dig_port->write_infoframe(&intel_dig_port->base.base, crtc_state,
125*3f2dd94aSFrançois Tigeot 					DP_SDP_VSC, &psr_vsc, sizeof(psr_vsc));
1262c9916cdSFrançois Tigeot }
1272c9916cdSFrançois Tigeot 
vlv_psr_enable_sink(struct intel_dp * intel_dp)1282c9916cdSFrançois Tigeot static void vlv_psr_enable_sink(struct intel_dp *intel_dp)
1292c9916cdSFrançois Tigeot {
1302c9916cdSFrançois Tigeot 	drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
13119c468b4SFrançois Tigeot 			   DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE);
1322c9916cdSFrançois Tigeot }
1332c9916cdSFrançois Tigeot 
psr_aux_ctl_reg(struct drm_i915_private * dev_priv,enum port port)134aee94f86SFrançois Tigeot static i915_reg_t psr_aux_ctl_reg(struct drm_i915_private *dev_priv,
135aee94f86SFrançois Tigeot 				       enum port port)
136aee94f86SFrançois Tigeot {
137aee94f86SFrançois Tigeot 	if (INTEL_INFO(dev_priv)->gen >= 9)
138aee94f86SFrançois Tigeot 		return DP_AUX_CH_CTL(port);
139aee94f86SFrançois Tigeot 	else
140aee94f86SFrançois Tigeot 		return EDP_PSR_AUX_CTL;
141aee94f86SFrançois Tigeot }
142aee94f86SFrançois Tigeot 
psr_aux_data_reg(struct drm_i915_private * dev_priv,enum port port,int index)143aee94f86SFrançois Tigeot static i915_reg_t psr_aux_data_reg(struct drm_i915_private *dev_priv,
144aee94f86SFrançois Tigeot 					enum port port, int index)
145aee94f86SFrançois Tigeot {
146aee94f86SFrançois Tigeot 	if (INTEL_INFO(dev_priv)->gen >= 9)
147aee94f86SFrançois Tigeot 		return DP_AUX_CH_DATA(port, index);
148aee94f86SFrançois Tigeot 	else
149aee94f86SFrançois Tigeot 		return EDP_PSR_AUX_DATA(index);
150aee94f86SFrançois Tigeot }
151aee94f86SFrançois Tigeot 
hsw_psr_enable_sink(struct intel_dp * intel_dp)1522c9916cdSFrançois Tigeot static void hsw_psr_enable_sink(struct intel_dp *intel_dp)
1532c9916cdSFrançois Tigeot {
1542c9916cdSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
1552c9916cdSFrançois Tigeot 	struct drm_device *dev = dig_port->base.base.dev;
156bf017597SFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
1572c9916cdSFrançois Tigeot 	uint32_t aux_clock_divider;
158aee94f86SFrançois Tigeot 	i915_reg_t aux_ctl_reg;
1592c9916cdSFrançois Tigeot 	static const uint8_t aux_msg[] = {
1602c9916cdSFrançois Tigeot 		[0] = DP_AUX_NATIVE_WRITE << 4,
1612c9916cdSFrançois Tigeot 		[1] = DP_SET_POWER >> 8,
1622c9916cdSFrançois Tigeot 		[2] = DP_SET_POWER & 0xff,
1632c9916cdSFrançois Tigeot 		[3] = 1 - 1,
1642c9916cdSFrançois Tigeot 		[4] = DP_SET_POWER_D0,
1652c9916cdSFrançois Tigeot 	};
166aee94f86SFrançois Tigeot 	enum port port = dig_port->port;
1671487f786SFrançois Tigeot 	u32 aux_ctl;
1682c9916cdSFrançois Tigeot 	int i;
1692c9916cdSFrançois Tigeot 
1702c9916cdSFrançois Tigeot 	BUILD_BUG_ON(sizeof(aux_msg) > 20);
1712c9916cdSFrançois Tigeot 
1722c9916cdSFrançois Tigeot 	aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0);
1732c9916cdSFrançois Tigeot 
17419c468b4SFrançois Tigeot 	/* Enable AUX frame sync at sink */
17519c468b4SFrançois Tigeot 	if (dev_priv->psr.aux_frame_sync)
17619c468b4SFrançois Tigeot 		drm_dp_dpcd_writeb(&intel_dp->aux,
17719c468b4SFrançois Tigeot 				DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF,
17819c468b4SFrançois Tigeot 				DP_AUX_FRAME_SYNC_ENABLE);
179a85cb24fSFrançois Tigeot 	/* Enable ALPM at sink for psr2 */
180a85cb24fSFrançois Tigeot 	if (dev_priv->psr.psr2_support && dev_priv->psr.alpm)
181a85cb24fSFrançois Tigeot 		drm_dp_dpcd_writeb(&intel_dp->aux,
182a85cb24fSFrançois Tigeot 				DP_RECEIVER_ALPM_CONFIG,
183a85cb24fSFrançois Tigeot 				DP_ALPM_ENABLE);
1841487f786SFrançois Tigeot 	if (dev_priv->psr.link_standby)
1851487f786SFrançois Tigeot 		drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
1861487f786SFrançois Tigeot 				   DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE);
1871487f786SFrançois Tigeot 	else
1881487f786SFrançois Tigeot 		drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
1891487f786SFrançois Tigeot 				   DP_PSR_ENABLE);
1901487f786SFrançois Tigeot 
191aee94f86SFrançois Tigeot 	aux_ctl_reg = psr_aux_ctl_reg(dev_priv, port);
1922c9916cdSFrançois Tigeot 
1932c9916cdSFrançois Tigeot 	/* Setup AUX registers */
1942c9916cdSFrançois Tigeot 	for (i = 0; i < sizeof(aux_msg); i += 4)
195aee94f86SFrançois Tigeot 		I915_WRITE(psr_aux_data_reg(dev_priv, port, i >> 2),
1962c9916cdSFrançois Tigeot 			   intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i));
1972c9916cdSFrançois Tigeot 
1981487f786SFrançois Tigeot 	aux_ctl = intel_dp->get_aux_send_ctl(intel_dp, 0, sizeof(aux_msg),
1991487f786SFrançois Tigeot 					     aux_clock_divider);
2001487f786SFrançois Tigeot 	I915_WRITE(aux_ctl_reg, aux_ctl);
2012c9916cdSFrançois Tigeot }
2022c9916cdSFrançois Tigeot 
vlv_psr_enable_source(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state)203*3f2dd94aSFrançois Tigeot static void vlv_psr_enable_source(struct intel_dp *intel_dp,
204*3f2dd94aSFrançois Tigeot 				  const struct intel_crtc_state *crtc_state)
2052c9916cdSFrançois Tigeot {
2062c9916cdSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
207*3f2dd94aSFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
208*3f2dd94aSFrançois Tigeot 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
2092c9916cdSFrançois Tigeot 
210*3f2dd94aSFrançois Tigeot 	/* Transition from PSR_state 0 (disabled) to PSR_state 1 (inactive) */
211*3f2dd94aSFrançois Tigeot 	I915_WRITE(VLV_PSRCTL(crtc->pipe),
2122c9916cdSFrançois Tigeot 		   VLV_EDP_PSR_MODE_SW_TIMER |
2132c9916cdSFrançois Tigeot 		   VLV_EDP_PSR_SRC_TRANSMITTER_STATE |
2142c9916cdSFrançois Tigeot 		   VLV_EDP_PSR_ENABLE);
2152c9916cdSFrançois Tigeot }
2162c9916cdSFrançois Tigeot 
vlv_psr_activate(struct intel_dp * intel_dp)2172c9916cdSFrançois Tigeot static void vlv_psr_activate(struct intel_dp *intel_dp)
2182c9916cdSFrançois Tigeot {
2192c9916cdSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
2202c9916cdSFrançois Tigeot 	struct drm_device *dev = dig_port->base.base.dev;
221bf017597SFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
2222c9916cdSFrançois Tigeot 	struct drm_crtc *crtc = dig_port->base.base.crtc;
2232c9916cdSFrançois Tigeot 	enum i915_pipe pipe = to_intel_crtc(crtc)->pipe;
2242c9916cdSFrançois Tigeot 
225*3f2dd94aSFrançois Tigeot 	/*
226*3f2dd94aSFrançois Tigeot 	 * Let's do the transition from PSR_state 1 (inactive) to
227*3f2dd94aSFrançois Tigeot 	 * PSR_state 2 (transition to active - static frame transmission).
228*3f2dd94aSFrançois Tigeot 	 * Then Hardware is responsible for the transition to
229*3f2dd94aSFrançois Tigeot 	 * PSR_state 3 (active - no Remote Frame Buffer (RFB) update).
2302c9916cdSFrançois Tigeot 	 */
2312c9916cdSFrançois Tigeot 	I915_WRITE(VLV_PSRCTL(pipe), I915_READ(VLV_PSRCTL(pipe)) |
2322c9916cdSFrançois Tigeot 		   VLV_EDP_PSR_ACTIVE_ENTRY);
2332c9916cdSFrançois Tigeot }
2342c9916cdSFrançois Tigeot 
hsw_activate_psr1(struct intel_dp * intel_dp)235*3f2dd94aSFrançois Tigeot static void hsw_activate_psr1(struct intel_dp *intel_dp)
2362c9916cdSFrançois Tigeot {
2372c9916cdSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
2382c9916cdSFrançois Tigeot 	struct drm_device *dev = dig_port->base.base.dev;
239bf017597SFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
24019c468b4SFrançois Tigeot 
2412c9916cdSFrançois Tigeot 	uint32_t max_sleep_time = 0x1f;
2421e12ee3bSFrançois Tigeot 	/*
2431e12ee3bSFrançois Tigeot 	 * Let's respect VBT in case VBT asks a higher idle_frame value.
2441e12ee3bSFrançois Tigeot 	 * Let's use 6 as the minimum to cover all known cases including
2451e12ee3bSFrançois Tigeot 	 * the off-by-one issue that HW has in some cases. Also there are
2461e12ee3bSFrançois Tigeot 	 * cases where sink should be able to train
2471e12ee3bSFrançois Tigeot 	 * with the 5 or 6 idle patterns.
2482c9916cdSFrançois Tigeot 	 */
2491e12ee3bSFrançois Tigeot 	uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
250c62a0e9aSFrançois Tigeot 	uint32_t val = EDP_PSR_ENABLE;
251c62a0e9aSFrançois Tigeot 
252c62a0e9aSFrançois Tigeot 	val |= max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT;
253c62a0e9aSFrançois Tigeot 	val |= idle_frames << EDP_PSR_IDLE_FRAME_SHIFT;
2542c9916cdSFrançois Tigeot 
2551e12ee3bSFrançois Tigeot 	if (IS_HASWELL(dev_priv))
256aee94f86SFrançois Tigeot 		val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
2572c9916cdSFrançois Tigeot 
258c0e85e96SFrançois Tigeot 	if (dev_priv->psr.link_standby)
259c0e85e96SFrançois Tigeot 		val |= EDP_PSR_LINK_STANDBY;
260c0e85e96SFrançois Tigeot 
261c62a0e9aSFrançois Tigeot 	if (dev_priv->vbt.psr.tp1_wakeup_time > 5)
262c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP1_TIME_2500us;
263c62a0e9aSFrançois Tigeot 	else if (dev_priv->vbt.psr.tp1_wakeup_time > 1)
264c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP1_TIME_500us;
265c62a0e9aSFrançois Tigeot 	else if (dev_priv->vbt.psr.tp1_wakeup_time > 0)
266c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP1_TIME_100us;
267c62a0e9aSFrançois Tigeot 	else
268c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP1_TIME_0us;
26919c468b4SFrançois Tigeot 
270c62a0e9aSFrançois Tigeot 	if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
271c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP2_TP3_TIME_2500us;
272c62a0e9aSFrançois Tigeot 	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1)
273c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP2_TP3_TIME_500us;
274c62a0e9aSFrançois Tigeot 	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0)
275c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP2_TP3_TIME_100us;
276c62a0e9aSFrançois Tigeot 	else
277c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP2_TP3_TIME_0us;
278c62a0e9aSFrançois Tigeot 
279c62a0e9aSFrançois Tigeot 	if (intel_dp_source_supports_hbr2(intel_dp) &&
280c62a0e9aSFrançois Tigeot 	    drm_dp_tps3_supported(intel_dp->dpcd))
281c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP1_TP3_SEL;
282c62a0e9aSFrançois Tigeot 	else
283c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP1_TP2_SEL;
284c62a0e9aSFrançois Tigeot 
285*3f2dd94aSFrançois Tigeot 	val |= I915_READ(EDP_PSR_CTL) & EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK;
286c62a0e9aSFrançois Tigeot 	I915_WRITE(EDP_PSR_CTL, val);
287a85cb24fSFrançois Tigeot }
288c62a0e9aSFrançois Tigeot 
hsw_activate_psr2(struct intel_dp * intel_dp)289*3f2dd94aSFrançois Tigeot static void hsw_activate_psr2(struct intel_dp *intel_dp)
290a85cb24fSFrançois Tigeot {
291a85cb24fSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
292a85cb24fSFrançois Tigeot 	struct drm_device *dev = dig_port->base.base.dev;
293a85cb24fSFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
294a85cb24fSFrançois Tigeot 	/*
295a85cb24fSFrançois Tigeot 	 * Let's respect VBT in case VBT asks a higher idle_frame value.
296a85cb24fSFrançois Tigeot 	 * Let's use 6 as the minimum to cover all known cases including
297a85cb24fSFrançois Tigeot 	 * the off-by-one issue that HW has in some cases. Also there are
298a85cb24fSFrançois Tigeot 	 * cases where sink should be able to train
299a85cb24fSFrançois Tigeot 	 * with the 5 or 6 idle patterns.
300a85cb24fSFrançois Tigeot 	 */
301a85cb24fSFrançois Tigeot 	uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
302a85cb24fSFrançois Tigeot 	uint32_t val;
303*3f2dd94aSFrançois Tigeot 	uint8_t sink_latency;
304a85cb24fSFrançois Tigeot 
305a85cb24fSFrançois Tigeot 	val = idle_frames << EDP_PSR_IDLE_FRAME_SHIFT;
306c62a0e9aSFrançois Tigeot 
307c62a0e9aSFrançois Tigeot 	/* FIXME: selective update is probably totally broken because it doesn't
308c62a0e9aSFrançois Tigeot 	 * mesh at all with our frontbuffer tracking. And the hw alone isn't
309c62a0e9aSFrançois Tigeot 	 * good enough. */
310a85cb24fSFrançois Tigeot 	val |= EDP_PSR2_ENABLE |
311*3f2dd94aSFrançois Tigeot 		EDP_SU_TRACK_ENABLE;
312*3f2dd94aSFrançois Tigeot 
313*3f2dd94aSFrançois Tigeot 	if (drm_dp_dpcd_readb(&intel_dp->aux,
314*3f2dd94aSFrançois Tigeot 				DP_SYNCHRONIZATION_LATENCY_IN_SINK,
315*3f2dd94aSFrançois Tigeot 				&sink_latency) == 1) {
316*3f2dd94aSFrançois Tigeot 		sink_latency &= DP_MAX_RESYNC_FRAME_COUNT_MASK;
317*3f2dd94aSFrançois Tigeot 	} else {
318*3f2dd94aSFrançois Tigeot 		sink_latency = 0;
319*3f2dd94aSFrançois Tigeot 	}
320*3f2dd94aSFrançois Tigeot 	val |= EDP_PSR2_FRAME_BEFORE_SU(sink_latency + 1);
321c62a0e9aSFrançois Tigeot 
322c62a0e9aSFrançois Tigeot 	if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
323c62a0e9aSFrançois Tigeot 		val |= EDP_PSR2_TP2_TIME_2500;
324c62a0e9aSFrançois Tigeot 	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1)
325c62a0e9aSFrançois Tigeot 		val |= EDP_PSR2_TP2_TIME_500;
326c62a0e9aSFrançois Tigeot 	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0)
327c62a0e9aSFrançois Tigeot 		val |= EDP_PSR2_TP2_TIME_100;
328c62a0e9aSFrançois Tigeot 	else
329c62a0e9aSFrançois Tigeot 		val |= EDP_PSR2_TP2_TIME_50;
330c62a0e9aSFrançois Tigeot 
331c62a0e9aSFrançois Tigeot 	I915_WRITE(EDP_PSR2_CTL, val);
3322c9916cdSFrançois Tigeot }
3332c9916cdSFrançois Tigeot 
hsw_psr_activate(struct intel_dp * intel_dp)334*3f2dd94aSFrançois Tigeot static void hsw_psr_activate(struct intel_dp *intel_dp)
335a85cb24fSFrançois Tigeot {
336a85cb24fSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
337a85cb24fSFrançois Tigeot 	struct drm_device *dev = dig_port->base.base.dev;
338a85cb24fSFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
339a85cb24fSFrançois Tigeot 
340*3f2dd94aSFrançois Tigeot 	/* On HSW+ after we enable PSR on source it will activate it
341*3f2dd94aSFrançois Tigeot 	 * as soon as it match configure idle_frame count. So
342*3f2dd94aSFrançois Tigeot 	 * we just actually enable it here on activation time.
343*3f2dd94aSFrançois Tigeot 	 */
344*3f2dd94aSFrançois Tigeot 
345a85cb24fSFrançois Tigeot 	/* psr1 and psr2 are mutually exclusive.*/
346a85cb24fSFrançois Tigeot 	if (dev_priv->psr.psr2_support)
347*3f2dd94aSFrançois Tigeot 		hsw_activate_psr2(intel_dp);
348a85cb24fSFrançois Tigeot 	else
349*3f2dd94aSFrançois Tigeot 		hsw_activate_psr1(intel_dp);
350a85cb24fSFrançois Tigeot }
351a85cb24fSFrançois Tigeot 
intel_psr_compute_config(struct intel_dp * intel_dp,struct intel_crtc_state * crtc_state)352*3f2dd94aSFrançois Tigeot void intel_psr_compute_config(struct intel_dp *intel_dp,
353*3f2dd94aSFrançois Tigeot 			      struct intel_crtc_state *crtc_state)
3542c9916cdSFrançois Tigeot {
3552c9916cdSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
356*3f2dd94aSFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
3571e12ee3bSFrançois Tigeot 	const struct drm_display_mode *adjusted_mode =
358*3f2dd94aSFrançois Tigeot 		&crtc_state->base.adjusted_mode;
3591e12ee3bSFrançois Tigeot 	int psr_setup_time;
3602c9916cdSFrançois Tigeot 
361*3f2dd94aSFrançois Tigeot 	if (!HAS_PSR(dev_priv))
362*3f2dd94aSFrançois Tigeot 		return;
3632c9916cdSFrançois Tigeot 
364*3f2dd94aSFrançois Tigeot 	if (!is_edp_psr(intel_dp))
365*3f2dd94aSFrançois Tigeot 		return;
366*3f2dd94aSFrançois Tigeot 
367*3f2dd94aSFrançois Tigeot 	if (!i915_modparams.enable_psr) {
368*3f2dd94aSFrançois Tigeot 		DRM_DEBUG_KMS("PSR disable by flag\n");
369*3f2dd94aSFrançois Tigeot 		return;
370*3f2dd94aSFrançois Tigeot 	}
3712c9916cdSFrançois Tigeot 
372c0e85e96SFrançois Tigeot 	/*
373c0e85e96SFrançois Tigeot 	 * HSW spec explicitly says PSR is tied to port A.
374c0e85e96SFrançois Tigeot 	 * BDW+ platforms with DDI implementation of PSR have different
375c0e85e96SFrançois Tigeot 	 * PSR registers per transcoder and we only implement transcoder EDP
376c0e85e96SFrançois Tigeot 	 * ones. Since by Display design transcoder EDP is tied to port A
377c0e85e96SFrançois Tigeot 	 * we can safely escape based on the port A.
378c0e85e96SFrançois Tigeot 	 */
3791e12ee3bSFrançois Tigeot 	if (HAS_DDI(dev_priv) && dig_port->port != PORT_A) {
380c0e85e96SFrançois Tigeot 		DRM_DEBUG_KMS("PSR condition failed: Port not supported\n");
381*3f2dd94aSFrançois Tigeot 		return;
3822c9916cdSFrançois Tigeot 	}
3832c9916cdSFrançois Tigeot 
3841e12ee3bSFrançois Tigeot 	if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
385c0e85e96SFrançois Tigeot 	    !dev_priv->psr.link_standby) {
386c0e85e96SFrançois Tigeot 		DRM_ERROR("PSR condition failed: Link off requested but not supported on this platform\n");
387*3f2dd94aSFrançois Tigeot 		return;
388c0e85e96SFrançois Tigeot 	}
389c0e85e96SFrançois Tigeot 
3901e12ee3bSFrançois Tigeot 	if (IS_HASWELL(dev_priv) &&
391*3f2dd94aSFrançois Tigeot 	    I915_READ(HSW_STEREO_3D_CTL(crtc_state->cpu_transcoder)) &
3922c9916cdSFrançois Tigeot 		      S3D_ENABLE) {
3932c9916cdSFrançois Tigeot 		DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n");
394*3f2dd94aSFrançois Tigeot 		return;
3952c9916cdSFrançois Tigeot 	}
3962c9916cdSFrançois Tigeot 
3971e12ee3bSFrançois Tigeot 	if (IS_HASWELL(dev_priv) &&
3981e12ee3bSFrançois Tigeot 	    adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
3992c9916cdSFrançois Tigeot 		DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n");
400*3f2dd94aSFrançois Tigeot 		return;
4012c9916cdSFrançois Tigeot 	}
4022c9916cdSFrançois Tigeot 
4031e12ee3bSFrançois Tigeot 	psr_setup_time = drm_dp_psr_setup_time(intel_dp->psr_dpcd);
4041e12ee3bSFrançois Tigeot 	if (psr_setup_time < 0) {
4051e12ee3bSFrançois Tigeot 		DRM_DEBUG_KMS("PSR condition failed: Invalid PSR setup time (0x%02x)\n",
4061e12ee3bSFrançois Tigeot 			      intel_dp->psr_dpcd[1]);
407*3f2dd94aSFrançois Tigeot 		return;
4081e12ee3bSFrançois Tigeot 	}
4091e12ee3bSFrançois Tigeot 
4101e12ee3bSFrançois Tigeot 	if (intel_usecs_to_scanlines(adjusted_mode, psr_setup_time) >
4111e12ee3bSFrançois Tigeot 	    adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vdisplay - 1) {
4121e12ee3bSFrançois Tigeot 		DRM_DEBUG_KMS("PSR condition failed: PSR setup time (%d us) too long\n",
4131e12ee3bSFrançois Tigeot 			      psr_setup_time);
414*3f2dd94aSFrançois Tigeot 		return;
415*3f2dd94aSFrançois Tigeot 	}
416*3f2dd94aSFrançois Tigeot 
417*3f2dd94aSFrançois Tigeot 	/*
418*3f2dd94aSFrançois Tigeot 	 * FIXME psr2_support is messed up. It's both computed
419*3f2dd94aSFrançois Tigeot 	 * dynamically during PSR enable, and extracted from sink
420*3f2dd94aSFrançois Tigeot 	 * caps during eDP detection.
421*3f2dd94aSFrançois Tigeot 	 */
422*3f2dd94aSFrançois Tigeot 	if (!dev_priv->psr.psr2_support) {
423*3f2dd94aSFrançois Tigeot 		crtc_state->has_psr = true;
424*3f2dd94aSFrançois Tigeot 		return;
4251e12ee3bSFrançois Tigeot 	}
4261e12ee3bSFrançois Tigeot 
427a85cb24fSFrançois Tigeot 	/* PSR2 is restricted to work with panel resolutions upto 3200x2000 */
428*3f2dd94aSFrançois Tigeot 	if (adjusted_mode->crtc_hdisplay > 3200 ||
429*3f2dd94aSFrançois Tigeot 	    adjusted_mode->crtc_vdisplay > 2000) {
430*3f2dd94aSFrançois Tigeot 		DRM_DEBUG_KMS("PSR2 disabled, panel resolution too big\n");
431*3f2dd94aSFrançois Tigeot 		return;
432a85cb24fSFrançois Tigeot 	}
433a85cb24fSFrançois Tigeot 
434a85cb24fSFrançois Tigeot 	/*
435a85cb24fSFrançois Tigeot 	 * FIXME:enable psr2 only for y-cordinate psr2 panels
436a85cb24fSFrançois Tigeot 	 * After gtc implementation , remove this restriction.
437a85cb24fSFrançois Tigeot 	 */
438*3f2dd94aSFrançois Tigeot 	if (!dev_priv->psr.y_cord_support) {
439a85cb24fSFrançois Tigeot 		DRM_DEBUG_KMS("PSR2 disabled, panel does not support Y coordinate\n");
440*3f2dd94aSFrançois Tigeot 		return;
441a85cb24fSFrançois Tigeot 	}
442a85cb24fSFrançois Tigeot 
443*3f2dd94aSFrançois Tigeot 	crtc_state->has_psr = true;
444*3f2dd94aSFrançois Tigeot 	crtc_state->has_psr2 = true;
4452c9916cdSFrançois Tigeot }
4462c9916cdSFrançois Tigeot 
intel_psr_activate(struct intel_dp * intel_dp)4472c9916cdSFrançois Tigeot static void intel_psr_activate(struct intel_dp *intel_dp)
4482c9916cdSFrançois Tigeot {
4492c9916cdSFrançois Tigeot 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
4502c9916cdSFrançois Tigeot 	struct drm_device *dev = intel_dig_port->base.base.dev;
451bf017597SFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
4522c9916cdSFrançois Tigeot 
453a85cb24fSFrançois Tigeot 	if (dev_priv->psr.psr2_support)
454a85cb24fSFrançois Tigeot 		WARN_ON(I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE);
455a85cb24fSFrançois Tigeot 	else
456aee94f86SFrançois Tigeot 		WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
4572c9916cdSFrançois Tigeot 	WARN_ON(dev_priv->psr.active);
4582c9916cdSFrançois Tigeot 	lockdep_assert_held(&dev_priv->psr.lock);
4592c9916cdSFrançois Tigeot 
460*3f2dd94aSFrançois Tigeot 	dev_priv->psr.activate(intel_dp);
4612c9916cdSFrançois Tigeot 	dev_priv->psr.active = true;
4622c9916cdSFrançois Tigeot }
4632c9916cdSFrançois Tigeot 
hsw_psr_enable_source(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state)464*3f2dd94aSFrançois Tigeot static void hsw_psr_enable_source(struct intel_dp *intel_dp,
465*3f2dd94aSFrançois Tigeot 				  const struct intel_crtc_state *crtc_state)
4662c9916cdSFrançois Tigeot {
467*3f2dd94aSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
468*3f2dd94aSFrançois Tigeot 	struct drm_device *dev = dig_port->base.base.dev;
469bf017597SFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
470*3f2dd94aSFrançois Tigeot 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
471a85cb24fSFrançois Tigeot 	u32 chicken;
4722c9916cdSFrançois Tigeot 
47319c468b4SFrançois Tigeot 	if (dev_priv->psr.psr2_support) {
474a85cb24fSFrançois Tigeot 		chicken = PSR2_VSC_ENABLE_PROG_HEADER;
475a85cb24fSFrançois Tigeot 		if (dev_priv->psr.y_cord_support)
476a85cb24fSFrançois Tigeot 			chicken |= PSR2_ADD_VERTICAL_LINE_COUNT;
477a85cb24fSFrançois Tigeot 		I915_WRITE(CHICKEN_TRANS(cpu_transcoder), chicken);
478*3f2dd94aSFrançois Tigeot 
479a85cb24fSFrançois Tigeot 		I915_WRITE(EDP_PSR_DEBUG_CTL,
480a85cb24fSFrançois Tigeot 			   EDP_PSR_DEBUG_MASK_MEMUP |
481a85cb24fSFrançois Tigeot 			   EDP_PSR_DEBUG_MASK_HPD |
482a85cb24fSFrançois Tigeot 			   EDP_PSR_DEBUG_MASK_LPSP |
483a85cb24fSFrançois Tigeot 			   EDP_PSR_DEBUG_MASK_MAX_SLEEP |
484a85cb24fSFrançois Tigeot 			   EDP_PSR_DEBUG_MASK_DISP_REG_WRITE);
485a85cb24fSFrançois Tigeot 	} else {
486aee94f86SFrançois Tigeot 		/*
487a85cb24fSFrançois Tigeot 		 * Per Spec: Avoid continuous PSR exit by masking MEMUP
488a85cb24fSFrançois Tigeot 		 * and HPD. also mask LPSP to avoid dependency on other
489a85cb24fSFrançois Tigeot 		 * drivers that might block runtime_pm besides
490a85cb24fSFrançois Tigeot 		 * preventing  other hw tracking issues now we can rely
491a85cb24fSFrançois Tigeot 		 * on frontbuffer tracking.
492aee94f86SFrançois Tigeot 		 */
493a85cb24fSFrançois Tigeot 		I915_WRITE(EDP_PSR_DEBUG_CTL,
494a85cb24fSFrançois Tigeot 			   EDP_PSR_DEBUG_MASK_MEMUP |
495a85cb24fSFrançois Tigeot 			   EDP_PSR_DEBUG_MASK_HPD |
496a85cb24fSFrançois Tigeot 			   EDP_PSR_DEBUG_MASK_LPSP);
497a85cb24fSFrançois Tigeot 	}
4982c9916cdSFrançois Tigeot }
4992c9916cdSFrançois Tigeot 
500*3f2dd94aSFrançois Tigeot /**
501*3f2dd94aSFrançois Tigeot  * intel_psr_enable - Enable PSR
502*3f2dd94aSFrançois Tigeot  * @intel_dp: Intel DP
503*3f2dd94aSFrançois Tigeot  * @crtc_state: new CRTC state
504*3f2dd94aSFrançois Tigeot  *
505*3f2dd94aSFrançois Tigeot  * This function can only be called after the pipe is fully trained and enabled.
506aee94f86SFrançois Tigeot  */
intel_psr_enable(struct intel_dp * intel_dp,const struct intel_crtc_state * crtc_state)507*3f2dd94aSFrançois Tigeot void intel_psr_enable(struct intel_dp *intel_dp,
508*3f2dd94aSFrançois Tigeot 		      const struct intel_crtc_state *crtc_state)
5092c9916cdSFrançois Tigeot {
5102c9916cdSFrançois Tigeot 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
5112c9916cdSFrançois Tigeot 	struct drm_device *dev = intel_dig_port->base.base.dev;
512bf017597SFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
513*3f2dd94aSFrançois Tigeot 
514*3f2dd94aSFrançois Tigeot 	if (!crtc_state->has_psr)
515*3f2dd94aSFrançois Tigeot 		return;
516*3f2dd94aSFrançois Tigeot 
517*3f2dd94aSFrançois Tigeot 	WARN_ON(dev_priv->drrs.dp);
518*3f2dd94aSFrançois Tigeot 	mutex_lock(&dev_priv->psr.lock);
519*3f2dd94aSFrançois Tigeot 	if (dev_priv->psr.enabled) {
520*3f2dd94aSFrançois Tigeot 		DRM_DEBUG_KMS("PSR already in use\n");
521*3f2dd94aSFrançois Tigeot 		goto unlock;
522*3f2dd94aSFrançois Tigeot 	}
523*3f2dd94aSFrançois Tigeot 
524*3f2dd94aSFrançois Tigeot 	dev_priv->psr.psr2_support = crtc_state->has_psr2;
525*3f2dd94aSFrançois Tigeot 	dev_priv->psr.source_ok = true;
526*3f2dd94aSFrançois Tigeot 
527*3f2dd94aSFrançois Tigeot 	dev_priv->psr.busy_frontbuffer_bits = 0;
528*3f2dd94aSFrançois Tigeot 
529*3f2dd94aSFrançois Tigeot 	dev_priv->psr.setup_vsc(intel_dp, crtc_state);
530*3f2dd94aSFrançois Tigeot 	dev_priv->psr.enable_sink(intel_dp);
531*3f2dd94aSFrançois Tigeot 	dev_priv->psr.enable_source(intel_dp, crtc_state);
532*3f2dd94aSFrançois Tigeot 	dev_priv->psr.enabled = intel_dp;
533*3f2dd94aSFrançois Tigeot 
534*3f2dd94aSFrançois Tigeot 	if (INTEL_GEN(dev_priv) >= 9) {
535*3f2dd94aSFrançois Tigeot 		intel_psr_activate(intel_dp);
536*3f2dd94aSFrançois Tigeot 	} else {
537*3f2dd94aSFrançois Tigeot 		/*
538*3f2dd94aSFrançois Tigeot 		 * FIXME: Activation should happen immediately since this
539*3f2dd94aSFrançois Tigeot 		 * function is just called after pipe is fully trained and
540*3f2dd94aSFrançois Tigeot 		 * enabled.
541*3f2dd94aSFrançois Tigeot 		 * However on some platforms we face issues when first
542*3f2dd94aSFrançois Tigeot 		 * activation follows a modeset so quickly.
543*3f2dd94aSFrançois Tigeot 		 *     - On VLV/CHV we get bank screen on first activation
544*3f2dd94aSFrançois Tigeot 		 *     - On HSW/BDW we get a recoverable frozen screen until
545*3f2dd94aSFrançois Tigeot 		 *       next exit-activate sequence.
546*3f2dd94aSFrançois Tigeot 		 */
547*3f2dd94aSFrançois Tigeot 		schedule_delayed_work(&dev_priv->psr.work,
548*3f2dd94aSFrançois Tigeot 				      msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5));
549*3f2dd94aSFrançois Tigeot 	}
550*3f2dd94aSFrançois Tigeot 
551*3f2dd94aSFrançois Tigeot unlock:
552*3f2dd94aSFrançois Tigeot 	mutex_unlock(&dev_priv->psr.lock);
553*3f2dd94aSFrançois Tigeot }
554*3f2dd94aSFrançois Tigeot 
vlv_psr_disable(struct intel_dp * intel_dp,const struct intel_crtc_state * old_crtc_state)555*3f2dd94aSFrançois Tigeot static void vlv_psr_disable(struct intel_dp *intel_dp,
556*3f2dd94aSFrançois Tigeot 			    const struct intel_crtc_state *old_crtc_state)
557*3f2dd94aSFrançois Tigeot {
558*3f2dd94aSFrançois Tigeot 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
559*3f2dd94aSFrançois Tigeot 	struct drm_device *dev = intel_dig_port->base.base.dev;
560*3f2dd94aSFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
561*3f2dd94aSFrançois Tigeot 	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
5622c9916cdSFrançois Tigeot 	uint32_t val;
5632c9916cdSFrançois Tigeot 
5642c9916cdSFrançois Tigeot 	if (dev_priv->psr.active) {
565*3f2dd94aSFrançois Tigeot 		/* Put VLV PSR back to PSR_state 0 (disabled). */
5661487f786SFrançois Tigeot 		if (intel_wait_for_register(dev_priv,
567*3f2dd94aSFrançois Tigeot 					    VLV_PSRSTAT(crtc->pipe),
5681487f786SFrançois Tigeot 					    VLV_EDP_PSR_IN_TRANS,
5691487f786SFrançois Tigeot 					    0,
5701487f786SFrançois Tigeot 					    1))
5712c9916cdSFrançois Tigeot 			WARN(1, "PSR transition took longer than expected\n");
5722c9916cdSFrançois Tigeot 
573*3f2dd94aSFrançois Tigeot 		val = I915_READ(VLV_PSRCTL(crtc->pipe));
5742c9916cdSFrançois Tigeot 		val &= ~VLV_EDP_PSR_ACTIVE_ENTRY;
5752c9916cdSFrançois Tigeot 		val &= ~VLV_EDP_PSR_ENABLE;
5762c9916cdSFrançois Tigeot 		val &= ~VLV_EDP_PSR_MODE_MASK;
577*3f2dd94aSFrançois Tigeot 		I915_WRITE(VLV_PSRCTL(crtc->pipe), val);
5782c9916cdSFrançois Tigeot 
5792c9916cdSFrançois Tigeot 		dev_priv->psr.active = false;
5802c9916cdSFrançois Tigeot 	} else {
581*3f2dd94aSFrançois Tigeot 		WARN_ON(vlv_is_psr_active_on_pipe(dev, crtc->pipe));
5822c9916cdSFrançois Tigeot 	}
5832c9916cdSFrançois Tigeot }
5842c9916cdSFrançois Tigeot 
hsw_psr_disable(struct intel_dp * intel_dp,const struct intel_crtc_state * old_crtc_state)585*3f2dd94aSFrançois Tigeot static void hsw_psr_disable(struct intel_dp *intel_dp,
586*3f2dd94aSFrançois Tigeot 			    const struct intel_crtc_state *old_crtc_state)
5872c9916cdSFrançois Tigeot {
5882c9916cdSFrançois Tigeot 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
5892c9916cdSFrançois Tigeot 	struct drm_device *dev = intel_dig_port->base.base.dev;
590bf017597SFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
5912c9916cdSFrançois Tigeot 
5922c9916cdSFrançois Tigeot 	if (dev_priv->psr.active) {
593*3f2dd94aSFrançois Tigeot 		i915_reg_t psr_status;
594a85cb24fSFrançois Tigeot 		u32 psr_status_mask;
595a85cb24fSFrançois Tigeot 
596a85cb24fSFrançois Tigeot 		if (dev_priv->psr.aux_frame_sync)
597a85cb24fSFrançois Tigeot 			drm_dp_dpcd_writeb(&intel_dp->aux,
598a85cb24fSFrançois Tigeot 					DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF,
599a85cb24fSFrançois Tigeot 					0);
600a85cb24fSFrançois Tigeot 
601a85cb24fSFrançois Tigeot 		if (dev_priv->psr.psr2_support) {
602*3f2dd94aSFrançois Tigeot 			psr_status = EDP_PSR2_STATUS_CTL;
603a85cb24fSFrançois Tigeot 			psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
604a85cb24fSFrançois Tigeot 
605*3f2dd94aSFrançois Tigeot 			I915_WRITE(EDP_PSR2_CTL,
606*3f2dd94aSFrançois Tigeot 				   I915_READ(EDP_PSR2_CTL) &
607a85cb24fSFrançois Tigeot 				   ~(EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE));
608a85cb24fSFrançois Tigeot 
609a85cb24fSFrançois Tigeot 		} else {
610*3f2dd94aSFrançois Tigeot 			psr_status = EDP_PSR_STATUS_CTL;
611a85cb24fSFrançois Tigeot 			psr_status_mask = EDP_PSR_STATUS_STATE_MASK;
612a85cb24fSFrançois Tigeot 
613*3f2dd94aSFrançois Tigeot 			I915_WRITE(EDP_PSR_CTL,
614*3f2dd94aSFrançois Tigeot 				   I915_READ(EDP_PSR_CTL) & ~EDP_PSR_ENABLE);
615a85cb24fSFrançois Tigeot 		}
6162c9916cdSFrançois Tigeot 
6172c9916cdSFrançois Tigeot 		/* Wait till PSR is idle */
6181487f786SFrançois Tigeot 		if (intel_wait_for_register(dev_priv,
619*3f2dd94aSFrançois Tigeot 					    psr_status, psr_status_mask, 0,
6201487f786SFrançois Tigeot 					    2000))
6212c9916cdSFrançois Tigeot 			DRM_ERROR("Timed out waiting for PSR Idle State\n");
6222c9916cdSFrançois Tigeot 
6232c9916cdSFrançois Tigeot 		dev_priv->psr.active = false;
6242c9916cdSFrançois Tigeot 	} else {
625a85cb24fSFrançois Tigeot 		if (dev_priv->psr.psr2_support)
626a85cb24fSFrançois Tigeot 			WARN_ON(I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE);
627a85cb24fSFrançois Tigeot 		else
628aee94f86SFrançois Tigeot 			WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
6292c9916cdSFrançois Tigeot 	}
6302c9916cdSFrançois Tigeot }
6312c9916cdSFrançois Tigeot 
6322c9916cdSFrançois Tigeot /**
6332c9916cdSFrançois Tigeot  * intel_psr_disable - Disable PSR
6342c9916cdSFrançois Tigeot  * @intel_dp: Intel DP
635*3f2dd94aSFrançois Tigeot  * @old_crtc_state: old CRTC state
6362c9916cdSFrançois Tigeot  *
6372c9916cdSFrançois Tigeot  * This function needs to be called before disabling pipe.
6382c9916cdSFrançois Tigeot  */
intel_psr_disable(struct intel_dp * intel_dp,const struct intel_crtc_state * old_crtc_state)639*3f2dd94aSFrançois Tigeot void intel_psr_disable(struct intel_dp *intel_dp,
640*3f2dd94aSFrançois Tigeot 		       const struct intel_crtc_state *old_crtc_state)
6412c9916cdSFrançois Tigeot {
6422c9916cdSFrançois Tigeot 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
6432c9916cdSFrançois Tigeot 	struct drm_device *dev = intel_dig_port->base.base.dev;
644bf017597SFrançois Tigeot 	struct drm_i915_private *dev_priv = to_i915(dev);
6452c9916cdSFrançois Tigeot 
646*3f2dd94aSFrançois Tigeot 	if (!old_crtc_state->has_psr)
647*3f2dd94aSFrançois Tigeot 		return;
648*3f2dd94aSFrançois Tigeot 
6492c9916cdSFrançois Tigeot 	mutex_lock(&dev_priv->psr.lock);
6502c9916cdSFrançois Tigeot 	if (!dev_priv->psr.enabled) {
6512c9916cdSFrançois Tigeot 		mutex_unlock(&dev_priv->psr.lock);
6522c9916cdSFrançois Tigeot 		return;
6532c9916cdSFrançois Tigeot 	}
6542c9916cdSFrançois Tigeot 
655*3f2dd94aSFrançois Tigeot 	dev_priv->psr.disable_source(intel_dp, old_crtc_state);
6562c9916cdSFrançois Tigeot 
657aee94f86SFrançois Tigeot 	/* Disable PSR on Sink */
658aee94f86SFrançois Tigeot 	drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
659aee94f86SFrançois Tigeot 
6602c9916cdSFrançois Tigeot 	dev_priv->psr.enabled = NULL;
6612c9916cdSFrançois Tigeot 	mutex_unlock(&dev_priv->psr.lock);
6622c9916cdSFrançois Tigeot 
6632c9916cdSFrançois Tigeot 	cancel_delayed_work_sync(&dev_priv->psr.work);
6642c9916cdSFrançois Tigeot }
6652c9916cdSFrançois Tigeot 
intel_psr_work(struct work_struct * work)6662c9916cdSFrançois Tigeot static void intel_psr_work(struct work_struct *work)
6672c9916cdSFrançois Tigeot {
6682c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv =
6692c9916cdSFrançois Tigeot 		container_of(work, typeof(*dev_priv), psr.work.work);
6702c9916cdSFrançois Tigeot 	struct intel_dp *intel_dp = dev_priv->psr.enabled;
6712c9916cdSFrançois Tigeot 	struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
6722c9916cdSFrançois Tigeot 	enum i915_pipe pipe = to_intel_crtc(crtc)->pipe;
6732c9916cdSFrançois Tigeot 
6742c9916cdSFrançois Tigeot 	/* We have to make sure PSR is ready for re-enable
6752c9916cdSFrançois Tigeot 	 * otherwise it keeps disabled until next full enable/disable cycle.
6762c9916cdSFrançois Tigeot 	 * PSR might take some time to get fully disabled
6772c9916cdSFrançois Tigeot 	 * and be ready for re-enable.
6782c9916cdSFrançois Tigeot 	 */
6798621f407SFrançois Tigeot 	if (HAS_DDI(dev_priv)) {
680a85cb24fSFrançois Tigeot 		if (dev_priv->psr.psr2_support) {
681a85cb24fSFrançois Tigeot 			if (intel_wait_for_register(dev_priv,
682a85cb24fSFrançois Tigeot 						EDP_PSR2_STATUS_CTL,
683a85cb24fSFrançois Tigeot 						EDP_PSR2_STATUS_STATE_MASK,
684a85cb24fSFrançois Tigeot 						0,
685a85cb24fSFrançois Tigeot 						50)) {
686a85cb24fSFrançois Tigeot 				DRM_ERROR("Timed out waiting for PSR2 Idle for re-enable\n");
687a85cb24fSFrançois Tigeot 				return;
688a85cb24fSFrançois Tigeot 			}
689a85cb24fSFrançois Tigeot 		} else {
6901487f786SFrançois Tigeot 			if (intel_wait_for_register(dev_priv,
6911487f786SFrançois Tigeot 						EDP_PSR_STATUS_CTL,
6921487f786SFrançois Tigeot 						EDP_PSR_STATUS_STATE_MASK,
6931487f786SFrançois Tigeot 						0,
6941487f786SFrançois Tigeot 						50)) {
6952c9916cdSFrançois Tigeot 				DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n");
6962c9916cdSFrançois Tigeot 				return;
6972c9916cdSFrançois Tigeot 			}
698a85cb24fSFrançois Tigeot 		}
6992c9916cdSFrançois Tigeot 	} else {
7001487f786SFrançois Tigeot 		if (intel_wait_for_register(dev_priv,
7011487f786SFrançois Tigeot 					    VLV_PSRSTAT(pipe),
7021487f786SFrançois Tigeot 					    VLV_EDP_PSR_IN_TRANS,
7031487f786SFrançois Tigeot 					    0,
7041487f786SFrançois Tigeot 					    1)) {
7052c9916cdSFrançois Tigeot 			DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n");
7062c9916cdSFrançois Tigeot 			return;
7072c9916cdSFrançois Tigeot 		}
7082c9916cdSFrançois Tigeot 	}
7092c9916cdSFrançois Tigeot 	mutex_lock(&dev_priv->psr.lock);
7102c9916cdSFrançois Tigeot 	intel_dp = dev_priv->psr.enabled;
7112c9916cdSFrançois Tigeot 
7122c9916cdSFrançois Tigeot 	if (!intel_dp)
7132c9916cdSFrançois Tigeot 		goto unlock;
7142c9916cdSFrançois Tigeot 
7152c9916cdSFrançois Tigeot 	/*
7162c9916cdSFrançois Tigeot 	 * The delayed work can race with an invalidate hence we need to
7172c9916cdSFrançois Tigeot 	 * recheck. Since psr_flush first clears this and then reschedules we
7182c9916cdSFrançois Tigeot 	 * won't ever miss a flush when bailing out here.
7192c9916cdSFrançois Tigeot 	 */
7202c9916cdSFrançois Tigeot 	if (dev_priv->psr.busy_frontbuffer_bits)
7212c9916cdSFrançois Tigeot 		goto unlock;
7222c9916cdSFrançois Tigeot 
7232c9916cdSFrançois Tigeot 	intel_psr_activate(intel_dp);
7242c9916cdSFrançois Tigeot unlock:
7252c9916cdSFrançois Tigeot 	mutex_unlock(&dev_priv->psr.lock);
7262c9916cdSFrançois Tigeot }
7272c9916cdSFrançois Tigeot 
intel_psr_exit(struct drm_i915_private * dev_priv)72871f41f3eSFrançois Tigeot static void intel_psr_exit(struct drm_i915_private *dev_priv)
7292c9916cdSFrançois Tigeot {
7302c9916cdSFrançois Tigeot 	struct intel_dp *intel_dp = dev_priv->psr.enabled;
7312c9916cdSFrançois Tigeot 	struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
7322c9916cdSFrançois Tigeot 	enum i915_pipe pipe = to_intel_crtc(crtc)->pipe;
7332c9916cdSFrançois Tigeot 	u32 val;
7342c9916cdSFrançois Tigeot 
7352c9916cdSFrançois Tigeot 	if (!dev_priv->psr.active)
7362c9916cdSFrançois Tigeot 		return;
7372c9916cdSFrançois Tigeot 
73871f41f3eSFrançois Tigeot 	if (HAS_DDI(dev_priv)) {
739a85cb24fSFrançois Tigeot 		if (dev_priv->psr.aux_frame_sync)
740a85cb24fSFrançois Tigeot 			drm_dp_dpcd_writeb(&intel_dp->aux,
741a85cb24fSFrançois Tigeot 					DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF,
742a85cb24fSFrançois Tigeot 					0);
743a85cb24fSFrançois Tigeot 		if (dev_priv->psr.psr2_support) {
744a85cb24fSFrançois Tigeot 			val = I915_READ(EDP_PSR2_CTL);
745a85cb24fSFrançois Tigeot 			WARN_ON(!(val & EDP_PSR2_ENABLE));
746a85cb24fSFrançois Tigeot 			I915_WRITE(EDP_PSR2_CTL, val & ~EDP_PSR2_ENABLE);
747a85cb24fSFrançois Tigeot 		} else {
748aee94f86SFrançois Tigeot 			val = I915_READ(EDP_PSR_CTL);
7492c9916cdSFrançois Tigeot 			WARN_ON(!(val & EDP_PSR_ENABLE));
750aee94f86SFrançois Tigeot 			I915_WRITE(EDP_PSR_CTL, val & ~EDP_PSR_ENABLE);
751a85cb24fSFrançois Tigeot 		}
7522c9916cdSFrançois Tigeot 	} else {
7532c9916cdSFrançois Tigeot 		val = I915_READ(VLV_PSRCTL(pipe));
7542c9916cdSFrançois Tigeot 
755*3f2dd94aSFrançois Tigeot 		/*
756*3f2dd94aSFrançois Tigeot 		 * Here we do the transition drirectly from
757*3f2dd94aSFrançois Tigeot 		 * PSR_state 3 (active - no Remote Frame Buffer (RFB) update) to
758*3f2dd94aSFrançois Tigeot 		 * PSR_state 5 (exit).
759*3f2dd94aSFrançois Tigeot 		 * PSR State 4 (active with single frame update) can be skipped.
760*3f2dd94aSFrançois Tigeot 		 * On PSR_state 5 (exit) Hardware is responsible to transition
761*3f2dd94aSFrançois Tigeot 		 * back to PSR_state 1 (inactive).
762*3f2dd94aSFrançois Tigeot 		 * Now we are at Same state after vlv_psr_enable_source.
7632c9916cdSFrançois Tigeot 		 */
7642c9916cdSFrançois Tigeot 		val &= ~VLV_EDP_PSR_ACTIVE_ENTRY;
7652c9916cdSFrançois Tigeot 		I915_WRITE(VLV_PSRCTL(pipe), val);
7662c9916cdSFrançois Tigeot 
767*3f2dd94aSFrançois Tigeot 		/*
768*3f2dd94aSFrançois Tigeot 		 * Send AUX wake up - Spec says after transitioning to PSR
7692c9916cdSFrançois Tigeot 		 * active we have to send AUX wake up by writing 01h in DPCD
7702c9916cdSFrançois Tigeot 		 * 600h of sink device.
7712c9916cdSFrançois Tigeot 		 * XXX: This might slow down the transition, but without this
7722c9916cdSFrançois Tigeot 		 * HW doesn't complete the transition to PSR_state 1 and we
7732c9916cdSFrançois Tigeot 		 * never get the screen updated.
7742c9916cdSFrançois Tigeot 		 */
7752c9916cdSFrançois Tigeot 		drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER,
7762c9916cdSFrançois Tigeot 				   DP_SET_POWER_D0);
7772c9916cdSFrançois Tigeot 	}
7782c9916cdSFrançois Tigeot 
7792c9916cdSFrançois Tigeot 	dev_priv->psr.active = false;
7802c9916cdSFrançois Tigeot }
7812c9916cdSFrançois Tigeot 
7822c9916cdSFrançois Tigeot /**
78319c468b4SFrançois Tigeot  * intel_psr_single_frame_update - Single Frame Update
78471f41f3eSFrançois Tigeot  * @dev_priv: i915 device
785a05eeebfSFrançois Tigeot  * @frontbuffer_bits: frontbuffer plane tracking bits
78619c468b4SFrançois Tigeot  *
78719c468b4SFrançois Tigeot  * Some platforms support a single frame update feature that is used to
78819c468b4SFrançois Tigeot  * send and update only one frame on Remote Frame Buffer.
78919c468b4SFrançois Tigeot  * So far it is only implemented for Valleyview and Cherryview because
79019c468b4SFrançois Tigeot  * hardware requires this to be done before a page flip.
79119c468b4SFrançois Tigeot  */
intel_psr_single_frame_update(struct drm_i915_private * dev_priv,unsigned frontbuffer_bits)79271f41f3eSFrançois Tigeot void intel_psr_single_frame_update(struct drm_i915_private *dev_priv,
793a05eeebfSFrançois Tigeot 				   unsigned frontbuffer_bits)
79419c468b4SFrançois Tigeot {
79519c468b4SFrançois Tigeot 	struct drm_crtc *crtc;
79619c468b4SFrançois Tigeot 	enum i915_pipe pipe;
79719c468b4SFrançois Tigeot 	u32 val;
79819c468b4SFrançois Tigeot 
799*3f2dd94aSFrançois Tigeot 	if (!HAS_PSR(dev_priv))
800*3f2dd94aSFrançois Tigeot 		return;
801*3f2dd94aSFrançois Tigeot 
80219c468b4SFrançois Tigeot 	/*
80319c468b4SFrançois Tigeot 	 * Single frame update is already supported on BDW+ but it requires
80419c468b4SFrançois Tigeot 	 * many W/A and it isn't really needed.
80519c468b4SFrançois Tigeot 	 */
80671f41f3eSFrançois Tigeot 	if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv))
80719c468b4SFrançois Tigeot 		return;
80819c468b4SFrançois Tigeot 
80919c468b4SFrançois Tigeot 	mutex_lock(&dev_priv->psr.lock);
81019c468b4SFrançois Tigeot 	if (!dev_priv->psr.enabled) {
81119c468b4SFrançois Tigeot 		mutex_unlock(&dev_priv->psr.lock);
81219c468b4SFrançois Tigeot 		return;
81319c468b4SFrançois Tigeot 	}
81419c468b4SFrançois Tigeot 
81519c468b4SFrançois Tigeot 	crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
81619c468b4SFrançois Tigeot 	pipe = to_intel_crtc(crtc)->pipe;
817a05eeebfSFrançois Tigeot 
818a05eeebfSFrançois Tigeot 	if (frontbuffer_bits & INTEL_FRONTBUFFER_ALL_MASK(pipe)) {
81919c468b4SFrançois Tigeot 		val = I915_READ(VLV_PSRCTL(pipe));
82019c468b4SFrançois Tigeot 
82119c468b4SFrançois Tigeot 		/*
82219c468b4SFrançois Tigeot 		 * We need to set this bit before writing registers for a flip.
82319c468b4SFrançois Tigeot 		 * This bit will be self-clear when it gets to the PSR active state.
82419c468b4SFrançois Tigeot 		 */
82519c468b4SFrançois Tigeot 		I915_WRITE(VLV_PSRCTL(pipe), val | VLV_EDP_PSR_SINGLE_FRAME_UPDATE);
826a05eeebfSFrançois Tigeot 	}
82719c468b4SFrançois Tigeot 	mutex_unlock(&dev_priv->psr.lock);
82819c468b4SFrançois Tigeot }
82919c468b4SFrançois Tigeot 
83019c468b4SFrançois Tigeot /**
8312c9916cdSFrançois Tigeot  * intel_psr_invalidate - Invalidade PSR
83271f41f3eSFrançois Tigeot  * @dev_priv: i915 device
8332c9916cdSFrançois Tigeot  * @frontbuffer_bits: frontbuffer plane tracking bits
8342c9916cdSFrançois Tigeot  *
8352c9916cdSFrançois Tigeot  * Since the hardware frontbuffer tracking has gaps we need to integrate
8362c9916cdSFrançois Tigeot  * with the software frontbuffer tracking. This function gets called every
8372c9916cdSFrançois Tigeot  * time frontbuffer rendering starts and a buffer gets dirtied. PSR must be
8382c9916cdSFrançois Tigeot  * disabled if the frontbuffer mask contains a buffer relevant to PSR.
8392c9916cdSFrançois Tigeot  *
8402c9916cdSFrançois Tigeot  * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits."
8412c9916cdSFrançois Tigeot  */
intel_psr_invalidate(struct drm_i915_private * dev_priv,unsigned frontbuffer_bits)84271f41f3eSFrançois Tigeot void intel_psr_invalidate(struct drm_i915_private *dev_priv,
8432c9916cdSFrançois Tigeot 			  unsigned frontbuffer_bits)
8442c9916cdSFrançois Tigeot {
8452c9916cdSFrançois Tigeot 	struct drm_crtc *crtc;
8462c9916cdSFrançois Tigeot 	enum i915_pipe pipe;
8472c9916cdSFrançois Tigeot 
848*3f2dd94aSFrançois Tigeot 	if (!HAS_PSR(dev_priv))
849*3f2dd94aSFrançois Tigeot 		return;
850*3f2dd94aSFrançois Tigeot 
8512c9916cdSFrançois Tigeot 	mutex_lock(&dev_priv->psr.lock);
8522c9916cdSFrançois Tigeot 	if (!dev_priv->psr.enabled) {
8532c9916cdSFrançois Tigeot 		mutex_unlock(&dev_priv->psr.lock);
8542c9916cdSFrançois Tigeot 		return;
8552c9916cdSFrançois Tigeot 	}
8562c9916cdSFrançois Tigeot 
8572c9916cdSFrançois Tigeot 	crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
8582c9916cdSFrançois Tigeot 	pipe = to_intel_crtc(crtc)->pipe;
8592c9916cdSFrançois Tigeot 
860a05eeebfSFrançois Tigeot 	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
861a05eeebfSFrançois Tigeot 	dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits;
862a05eeebfSFrançois Tigeot 
863a05eeebfSFrançois Tigeot 	if (frontbuffer_bits)
86471f41f3eSFrançois Tigeot 		intel_psr_exit(dev_priv);
8652c9916cdSFrançois Tigeot 
8662c9916cdSFrançois Tigeot 	mutex_unlock(&dev_priv->psr.lock);
8672c9916cdSFrançois Tigeot }
8682c9916cdSFrançois Tigeot 
8692c9916cdSFrançois Tigeot /**
8702c9916cdSFrançois Tigeot  * intel_psr_flush - Flush PSR
87171f41f3eSFrançois Tigeot  * @dev_priv: i915 device
8722c9916cdSFrançois Tigeot  * @frontbuffer_bits: frontbuffer plane tracking bits
873a05eeebfSFrançois Tigeot  * @origin: which operation caused the flush
8742c9916cdSFrançois Tigeot  *
8752c9916cdSFrançois Tigeot  * Since the hardware frontbuffer tracking has gaps we need to integrate
8762c9916cdSFrançois Tigeot  * with the software frontbuffer tracking. This function gets called every
8772c9916cdSFrançois Tigeot  * time frontbuffer rendering has completed and flushed out to memory. PSR
8782c9916cdSFrançois Tigeot  * can be enabled again if no other frontbuffer relevant to PSR is dirty.
8792c9916cdSFrançois Tigeot  *
8802c9916cdSFrançois Tigeot  * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits.
8812c9916cdSFrançois Tigeot  */
intel_psr_flush(struct drm_i915_private * dev_priv,unsigned frontbuffer_bits,enum fb_op_origin origin)88271f41f3eSFrançois Tigeot void intel_psr_flush(struct drm_i915_private *dev_priv,
883a05eeebfSFrançois Tigeot 		     unsigned frontbuffer_bits, enum fb_op_origin origin)
8842c9916cdSFrançois Tigeot {
8852c9916cdSFrançois Tigeot 	struct drm_crtc *crtc;
8862c9916cdSFrançois Tigeot 	enum i915_pipe pipe;
8872c9916cdSFrançois Tigeot 
888*3f2dd94aSFrançois Tigeot 	if (!HAS_PSR(dev_priv))
889*3f2dd94aSFrançois Tigeot 		return;
890*3f2dd94aSFrançois Tigeot 
8912c9916cdSFrançois Tigeot 	mutex_lock(&dev_priv->psr.lock);
8922c9916cdSFrançois Tigeot 	if (!dev_priv->psr.enabled) {
8932c9916cdSFrançois Tigeot 		mutex_unlock(&dev_priv->psr.lock);
8942c9916cdSFrançois Tigeot 		return;
8952c9916cdSFrançois Tigeot 	}
8962c9916cdSFrançois Tigeot 
8972c9916cdSFrançois Tigeot 	crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
8982c9916cdSFrançois Tigeot 	pipe = to_intel_crtc(crtc)->pipe;
899a05eeebfSFrançois Tigeot 
900a05eeebfSFrançois Tigeot 	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
9012c9916cdSFrançois Tigeot 	dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits;
9022c9916cdSFrançois Tigeot 
903aee94f86SFrançois Tigeot 	/* By definition flush = invalidate + flush */
904a05eeebfSFrançois Tigeot 	if (frontbuffer_bits)
90571f41f3eSFrançois Tigeot 		intel_psr_exit(dev_priv);
9062c9916cdSFrançois Tigeot 
9072c9916cdSFrançois Tigeot 	if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits)
908aee94f86SFrançois Tigeot 		if (!work_busy(&dev_priv->psr.work.work))
9092c9916cdSFrançois Tigeot 			schedule_delayed_work(&dev_priv->psr.work,
910aee94f86SFrançois Tigeot 					      msecs_to_jiffies(100));
9112c9916cdSFrançois Tigeot 	mutex_unlock(&dev_priv->psr.lock);
9122c9916cdSFrançois Tigeot }
9132c9916cdSFrançois Tigeot 
9142c9916cdSFrançois Tigeot /**
9152c9916cdSFrançois Tigeot  * intel_psr_init - Init basic PSR work and mutex.
916a85cb24fSFrançois Tigeot  * @dev_priv: i915 device private
9172c9916cdSFrançois Tigeot  *
9182c9916cdSFrançois Tigeot  * This function is  called only once at driver load to initialize basic
9192c9916cdSFrançois Tigeot  * PSR stuff.
9202c9916cdSFrançois Tigeot  */
intel_psr_init(struct drm_i915_private * dev_priv)921a85cb24fSFrançois Tigeot void intel_psr_init(struct drm_i915_private *dev_priv)
9222c9916cdSFrançois Tigeot {
923*3f2dd94aSFrançois Tigeot 	if (!HAS_PSR(dev_priv))
924*3f2dd94aSFrançois Tigeot 		return;
925*3f2dd94aSFrançois Tigeot 
926aee94f86SFrançois Tigeot 	dev_priv->psr_mmio_base = IS_HASWELL(dev_priv) ?
927aee94f86SFrançois Tigeot 		HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE;
928aee94f86SFrançois Tigeot 
9294be47400SFrançois Tigeot 	/* Per platform default: all disabled. */
930*3f2dd94aSFrançois Tigeot 	if (i915_modparams.enable_psr == -1)
931*3f2dd94aSFrançois Tigeot 		i915_modparams.enable_psr = 0;
932c0e85e96SFrançois Tigeot 
933c0e85e96SFrançois Tigeot 	/* Set link_standby x link_off defaults */
9341e12ee3bSFrançois Tigeot 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
935c0e85e96SFrançois Tigeot 		/* HSW and BDW require workarounds that we don't implement. */
936c0e85e96SFrançois Tigeot 		dev_priv->psr.link_standby = false;
9371e12ee3bSFrançois Tigeot 	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
938c0e85e96SFrançois Tigeot 		/* On VLV and CHV only standby mode is supported. */
939c0e85e96SFrançois Tigeot 		dev_priv->psr.link_standby = true;
940c0e85e96SFrançois Tigeot 	else
941c0e85e96SFrançois Tigeot 		/* For new platforms let's respect VBT back again */
942c0e85e96SFrançois Tigeot 		dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link;
943c0e85e96SFrançois Tigeot 
944c0e85e96SFrançois Tigeot 	/* Override link_standby x link_off defaults */
945*3f2dd94aSFrançois Tigeot 	if (i915_modparams.enable_psr == 2 && !dev_priv->psr.link_standby) {
946c0e85e96SFrançois Tigeot 		DRM_DEBUG_KMS("PSR: Forcing link standby\n");
947c0e85e96SFrançois Tigeot 		dev_priv->psr.link_standby = true;
948c0e85e96SFrançois Tigeot 	}
949*3f2dd94aSFrançois Tigeot 	if (i915_modparams.enable_psr == 3 && dev_priv->psr.link_standby) {
950c0e85e96SFrançois Tigeot 		DRM_DEBUG_KMS("PSR: Forcing main link off\n");
951c0e85e96SFrançois Tigeot 		dev_priv->psr.link_standby = false;
952c0e85e96SFrançois Tigeot 	}
953c0e85e96SFrançois Tigeot 
9542c9916cdSFrançois Tigeot 	INIT_DELAYED_WORK(&dev_priv->psr.work, intel_psr_work);
9552c9916cdSFrançois Tigeot 	lockinit(&dev_priv->psr.lock, "i915dpl", 0, LK_CANRECURSE);
956*3f2dd94aSFrançois Tigeot 
957*3f2dd94aSFrançois Tigeot 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
958*3f2dd94aSFrançois Tigeot 		dev_priv->psr.enable_source = vlv_psr_enable_source;
959*3f2dd94aSFrançois Tigeot 		dev_priv->psr.disable_source = vlv_psr_disable;
960*3f2dd94aSFrançois Tigeot 		dev_priv->psr.enable_sink = vlv_psr_enable_sink;
961*3f2dd94aSFrançois Tigeot 		dev_priv->psr.activate = vlv_psr_activate;
962*3f2dd94aSFrançois Tigeot 		dev_priv->psr.setup_vsc = vlv_psr_setup_vsc;
963*3f2dd94aSFrançois Tigeot 	} else {
964*3f2dd94aSFrançois Tigeot 		dev_priv->psr.enable_source = hsw_psr_enable_source;
965*3f2dd94aSFrançois Tigeot 		dev_priv->psr.disable_source = hsw_psr_disable;
966*3f2dd94aSFrançois Tigeot 		dev_priv->psr.enable_sink = hsw_psr_enable_sink;
967*3f2dd94aSFrançois Tigeot 		dev_priv->psr.activate = hsw_psr_activate;
968*3f2dd94aSFrançois Tigeot 		dev_priv->psr.setup_vsc = hsw_psr_setup_vsc;
969*3f2dd94aSFrançois Tigeot 	}
9702c9916cdSFrançois Tigeot }
971