xref: /dflybsd-src/sys/dev/drm/i915/intel_psr.c (revision c62a0e9a6d809af0f2caec1215230a697366e537)
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 
592c9916cdSFrançois Tigeot static bool is_edp_psr(struct intel_dp *intel_dp)
602c9916cdSFrançois Tigeot {
612c9916cdSFrançois Tigeot 	return intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED;
622c9916cdSFrançois Tigeot }
632c9916cdSFrançois Tigeot 
642c9916cdSFrançois Tigeot static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe)
652c9916cdSFrançois Tigeot {
662c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
672c9916cdSFrançois Tigeot 	uint32_t val;
682c9916cdSFrançois Tigeot 
692c9916cdSFrançois Tigeot 	val = I915_READ(VLV_PSRSTAT(pipe)) &
702c9916cdSFrançois Tigeot 	      VLV_EDP_PSR_CURR_STATE_MASK;
712c9916cdSFrançois Tigeot 	return (val == VLV_EDP_PSR_ACTIVE_NORFB_UP) ||
722c9916cdSFrançois Tigeot 	       (val == VLV_EDP_PSR_ACTIVE_SF_UPDATE);
732c9916cdSFrançois Tigeot }
742c9916cdSFrançois Tigeot 
752c9916cdSFrançois Tigeot static void intel_psr_write_vsc(struct intel_dp *intel_dp,
76352ff8bdSFrançois Tigeot 				const struct edp_vsc_psr *vsc_psr)
772c9916cdSFrançois Tigeot {
782c9916cdSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
792c9916cdSFrançois Tigeot 	struct drm_device *dev = dig_port->base.base.dev;
802c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
812c9916cdSFrançois Tigeot 	struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
82352ff8bdSFrançois Tigeot 	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
83aee94f86SFrançois Tigeot 	i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder);
84352ff8bdSFrançois Tigeot 	const uint32_t *data = (const uint32_t *) vsc_psr;
852c9916cdSFrançois Tigeot 	unsigned int i;
862c9916cdSFrançois Tigeot 
872c9916cdSFrançois Tigeot 	/* As per BSPec (Pipe Video Data Island Packet), we need to disable
882c9916cdSFrançois Tigeot 	   the video DIP being updated before program video DIP data buffer
892c9916cdSFrançois Tigeot 	   registers for DIP being updated. */
902c9916cdSFrançois Tigeot 	I915_WRITE(ctl_reg, 0);
912c9916cdSFrançois Tigeot 	POSTING_READ(ctl_reg);
922c9916cdSFrançois Tigeot 
93352ff8bdSFrançois Tigeot 	for (i = 0; i < sizeof(*vsc_psr); i += 4) {
94352ff8bdSFrançois Tigeot 		I915_WRITE(HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder,
95352ff8bdSFrançois Tigeot 						   i >> 2), *data);
96352ff8bdSFrançois Tigeot 		data++;
972c9916cdSFrançois Tigeot 	}
98352ff8bdSFrançois Tigeot 	for (; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4)
99352ff8bdSFrançois Tigeot 		I915_WRITE(HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder,
100352ff8bdSFrançois Tigeot 						   i >> 2), 0);
1012c9916cdSFrançois Tigeot 
1022c9916cdSFrançois Tigeot 	I915_WRITE(ctl_reg, VIDEO_DIP_ENABLE_VSC_HSW);
1032c9916cdSFrançois Tigeot 	POSTING_READ(ctl_reg);
1042c9916cdSFrançois Tigeot }
1052c9916cdSFrançois Tigeot 
1062c9916cdSFrançois Tigeot static void vlv_psr_setup_vsc(struct intel_dp *intel_dp)
1072c9916cdSFrançois Tigeot {
1082c9916cdSFrançois Tigeot 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
1092c9916cdSFrançois Tigeot 	struct drm_device *dev = intel_dig_port->base.base.dev;
1102c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
1112c9916cdSFrançois Tigeot 	struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
1122c9916cdSFrançois Tigeot 	enum i915_pipe pipe = to_intel_crtc(crtc)->pipe;
1132c9916cdSFrançois Tigeot 	uint32_t val;
1142c9916cdSFrançois Tigeot 
1152c9916cdSFrançois Tigeot 	/* VLV auto-generate VSC package as per EDP 1.3 spec, Table 3.10 */
1162c9916cdSFrançois Tigeot 	val  = I915_READ(VLV_VSCSDP(pipe));
1172c9916cdSFrançois Tigeot 	val &= ~VLV_EDP_PSR_SDP_FREQ_MASK;
1182c9916cdSFrançois Tigeot 	val |= VLV_EDP_PSR_SDP_FREQ_EVFRAME;
1192c9916cdSFrançois Tigeot 	I915_WRITE(VLV_VSCSDP(pipe), val);
1202c9916cdSFrançois Tigeot }
1212c9916cdSFrançois Tigeot 
12219c468b4SFrançois Tigeot static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp)
12319c468b4SFrançois Tigeot {
12419c468b4SFrançois Tigeot 	struct edp_vsc_psr psr_vsc;
12519c468b4SFrançois Tigeot 
12619c468b4SFrançois Tigeot 	/* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */
12719c468b4SFrançois Tigeot 	memset(&psr_vsc, 0, sizeof(psr_vsc));
12819c468b4SFrançois Tigeot 	psr_vsc.sdp_header.HB0 = 0;
12919c468b4SFrançois Tigeot 	psr_vsc.sdp_header.HB1 = 0x7;
13019c468b4SFrançois Tigeot 	psr_vsc.sdp_header.HB2 = 0x3;
13119c468b4SFrançois Tigeot 	psr_vsc.sdp_header.HB3 = 0xb;
13219c468b4SFrançois Tigeot 	intel_psr_write_vsc(intel_dp, &psr_vsc);
13319c468b4SFrançois Tigeot }
13419c468b4SFrançois Tigeot 
1352c9916cdSFrançois Tigeot static void hsw_psr_setup_vsc(struct intel_dp *intel_dp)
1362c9916cdSFrançois Tigeot {
1372c9916cdSFrançois Tigeot 	struct edp_vsc_psr psr_vsc;
1382c9916cdSFrançois Tigeot 
1392c9916cdSFrançois Tigeot 	/* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */
1402c9916cdSFrançois Tigeot 	memset(&psr_vsc, 0, sizeof(psr_vsc));
1412c9916cdSFrançois Tigeot 	psr_vsc.sdp_header.HB0 = 0;
1422c9916cdSFrançois Tigeot 	psr_vsc.sdp_header.HB1 = 0x7;
1432c9916cdSFrançois Tigeot 	psr_vsc.sdp_header.HB2 = 0x2;
1442c9916cdSFrançois Tigeot 	psr_vsc.sdp_header.HB3 = 0x8;
1452c9916cdSFrançois Tigeot 	intel_psr_write_vsc(intel_dp, &psr_vsc);
1462c9916cdSFrançois Tigeot }
1472c9916cdSFrançois Tigeot 
1482c9916cdSFrançois Tigeot static void vlv_psr_enable_sink(struct intel_dp *intel_dp)
1492c9916cdSFrançois Tigeot {
1502c9916cdSFrançois Tigeot 	drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
15119c468b4SFrançois Tigeot 			   DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE);
1522c9916cdSFrançois Tigeot }
1532c9916cdSFrançois Tigeot 
154aee94f86SFrançois Tigeot static i915_reg_t psr_aux_ctl_reg(struct drm_i915_private *dev_priv,
155aee94f86SFrançois Tigeot 				       enum port port)
156aee94f86SFrançois Tigeot {
157aee94f86SFrançois Tigeot 	if (INTEL_INFO(dev_priv)->gen >= 9)
158aee94f86SFrançois Tigeot 		return DP_AUX_CH_CTL(port);
159aee94f86SFrançois Tigeot 	else
160aee94f86SFrançois Tigeot 		return EDP_PSR_AUX_CTL;
161aee94f86SFrançois Tigeot }
162aee94f86SFrançois Tigeot 
163aee94f86SFrançois Tigeot static i915_reg_t psr_aux_data_reg(struct drm_i915_private *dev_priv,
164aee94f86SFrançois Tigeot 					enum port port, int index)
165aee94f86SFrançois Tigeot {
166aee94f86SFrançois Tigeot 	if (INTEL_INFO(dev_priv)->gen >= 9)
167aee94f86SFrançois Tigeot 		return DP_AUX_CH_DATA(port, index);
168aee94f86SFrançois Tigeot 	else
169aee94f86SFrançois Tigeot 		return EDP_PSR_AUX_DATA(index);
170aee94f86SFrançois Tigeot }
171aee94f86SFrançois Tigeot 
1722c9916cdSFrançois Tigeot static void hsw_psr_enable_sink(struct intel_dp *intel_dp)
1732c9916cdSFrançois Tigeot {
1742c9916cdSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
1752c9916cdSFrançois Tigeot 	struct drm_device *dev = dig_port->base.base.dev;
1762c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
1772c9916cdSFrançois Tigeot 	uint32_t aux_clock_divider;
178aee94f86SFrançois Tigeot 	i915_reg_t aux_ctl_reg;
1792c9916cdSFrançois Tigeot 	int precharge = 0x3;
1802c9916cdSFrançois Tigeot 	static const uint8_t aux_msg[] = {
1812c9916cdSFrançois Tigeot 		[0] = DP_AUX_NATIVE_WRITE << 4,
1822c9916cdSFrançois Tigeot 		[1] = DP_SET_POWER >> 8,
1832c9916cdSFrançois Tigeot 		[2] = DP_SET_POWER & 0xff,
1842c9916cdSFrançois Tigeot 		[3] = 1 - 1,
1852c9916cdSFrançois Tigeot 		[4] = DP_SET_POWER_D0,
1862c9916cdSFrançois Tigeot 	};
187aee94f86SFrançois Tigeot 	enum port port = dig_port->port;
1882c9916cdSFrançois Tigeot 	int i;
1892c9916cdSFrançois Tigeot 
1902c9916cdSFrançois Tigeot 	BUILD_BUG_ON(sizeof(aux_msg) > 20);
1912c9916cdSFrançois Tigeot 
1922c9916cdSFrançois Tigeot 	aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0);
1932c9916cdSFrançois Tigeot 
19419c468b4SFrançois Tigeot 	/* Enable AUX frame sync at sink */
19519c468b4SFrançois Tigeot 	if (dev_priv->psr.aux_frame_sync)
19619c468b4SFrançois Tigeot 		drm_dp_dpcd_writeb(&intel_dp->aux,
19719c468b4SFrançois Tigeot 				DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF,
19819c468b4SFrançois Tigeot 				DP_AUX_FRAME_SYNC_ENABLE);
19919c468b4SFrançois Tigeot 
200aee94f86SFrançois Tigeot 	aux_ctl_reg = psr_aux_ctl_reg(dev_priv, port);
2012c9916cdSFrançois Tigeot 
2022c9916cdSFrançois Tigeot 	/* Setup AUX registers */
2032c9916cdSFrançois Tigeot 	for (i = 0; i < sizeof(aux_msg); i += 4)
204aee94f86SFrançois Tigeot 		I915_WRITE(psr_aux_data_reg(dev_priv, port, i >> 2),
2052c9916cdSFrançois Tigeot 			   intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i));
2062c9916cdSFrançois Tigeot 
2072c9916cdSFrançois Tigeot 	if (INTEL_INFO(dev)->gen >= 9) {
2082c9916cdSFrançois Tigeot 		uint32_t val;
2092c9916cdSFrançois Tigeot 
2102c9916cdSFrançois Tigeot 		val = I915_READ(aux_ctl_reg);
2112c9916cdSFrançois Tigeot 		val &= ~DP_AUX_CH_CTL_TIME_OUT_MASK;
2122c9916cdSFrançois Tigeot 		val |= DP_AUX_CH_CTL_TIME_OUT_1600us;
2132c9916cdSFrançois Tigeot 		val &= ~DP_AUX_CH_CTL_MESSAGE_SIZE_MASK;
2142c9916cdSFrançois Tigeot 		val |= (sizeof(aux_msg) << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT);
21519c468b4SFrançois Tigeot 		/* Use hardcoded data values for PSR, frame sync and GTC */
2162c9916cdSFrançois Tigeot 		val &= ~DP_AUX_CH_CTL_PSR_DATA_AUX_REG_SKL;
21719c468b4SFrançois Tigeot 		val &= ~DP_AUX_CH_CTL_FS_DATA_AUX_REG_SKL;
21819c468b4SFrançois Tigeot 		val &= ~DP_AUX_CH_CTL_GTC_DATA_AUX_REG_SKL;
2192c9916cdSFrançois Tigeot 		I915_WRITE(aux_ctl_reg, val);
2202c9916cdSFrançois Tigeot 	} else {
2212c9916cdSFrançois Tigeot 		I915_WRITE(aux_ctl_reg,
2222c9916cdSFrançois Tigeot 		   DP_AUX_CH_CTL_TIME_OUT_400us |
2232c9916cdSFrançois Tigeot 		   (sizeof(aux_msg) << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
2242c9916cdSFrançois Tigeot 		   (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
2252c9916cdSFrançois Tigeot 		   (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT));
2262c9916cdSFrançois Tigeot 	}
22719c468b4SFrançois Tigeot 
228c0e85e96SFrançois Tigeot 	if (dev_priv->psr.link_standby)
229c0e85e96SFrançois Tigeot 		drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
230c0e85e96SFrançois Tigeot 				   DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE);
231c0e85e96SFrançois Tigeot 	else
232c0e85e96SFrançois Tigeot 		drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
233c0e85e96SFrançois Tigeot 				   DP_PSR_ENABLE);
2342c9916cdSFrançois Tigeot }
2352c9916cdSFrançois Tigeot 
2362c9916cdSFrançois Tigeot static void vlv_psr_enable_source(struct intel_dp *intel_dp)
2372c9916cdSFrançois Tigeot {
2382c9916cdSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
2392c9916cdSFrançois Tigeot 	struct drm_device *dev = dig_port->base.base.dev;
2402c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
2412c9916cdSFrançois Tigeot 	struct drm_crtc *crtc = dig_port->base.base.crtc;
2422c9916cdSFrançois Tigeot 	enum i915_pipe pipe = to_intel_crtc(crtc)->pipe;
2432c9916cdSFrançois Tigeot 
2442c9916cdSFrançois Tigeot 	/* Transition from PSR_state 0 to PSR_state 1, i.e. PSR Inactive */
2452c9916cdSFrançois Tigeot 	I915_WRITE(VLV_PSRCTL(pipe),
2462c9916cdSFrançois Tigeot 		   VLV_EDP_PSR_MODE_SW_TIMER |
2472c9916cdSFrançois Tigeot 		   VLV_EDP_PSR_SRC_TRANSMITTER_STATE |
2482c9916cdSFrançois Tigeot 		   VLV_EDP_PSR_ENABLE);
2492c9916cdSFrançois Tigeot }
2502c9916cdSFrançois Tigeot 
2512c9916cdSFrançois Tigeot static void vlv_psr_activate(struct intel_dp *intel_dp)
2522c9916cdSFrançois Tigeot {
2532c9916cdSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
2542c9916cdSFrançois Tigeot 	struct drm_device *dev = dig_port->base.base.dev;
2552c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
2562c9916cdSFrançois Tigeot 	struct drm_crtc *crtc = dig_port->base.base.crtc;
2572c9916cdSFrançois Tigeot 	enum i915_pipe pipe = to_intel_crtc(crtc)->pipe;
2582c9916cdSFrançois Tigeot 
2592c9916cdSFrançois Tigeot 	/* Let's do the transition from PSR_state 1 to PSR_state 2
2602c9916cdSFrançois Tigeot 	 * that is PSR transition to active - static frame transmission.
2612c9916cdSFrançois Tigeot 	 * Then Hardware is responsible for the transition to PSR_state 3
2622c9916cdSFrançois Tigeot 	 * that is PSR active - no Remote Frame Buffer (RFB) update.
2632c9916cdSFrançois Tigeot 	 */
2642c9916cdSFrançois Tigeot 	I915_WRITE(VLV_PSRCTL(pipe), I915_READ(VLV_PSRCTL(pipe)) |
2652c9916cdSFrançois Tigeot 		   VLV_EDP_PSR_ACTIVE_ENTRY);
2662c9916cdSFrançois Tigeot }
2672c9916cdSFrançois Tigeot 
2682c9916cdSFrançois Tigeot static void hsw_psr_enable_source(struct intel_dp *intel_dp)
2692c9916cdSFrançois Tigeot {
2702c9916cdSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
2712c9916cdSFrançois Tigeot 	struct drm_device *dev = dig_port->base.base.dev;
2722c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
27319c468b4SFrançois Tigeot 
2742c9916cdSFrançois Tigeot 	uint32_t max_sleep_time = 0x1f;
275aee94f86SFrançois Tigeot 	/*
276aee94f86SFrançois Tigeot 	 * Let's respect VBT in case VBT asks a higher idle_frame value.
277aee94f86SFrançois Tigeot 	 * Let's use 6 as the minimum to cover all known cases including
278aee94f86SFrançois Tigeot 	 * the off-by-one issue that HW has in some cases. Also there are
279aee94f86SFrançois Tigeot 	 * cases where sink should be able to train
280aee94f86SFrançois Tigeot 	 * with the 5 or 6 idle patterns.
2812c9916cdSFrançois Tigeot 	 */
282aee94f86SFrançois Tigeot 	uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
283*c62a0e9aSFrançois Tigeot 	uint32_t val = EDP_PSR_ENABLE;
284*c62a0e9aSFrançois Tigeot 
285*c62a0e9aSFrançois Tigeot 	val |= max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT;
286*c62a0e9aSFrançois Tigeot 	val |= idle_frames << EDP_PSR_IDLE_FRAME_SHIFT;
2872c9916cdSFrançois Tigeot 
288aee94f86SFrançois Tigeot 	if (IS_HASWELL(dev))
289aee94f86SFrançois Tigeot 		val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
2902c9916cdSFrançois Tigeot 
291c0e85e96SFrançois Tigeot 	if (dev_priv->psr.link_standby)
292c0e85e96SFrançois Tigeot 		val |= EDP_PSR_LINK_STANDBY;
293c0e85e96SFrançois Tigeot 
294*c62a0e9aSFrançois Tigeot 	if (dev_priv->vbt.psr.tp1_wakeup_time > 5)
295*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP1_TIME_2500us;
296*c62a0e9aSFrançois Tigeot 	else if (dev_priv->vbt.psr.tp1_wakeup_time > 1)
297*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP1_TIME_500us;
298*c62a0e9aSFrançois Tigeot 	else if (dev_priv->vbt.psr.tp1_wakeup_time > 0)
299*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP1_TIME_100us;
300*c62a0e9aSFrançois Tigeot 	else
301*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP1_TIME_0us;
30219c468b4SFrançois Tigeot 
303*c62a0e9aSFrançois Tigeot 	if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
304*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP2_TP3_TIME_2500us;
305*c62a0e9aSFrançois Tigeot 	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1)
306*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP2_TP3_TIME_500us;
307*c62a0e9aSFrançois Tigeot 	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0)
308*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP2_TP3_TIME_100us;
309*c62a0e9aSFrançois Tigeot 	else
310*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP2_TP3_TIME_0us;
311*c62a0e9aSFrançois Tigeot 
312*c62a0e9aSFrançois Tigeot 	if (intel_dp_source_supports_hbr2(intel_dp) &&
313*c62a0e9aSFrançois Tigeot 	    drm_dp_tps3_supported(intel_dp->dpcd))
314*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP1_TP3_SEL;
315*c62a0e9aSFrançois Tigeot 	else
316*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR_TP1_TP2_SEL;
317*c62a0e9aSFrançois Tigeot 
318*c62a0e9aSFrançois Tigeot 	I915_WRITE(EDP_PSR_CTL, val);
319*c62a0e9aSFrançois Tigeot 
320*c62a0e9aSFrançois Tigeot 	if (!dev_priv->psr.psr2_support)
321*c62a0e9aSFrançois Tigeot 		return;
322*c62a0e9aSFrançois Tigeot 
323*c62a0e9aSFrançois Tigeot 	/* FIXME: selective update is probably totally broken because it doesn't
324*c62a0e9aSFrançois Tigeot 	 * mesh at all with our frontbuffer tracking. And the hw alone isn't
325*c62a0e9aSFrançois Tigeot 	 * good enough. */
326*c62a0e9aSFrançois Tigeot 	val = EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE;
327*c62a0e9aSFrançois Tigeot 
328*c62a0e9aSFrançois Tigeot 	if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
329*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR2_TP2_TIME_2500;
330*c62a0e9aSFrançois Tigeot 	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1)
331*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR2_TP2_TIME_500;
332*c62a0e9aSFrançois Tigeot 	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0)
333*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR2_TP2_TIME_100;
334*c62a0e9aSFrançois Tigeot 	else
335*c62a0e9aSFrançois Tigeot 		val |= EDP_PSR2_TP2_TIME_50;
336*c62a0e9aSFrançois Tigeot 
337*c62a0e9aSFrançois Tigeot 	I915_WRITE(EDP_PSR2_CTL, val);
3382c9916cdSFrançois Tigeot }
3392c9916cdSFrançois Tigeot 
3402c9916cdSFrançois Tigeot static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
3412c9916cdSFrançois Tigeot {
3422c9916cdSFrançois Tigeot 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
3432c9916cdSFrançois Tigeot 	struct drm_device *dev = dig_port->base.base.dev;
3442c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
3452c9916cdSFrançois Tigeot 	struct drm_crtc *crtc = dig_port->base.base.crtc;
3462c9916cdSFrançois Tigeot 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
3472c9916cdSFrançois Tigeot 
3482c9916cdSFrançois Tigeot 	lockdep_assert_held(&dev_priv->psr.lock);
3492c9916cdSFrançois Tigeot 	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
3502c9916cdSFrançois Tigeot 	WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
3512c9916cdSFrançois Tigeot 
3522c9916cdSFrançois Tigeot 	dev_priv->psr.source_ok = false;
3532c9916cdSFrançois Tigeot 
354c0e85e96SFrançois Tigeot 	/*
355c0e85e96SFrançois Tigeot 	 * HSW spec explicitly says PSR is tied to port A.
356c0e85e96SFrançois Tigeot 	 * BDW+ platforms with DDI implementation of PSR have different
357c0e85e96SFrançois Tigeot 	 * PSR registers per transcoder and we only implement transcoder EDP
358c0e85e96SFrançois Tigeot 	 * ones. Since by Display design transcoder EDP is tied to port A
359c0e85e96SFrançois Tigeot 	 * we can safely escape based on the port A.
360c0e85e96SFrançois Tigeot 	 */
361c0e85e96SFrançois Tigeot 	if (HAS_DDI(dev) && dig_port->port != PORT_A) {
362c0e85e96SFrançois Tigeot 		DRM_DEBUG_KMS("PSR condition failed: Port not supported\n");
3632c9916cdSFrançois Tigeot 		return false;
3642c9916cdSFrançois Tigeot 	}
3652c9916cdSFrançois Tigeot 
3662c9916cdSFrançois Tigeot 	if (!i915.enable_psr) {
3672c9916cdSFrançois Tigeot 		DRM_DEBUG_KMS("PSR disable by flag\n");
3682c9916cdSFrançois Tigeot 		return false;
3692c9916cdSFrançois Tigeot 	}
3702c9916cdSFrançois Tigeot 
371c0e85e96SFrançois Tigeot 	if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
372c0e85e96SFrançois Tigeot 	    !dev_priv->psr.link_standby) {
373c0e85e96SFrançois Tigeot 		DRM_ERROR("PSR condition failed: Link off requested but not supported on this platform\n");
374c0e85e96SFrançois Tigeot 		return false;
375c0e85e96SFrançois Tigeot 	}
376c0e85e96SFrançois Tigeot 
3772c9916cdSFrançois Tigeot 	if (IS_HASWELL(dev) &&
3782c9916cdSFrançois Tigeot 	    I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config->cpu_transcoder)) &
3792c9916cdSFrançois Tigeot 		      S3D_ENABLE) {
3802c9916cdSFrançois Tigeot 		DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n");
3812c9916cdSFrançois Tigeot 		return false;
3822c9916cdSFrançois Tigeot 	}
3832c9916cdSFrançois Tigeot 
3842c9916cdSFrançois Tigeot 	if (IS_HASWELL(dev) &&
3852c9916cdSFrançois Tigeot 	    intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
3862c9916cdSFrançois Tigeot 		DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n");
3872c9916cdSFrançois Tigeot 		return false;
3882c9916cdSFrançois Tigeot 	}
3892c9916cdSFrançois Tigeot 
3902c9916cdSFrançois Tigeot 	dev_priv->psr.source_ok = true;
3912c9916cdSFrançois Tigeot 	return true;
3922c9916cdSFrançois Tigeot }
3932c9916cdSFrançois Tigeot 
3942c9916cdSFrançois Tigeot static void intel_psr_activate(struct intel_dp *intel_dp)
3952c9916cdSFrançois Tigeot {
3962c9916cdSFrançois Tigeot 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
3972c9916cdSFrançois Tigeot 	struct drm_device *dev = intel_dig_port->base.base.dev;
3982c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
3992c9916cdSFrançois Tigeot 
400aee94f86SFrançois Tigeot 	WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
4012c9916cdSFrançois Tigeot 	WARN_ON(dev_priv->psr.active);
4022c9916cdSFrançois Tigeot 	lockdep_assert_held(&dev_priv->psr.lock);
4032c9916cdSFrançois Tigeot 
4042c9916cdSFrançois Tigeot 	/* Enable/Re-enable PSR on the host */
4052c9916cdSFrançois Tigeot 	if (HAS_DDI(dev))
4062c9916cdSFrançois Tigeot 		/* On HSW+ after we enable PSR on source it will activate it
4072c9916cdSFrançois Tigeot 		 * as soon as it match configure idle_frame count. So
4082c9916cdSFrançois Tigeot 		 * we just actually enable it here on activation time.
4092c9916cdSFrançois Tigeot 		 */
4102c9916cdSFrançois Tigeot 		hsw_psr_enable_source(intel_dp);
4112c9916cdSFrançois Tigeot 	else
4122c9916cdSFrançois Tigeot 		vlv_psr_activate(intel_dp);
4132c9916cdSFrançois Tigeot 
4142c9916cdSFrançois Tigeot 	dev_priv->psr.active = true;
4152c9916cdSFrançois Tigeot }
4162c9916cdSFrançois Tigeot 
4172c9916cdSFrançois Tigeot /**
4182c9916cdSFrançois Tigeot  * intel_psr_enable - Enable PSR
4192c9916cdSFrançois Tigeot  * @intel_dp: Intel DP
4202c9916cdSFrançois Tigeot  *
4212c9916cdSFrançois Tigeot  * This function can only be called after the pipe is fully trained and enabled.
4222c9916cdSFrançois Tigeot  */
4232c9916cdSFrançois Tigeot void intel_psr_enable(struct intel_dp *intel_dp)
4242c9916cdSFrançois Tigeot {
4252c9916cdSFrançois Tigeot 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
4262c9916cdSFrançois Tigeot 	struct drm_device *dev = intel_dig_port->base.base.dev;
4272c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
42819c468b4SFrançois Tigeot 	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
4292c9916cdSFrançois Tigeot 
4302c9916cdSFrançois Tigeot 	if (!HAS_PSR(dev)) {
4312c9916cdSFrançois Tigeot 		DRM_DEBUG_KMS("PSR not supported on this platform\n");
4322c9916cdSFrançois Tigeot 		return;
4332c9916cdSFrançois Tigeot 	}
4342c9916cdSFrançois Tigeot 
4352c9916cdSFrançois Tigeot 	if (!is_edp_psr(intel_dp)) {
4362c9916cdSFrançois Tigeot 		DRM_DEBUG_KMS("PSR not supported by this panel\n");
4372c9916cdSFrançois Tigeot 		return;
4382c9916cdSFrançois Tigeot 	}
4392c9916cdSFrançois Tigeot 
4402c9916cdSFrançois Tigeot 	mutex_lock(&dev_priv->psr.lock);
4412c9916cdSFrançois Tigeot 	if (dev_priv->psr.enabled) {
4422c9916cdSFrançois Tigeot 		DRM_DEBUG_KMS("PSR already in use\n");
4432c9916cdSFrançois Tigeot 		goto unlock;
4442c9916cdSFrançois Tigeot 	}
4452c9916cdSFrançois Tigeot 
4462c9916cdSFrançois Tigeot 	if (!intel_psr_match_conditions(intel_dp))
4472c9916cdSFrançois Tigeot 		goto unlock;
4482c9916cdSFrançois Tigeot 
4492c9916cdSFrançois Tigeot 	dev_priv->psr.busy_frontbuffer_bits = 0;
4502c9916cdSFrançois Tigeot 
4512c9916cdSFrançois Tigeot 	if (HAS_DDI(dev)) {
4522c9916cdSFrançois Tigeot 		hsw_psr_setup_vsc(intel_dp);
4532c9916cdSFrançois Tigeot 
45419c468b4SFrançois Tigeot 		if (dev_priv->psr.psr2_support) {
45519c468b4SFrançois Tigeot 			/* PSR2 is restricted to work with panel resolutions upto 3200x2000 */
45619c468b4SFrançois Tigeot 			if (crtc->config->pipe_src_w > 3200 ||
45719c468b4SFrançois Tigeot 				crtc->config->pipe_src_h > 2000)
45819c468b4SFrançois Tigeot 				dev_priv->psr.psr2_support = false;
45919c468b4SFrançois Tigeot 			else
46019c468b4SFrançois Tigeot 				skl_psr_setup_su_vsc(intel_dp);
46119c468b4SFrançois Tigeot 		}
46219c468b4SFrançois Tigeot 
463aee94f86SFrançois Tigeot 		/*
464aee94f86SFrançois Tigeot 		 * Per Spec: Avoid continuous PSR exit by masking MEMUP and HPD.
465aee94f86SFrançois Tigeot 		 * Also mask LPSP to avoid dependency on other drivers that
466aee94f86SFrançois Tigeot 		 * might block runtime_pm besides preventing other hw tracking
467aee94f86SFrançois Tigeot 		 * issues now we can rely on frontbuffer tracking.
468aee94f86SFrançois Tigeot 		 */
469aee94f86SFrançois Tigeot 		I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP |
470aee94f86SFrançois Tigeot 			   EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP);
4712c9916cdSFrançois Tigeot 
4722c9916cdSFrançois Tigeot 		/* Enable PSR on the panel */
4732c9916cdSFrançois Tigeot 		hsw_psr_enable_sink(intel_dp);
4742c9916cdSFrançois Tigeot 
4752c9916cdSFrançois Tigeot 		if (INTEL_INFO(dev)->gen >= 9)
4762c9916cdSFrançois Tigeot 			intel_psr_activate(intel_dp);
4772c9916cdSFrançois Tigeot 	} else {
4782c9916cdSFrançois Tigeot 		vlv_psr_setup_vsc(intel_dp);
4792c9916cdSFrançois Tigeot 
4802c9916cdSFrançois Tigeot 		/* Enable PSR on the panel */
4812c9916cdSFrançois Tigeot 		vlv_psr_enable_sink(intel_dp);
4822c9916cdSFrançois Tigeot 
4832c9916cdSFrançois Tigeot 		/* On HSW+ enable_source also means go to PSR entry/active
4842c9916cdSFrançois Tigeot 		 * state as soon as idle_frame achieved and here would be
4852c9916cdSFrançois Tigeot 		 * to soon. However on VLV enable_source just enable PSR
4862c9916cdSFrançois Tigeot 		 * but let it on inactive state. So we might do this prior
4872c9916cdSFrançois Tigeot 		 * to active transition, i.e. here.
4882c9916cdSFrançois Tigeot 		 */
4892c9916cdSFrançois Tigeot 		vlv_psr_enable_source(intel_dp);
4902c9916cdSFrançois Tigeot 	}
4912c9916cdSFrançois Tigeot 
492aee94f86SFrançois Tigeot 	/*
493aee94f86SFrançois Tigeot 	 * FIXME: Activation should happen immediately since this function
494aee94f86SFrançois Tigeot 	 * is just called after pipe is fully trained and enabled.
495aee94f86SFrançois Tigeot 	 * However on every platform we face issues when first activation
496aee94f86SFrançois Tigeot 	 * follows a modeset so quickly.
497aee94f86SFrançois Tigeot 	 *     - On VLV/CHV we get bank screen on first activation
498aee94f86SFrançois Tigeot 	 *     - On HSW/BDW we get a recoverable frozen screen until next
499aee94f86SFrançois Tigeot 	 *       exit-activate sequence.
500aee94f86SFrançois Tigeot 	 */
501aee94f86SFrançois Tigeot 	if (INTEL_INFO(dev)->gen < 9)
502aee94f86SFrançois Tigeot 		schedule_delayed_work(&dev_priv->psr.work,
503aee94f86SFrançois Tigeot 				      msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5));
504aee94f86SFrançois Tigeot 
5052c9916cdSFrançois Tigeot 	dev_priv->psr.enabled = intel_dp;
5062c9916cdSFrançois Tigeot unlock:
5072c9916cdSFrançois Tigeot 	mutex_unlock(&dev_priv->psr.lock);
5082c9916cdSFrançois Tigeot }
5092c9916cdSFrançois Tigeot 
5102c9916cdSFrançois Tigeot static void vlv_psr_disable(struct intel_dp *intel_dp)
5112c9916cdSFrançois Tigeot {
5122c9916cdSFrançois Tigeot 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
5132c9916cdSFrançois Tigeot 	struct drm_device *dev = intel_dig_port->base.base.dev;
5142c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
5152c9916cdSFrançois Tigeot 	struct intel_crtc *intel_crtc =
5162c9916cdSFrançois Tigeot 		to_intel_crtc(intel_dig_port->base.base.crtc);
5172c9916cdSFrançois Tigeot 	uint32_t val;
5182c9916cdSFrançois Tigeot 
5192c9916cdSFrançois Tigeot 	if (dev_priv->psr.active) {
5202c9916cdSFrançois Tigeot 		/* Put VLV PSR back to PSR_state 0 that is PSR Disabled. */
5212c9916cdSFrançois Tigeot 		if (wait_for((I915_READ(VLV_PSRSTAT(intel_crtc->pipe)) &
5222c9916cdSFrançois Tigeot 			      VLV_EDP_PSR_IN_TRANS) == 0, 1))
5232c9916cdSFrançois Tigeot 			WARN(1, "PSR transition took longer than expected\n");
5242c9916cdSFrançois Tigeot 
5252c9916cdSFrançois Tigeot 		val = I915_READ(VLV_PSRCTL(intel_crtc->pipe));
5262c9916cdSFrançois Tigeot 		val &= ~VLV_EDP_PSR_ACTIVE_ENTRY;
5272c9916cdSFrançois Tigeot 		val &= ~VLV_EDP_PSR_ENABLE;
5282c9916cdSFrançois Tigeot 		val &= ~VLV_EDP_PSR_MODE_MASK;
5292c9916cdSFrançois Tigeot 		I915_WRITE(VLV_PSRCTL(intel_crtc->pipe), val);
5302c9916cdSFrançois Tigeot 
5312c9916cdSFrançois Tigeot 		dev_priv->psr.active = false;
5322c9916cdSFrançois Tigeot 	} else {
5332c9916cdSFrançois Tigeot 		WARN_ON(vlv_is_psr_active_on_pipe(dev, intel_crtc->pipe));
5342c9916cdSFrançois Tigeot 	}
5352c9916cdSFrançois Tigeot }
5362c9916cdSFrançois Tigeot 
5372c9916cdSFrançois Tigeot static void hsw_psr_disable(struct intel_dp *intel_dp)
5382c9916cdSFrançois Tigeot {
5392c9916cdSFrançois Tigeot 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
5402c9916cdSFrançois Tigeot 	struct drm_device *dev = intel_dig_port->base.base.dev;
5412c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
5422c9916cdSFrançois Tigeot 
5432c9916cdSFrançois Tigeot 	if (dev_priv->psr.active) {
544aee94f86SFrançois Tigeot 		I915_WRITE(EDP_PSR_CTL,
545aee94f86SFrançois Tigeot 			   I915_READ(EDP_PSR_CTL) & ~EDP_PSR_ENABLE);
5462c9916cdSFrançois Tigeot 
5472c9916cdSFrançois Tigeot 		/* Wait till PSR is idle */
548aee94f86SFrançois Tigeot 		if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) &
5492c9916cdSFrançois Tigeot 			       EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10))
5502c9916cdSFrançois Tigeot 			DRM_ERROR("Timed out waiting for PSR Idle State\n");
5512c9916cdSFrançois Tigeot 
5522c9916cdSFrançois Tigeot 		dev_priv->psr.active = false;
5532c9916cdSFrançois Tigeot 	} else {
554aee94f86SFrançois Tigeot 		WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
5552c9916cdSFrançois Tigeot 	}
5562c9916cdSFrançois Tigeot }
5572c9916cdSFrançois Tigeot 
5582c9916cdSFrançois Tigeot /**
5592c9916cdSFrançois Tigeot  * intel_psr_disable - Disable PSR
5602c9916cdSFrançois Tigeot  * @intel_dp: Intel DP
5612c9916cdSFrançois Tigeot  *
5622c9916cdSFrançois Tigeot  * This function needs to be called before disabling pipe.
5632c9916cdSFrançois Tigeot  */
5642c9916cdSFrançois Tigeot void intel_psr_disable(struct intel_dp *intel_dp)
5652c9916cdSFrançois Tigeot {
5662c9916cdSFrançois Tigeot 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
5672c9916cdSFrançois Tigeot 	struct drm_device *dev = intel_dig_port->base.base.dev;
5682c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
5692c9916cdSFrançois Tigeot 
5702c9916cdSFrançois Tigeot 	mutex_lock(&dev_priv->psr.lock);
5712c9916cdSFrançois Tigeot 	if (!dev_priv->psr.enabled) {
5722c9916cdSFrançois Tigeot 		mutex_unlock(&dev_priv->psr.lock);
5732c9916cdSFrançois Tigeot 		return;
5742c9916cdSFrançois Tigeot 	}
5752c9916cdSFrançois Tigeot 
576aee94f86SFrançois Tigeot 	/* Disable PSR on Source */
5772c9916cdSFrançois Tigeot 	if (HAS_DDI(dev))
5782c9916cdSFrançois Tigeot 		hsw_psr_disable(intel_dp);
5792c9916cdSFrançois Tigeot 	else
5802c9916cdSFrançois Tigeot 		vlv_psr_disable(intel_dp);
5812c9916cdSFrançois Tigeot 
582aee94f86SFrançois Tigeot 	/* Disable PSR on Sink */
583aee94f86SFrançois Tigeot 	drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
584aee94f86SFrançois Tigeot 
5852c9916cdSFrançois Tigeot 	dev_priv->psr.enabled = NULL;
5862c9916cdSFrançois Tigeot 	mutex_unlock(&dev_priv->psr.lock);
5872c9916cdSFrançois Tigeot 
5882c9916cdSFrançois Tigeot 	cancel_delayed_work_sync(&dev_priv->psr.work);
5892c9916cdSFrançois Tigeot }
5902c9916cdSFrançois Tigeot 
5912c9916cdSFrançois Tigeot static void intel_psr_work(struct work_struct *work)
5922c9916cdSFrançois Tigeot {
5932c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv =
5942c9916cdSFrançois Tigeot 		container_of(work, typeof(*dev_priv), psr.work.work);
5952c9916cdSFrançois Tigeot 	struct intel_dp *intel_dp = dev_priv->psr.enabled;
5962c9916cdSFrançois Tigeot 	struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
5972c9916cdSFrançois Tigeot 	enum i915_pipe pipe = to_intel_crtc(crtc)->pipe;
5982c9916cdSFrançois Tigeot 
5992c9916cdSFrançois Tigeot 	/* We have to make sure PSR is ready for re-enable
6002c9916cdSFrançois Tigeot 	 * otherwise it keeps disabled until next full enable/disable cycle.
6012c9916cdSFrançois Tigeot 	 * PSR might take some time to get fully disabled
6022c9916cdSFrançois Tigeot 	 * and be ready for re-enable.
6032c9916cdSFrançois Tigeot 	 */
6042c9916cdSFrançois Tigeot 	if (HAS_DDI(dev_priv->dev)) {
605aee94f86SFrançois Tigeot 		if (wait_for((I915_READ(EDP_PSR_STATUS_CTL) &
6062c9916cdSFrançois Tigeot 			      EDP_PSR_STATUS_STATE_MASK) == 0, 50)) {
6072c9916cdSFrançois Tigeot 			DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n");
6082c9916cdSFrançois Tigeot 			return;
6092c9916cdSFrançois Tigeot 		}
6102c9916cdSFrançois Tigeot 	} else {
6112c9916cdSFrançois Tigeot 		if (wait_for((I915_READ(VLV_PSRSTAT(pipe)) &
6122c9916cdSFrançois Tigeot 			      VLV_EDP_PSR_IN_TRANS) == 0, 1)) {
6132c9916cdSFrançois Tigeot 			DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n");
6142c9916cdSFrançois Tigeot 			return;
6152c9916cdSFrançois Tigeot 		}
6162c9916cdSFrançois Tigeot 	}
6172c9916cdSFrançois Tigeot 	mutex_lock(&dev_priv->psr.lock);
6182c9916cdSFrançois Tigeot 	intel_dp = dev_priv->psr.enabled;
6192c9916cdSFrançois Tigeot 
6202c9916cdSFrançois Tigeot 	if (!intel_dp)
6212c9916cdSFrançois Tigeot 		goto unlock;
6222c9916cdSFrançois Tigeot 
6232c9916cdSFrançois Tigeot 	/*
6242c9916cdSFrançois Tigeot 	 * The delayed work can race with an invalidate hence we need to
6252c9916cdSFrançois Tigeot 	 * recheck. Since psr_flush first clears this and then reschedules we
6262c9916cdSFrançois Tigeot 	 * won't ever miss a flush when bailing out here.
6272c9916cdSFrançois Tigeot 	 */
6282c9916cdSFrançois Tigeot 	if (dev_priv->psr.busy_frontbuffer_bits)
6292c9916cdSFrançois Tigeot 		goto unlock;
6302c9916cdSFrançois Tigeot 
6312c9916cdSFrançois Tigeot 	intel_psr_activate(intel_dp);
6322c9916cdSFrançois Tigeot unlock:
6332c9916cdSFrançois Tigeot 	mutex_unlock(&dev_priv->psr.lock);
6342c9916cdSFrançois Tigeot }
6352c9916cdSFrançois Tigeot 
6362c9916cdSFrançois Tigeot static void intel_psr_exit(struct drm_device *dev)
6372c9916cdSFrançois Tigeot {
6382c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
6392c9916cdSFrançois Tigeot 	struct intel_dp *intel_dp = dev_priv->psr.enabled;
6402c9916cdSFrançois Tigeot 	struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc;
6412c9916cdSFrançois Tigeot 	enum i915_pipe pipe = to_intel_crtc(crtc)->pipe;
6422c9916cdSFrançois Tigeot 	u32 val;
6432c9916cdSFrançois Tigeot 
6442c9916cdSFrançois Tigeot 	if (!dev_priv->psr.active)
6452c9916cdSFrançois Tigeot 		return;
6462c9916cdSFrançois Tigeot 
6472c9916cdSFrançois Tigeot 	if (HAS_DDI(dev)) {
648aee94f86SFrançois Tigeot 		val = I915_READ(EDP_PSR_CTL);
6492c9916cdSFrançois Tigeot 
6502c9916cdSFrançois Tigeot 		WARN_ON(!(val & EDP_PSR_ENABLE));
6512c9916cdSFrançois Tigeot 
652aee94f86SFrançois Tigeot 		I915_WRITE(EDP_PSR_CTL, val & ~EDP_PSR_ENABLE);
6532c9916cdSFrançois Tigeot 	} else {
6542c9916cdSFrançois Tigeot 		val = I915_READ(VLV_PSRCTL(pipe));
6552c9916cdSFrançois Tigeot 
6562c9916cdSFrançois Tigeot 		/* Here we do the transition from PSR_state 3 to PSR_state 5
6572c9916cdSFrançois Tigeot 		 * directly once PSR State 4 that is active with single frame
6582c9916cdSFrançois Tigeot 		 * update can be skipped. PSR_state 5 that is PSR exit then
6592c9916cdSFrançois Tigeot 		 * Hardware is responsible to transition back to PSR_state 1
6602c9916cdSFrançois Tigeot 		 * that is PSR inactive. Same state after
6612c9916cdSFrançois Tigeot 		 * vlv_edp_psr_enable_source.
6622c9916cdSFrançois Tigeot 		 */
6632c9916cdSFrançois Tigeot 		val &= ~VLV_EDP_PSR_ACTIVE_ENTRY;
6642c9916cdSFrançois Tigeot 		I915_WRITE(VLV_PSRCTL(pipe), val);
6652c9916cdSFrançois Tigeot 
6662c9916cdSFrançois Tigeot 		/* Send AUX wake up - Spec says after transitioning to PSR
6672c9916cdSFrançois Tigeot 		 * active we have to send AUX wake up by writing 01h in DPCD
6682c9916cdSFrançois Tigeot 		 * 600h of sink device.
6692c9916cdSFrançois Tigeot 		 * XXX: This might slow down the transition, but without this
6702c9916cdSFrançois Tigeot 		 * HW doesn't complete the transition to PSR_state 1 and we
6712c9916cdSFrançois Tigeot 		 * never get the screen updated.
6722c9916cdSFrançois Tigeot 		 */
6732c9916cdSFrançois Tigeot 		drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER,
6742c9916cdSFrançois Tigeot 				   DP_SET_POWER_D0);
6752c9916cdSFrançois Tigeot 	}
6762c9916cdSFrançois Tigeot 
6772c9916cdSFrançois Tigeot 	dev_priv->psr.active = false;
6782c9916cdSFrançois Tigeot }
6792c9916cdSFrançois Tigeot 
6802c9916cdSFrançois Tigeot /**
68119c468b4SFrançois Tigeot  * intel_psr_single_frame_update - Single Frame Update
68219c468b4SFrançois Tigeot  * @dev: DRM device
683a05eeebfSFrançois Tigeot  * @frontbuffer_bits: frontbuffer plane tracking bits
68419c468b4SFrançois Tigeot  *
68519c468b4SFrançois Tigeot  * Some platforms support a single frame update feature that is used to
68619c468b4SFrançois Tigeot  * send and update only one frame on Remote Frame Buffer.
68719c468b4SFrançois Tigeot  * So far it is only implemented for Valleyview and Cherryview because
68819c468b4SFrançois Tigeot  * hardware requires this to be done before a page flip.
68919c468b4SFrançois Tigeot  */
690a05eeebfSFrançois Tigeot void intel_psr_single_frame_update(struct drm_device *dev,
691a05eeebfSFrançois Tigeot 				   unsigned frontbuffer_bits)
69219c468b4SFrançois Tigeot {
69319c468b4SFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
69419c468b4SFrançois Tigeot 	struct drm_crtc *crtc;
69519c468b4SFrançois Tigeot 	enum i915_pipe pipe;
69619c468b4SFrançois Tigeot 	u32 val;
69719c468b4SFrançois Tigeot 
69819c468b4SFrançois Tigeot 	/*
69919c468b4SFrançois Tigeot 	 * Single frame update is already supported on BDW+ but it requires
70019c468b4SFrançois Tigeot 	 * many W/A and it isn't really needed.
70119c468b4SFrançois Tigeot 	 */
702aee94f86SFrançois Tigeot 	if (!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev))
70319c468b4SFrançois Tigeot 		return;
70419c468b4SFrançois Tigeot 
70519c468b4SFrançois Tigeot 	mutex_lock(&dev_priv->psr.lock);
70619c468b4SFrançois Tigeot 	if (!dev_priv->psr.enabled) {
70719c468b4SFrançois Tigeot 		mutex_unlock(&dev_priv->psr.lock);
70819c468b4SFrançois Tigeot 		return;
70919c468b4SFrançois Tigeot 	}
71019c468b4SFrançois Tigeot 
71119c468b4SFrançois Tigeot 	crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
71219c468b4SFrançois Tigeot 	pipe = to_intel_crtc(crtc)->pipe;
713a05eeebfSFrançois Tigeot 
714a05eeebfSFrançois Tigeot 	if (frontbuffer_bits & INTEL_FRONTBUFFER_ALL_MASK(pipe)) {
71519c468b4SFrançois Tigeot 		val = I915_READ(VLV_PSRCTL(pipe));
71619c468b4SFrançois Tigeot 
71719c468b4SFrançois Tigeot 		/*
71819c468b4SFrançois Tigeot 		 * We need to set this bit before writing registers for a flip.
71919c468b4SFrançois Tigeot 		 * This bit will be self-clear when it gets to the PSR active state.
72019c468b4SFrançois Tigeot 		 */
72119c468b4SFrançois Tigeot 		I915_WRITE(VLV_PSRCTL(pipe), val | VLV_EDP_PSR_SINGLE_FRAME_UPDATE);
722a05eeebfSFrançois Tigeot 	}
72319c468b4SFrançois Tigeot 	mutex_unlock(&dev_priv->psr.lock);
72419c468b4SFrançois Tigeot }
72519c468b4SFrançois Tigeot 
72619c468b4SFrançois Tigeot /**
7272c9916cdSFrançois Tigeot  * intel_psr_invalidate - Invalidade PSR
7282c9916cdSFrançois Tigeot  * @dev: DRM device
7292c9916cdSFrançois Tigeot  * @frontbuffer_bits: frontbuffer plane tracking bits
7302c9916cdSFrançois Tigeot  *
7312c9916cdSFrançois Tigeot  * Since the hardware frontbuffer tracking has gaps we need to integrate
7322c9916cdSFrançois Tigeot  * with the software frontbuffer tracking. This function gets called every
7332c9916cdSFrançois Tigeot  * time frontbuffer rendering starts and a buffer gets dirtied. PSR must be
7342c9916cdSFrançois Tigeot  * disabled if the frontbuffer mask contains a buffer relevant to PSR.
7352c9916cdSFrançois Tigeot  *
7362c9916cdSFrançois Tigeot  * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits."
7372c9916cdSFrançois Tigeot  */
7382c9916cdSFrançois Tigeot void intel_psr_invalidate(struct drm_device *dev,
7392c9916cdSFrançois Tigeot 			  unsigned frontbuffer_bits)
7402c9916cdSFrançois Tigeot {
7412c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
7422c9916cdSFrançois Tigeot 	struct drm_crtc *crtc;
7432c9916cdSFrançois Tigeot 	enum i915_pipe pipe;
7442c9916cdSFrançois Tigeot 
7452c9916cdSFrançois Tigeot 	mutex_lock(&dev_priv->psr.lock);
7462c9916cdSFrançois Tigeot 	if (!dev_priv->psr.enabled) {
7472c9916cdSFrançois Tigeot 		mutex_unlock(&dev_priv->psr.lock);
7482c9916cdSFrançois Tigeot 		return;
7492c9916cdSFrançois Tigeot 	}
7502c9916cdSFrançois Tigeot 
7512c9916cdSFrançois Tigeot 	crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
7522c9916cdSFrançois Tigeot 	pipe = to_intel_crtc(crtc)->pipe;
7532c9916cdSFrançois Tigeot 
754a05eeebfSFrançois Tigeot 	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
755a05eeebfSFrançois Tigeot 	dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits;
756a05eeebfSFrançois Tigeot 
757a05eeebfSFrançois Tigeot 	if (frontbuffer_bits)
7582c9916cdSFrançois Tigeot 		intel_psr_exit(dev);
7592c9916cdSFrançois Tigeot 
7602c9916cdSFrançois Tigeot 	mutex_unlock(&dev_priv->psr.lock);
7612c9916cdSFrançois Tigeot }
7622c9916cdSFrançois Tigeot 
7632c9916cdSFrançois Tigeot /**
7642c9916cdSFrançois Tigeot  * intel_psr_flush - Flush PSR
7652c9916cdSFrançois Tigeot  * @dev: DRM device
7662c9916cdSFrançois Tigeot  * @frontbuffer_bits: frontbuffer plane tracking bits
767a05eeebfSFrançois Tigeot  * @origin: which operation caused the flush
7682c9916cdSFrançois Tigeot  *
7692c9916cdSFrançois Tigeot  * Since the hardware frontbuffer tracking has gaps we need to integrate
7702c9916cdSFrançois Tigeot  * with the software frontbuffer tracking. This function gets called every
7712c9916cdSFrançois Tigeot  * time frontbuffer rendering has completed and flushed out to memory. PSR
7722c9916cdSFrançois Tigeot  * can be enabled again if no other frontbuffer relevant to PSR is dirty.
7732c9916cdSFrançois Tigeot  *
7742c9916cdSFrançois Tigeot  * Dirty frontbuffers relevant to PSR are tracked in busy_frontbuffer_bits.
7752c9916cdSFrançois Tigeot  */
7762c9916cdSFrançois Tigeot void intel_psr_flush(struct drm_device *dev,
777a05eeebfSFrançois Tigeot 		     unsigned frontbuffer_bits, enum fb_op_origin origin)
7782c9916cdSFrançois Tigeot {
7792c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
7802c9916cdSFrançois Tigeot 	struct drm_crtc *crtc;
7812c9916cdSFrançois Tigeot 	enum i915_pipe pipe;
7822c9916cdSFrançois Tigeot 
7832c9916cdSFrançois Tigeot 	mutex_lock(&dev_priv->psr.lock);
7842c9916cdSFrançois Tigeot 	if (!dev_priv->psr.enabled) {
7852c9916cdSFrançois Tigeot 		mutex_unlock(&dev_priv->psr.lock);
7862c9916cdSFrançois Tigeot 		return;
7872c9916cdSFrançois Tigeot 	}
7882c9916cdSFrançois Tigeot 
7892c9916cdSFrançois Tigeot 	crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
7902c9916cdSFrançois Tigeot 	pipe = to_intel_crtc(crtc)->pipe;
791a05eeebfSFrançois Tigeot 
792a05eeebfSFrançois Tigeot 	frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
7932c9916cdSFrançois Tigeot 	dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits;
7942c9916cdSFrançois Tigeot 
795aee94f86SFrançois Tigeot 	/* By definition flush = invalidate + flush */
796a05eeebfSFrançois Tigeot 	if (frontbuffer_bits)
7972c9916cdSFrançois Tigeot 		intel_psr_exit(dev);
7982c9916cdSFrançois Tigeot 
7992c9916cdSFrançois Tigeot 	if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits)
800aee94f86SFrançois Tigeot #if 0
801aee94f86SFrançois Tigeot 		if (!work_busy(&dev_priv->psr.work.work))
802aee94f86SFrançois Tigeot #endif
8032c9916cdSFrançois Tigeot 			schedule_delayed_work(&dev_priv->psr.work,
804aee94f86SFrançois Tigeot 					      msecs_to_jiffies(100));
8052c9916cdSFrançois Tigeot 	mutex_unlock(&dev_priv->psr.lock);
8062c9916cdSFrançois Tigeot }
8072c9916cdSFrançois Tigeot 
8082c9916cdSFrançois Tigeot /**
8092c9916cdSFrançois Tigeot  * intel_psr_init - Init basic PSR work and mutex.
8102c9916cdSFrançois Tigeot  * @dev: DRM device
8112c9916cdSFrançois Tigeot  *
8122c9916cdSFrançois Tigeot  * This function is  called only once at driver load to initialize basic
8132c9916cdSFrançois Tigeot  * PSR stuff.
8142c9916cdSFrançois Tigeot  */
8152c9916cdSFrançois Tigeot void intel_psr_init(struct drm_device *dev)
8162c9916cdSFrançois Tigeot {
8172c9916cdSFrançois Tigeot 	struct drm_i915_private *dev_priv = dev->dev_private;
8182c9916cdSFrançois Tigeot 
819aee94f86SFrançois Tigeot 	dev_priv->psr_mmio_base = IS_HASWELL(dev_priv) ?
820aee94f86SFrançois Tigeot 		HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE;
821aee94f86SFrançois Tigeot 
822c0e85e96SFrançois Tigeot 	/* Per platform default */
823c0e85e96SFrançois Tigeot 	if (i915.enable_psr == -1) {
824c0e85e96SFrançois Tigeot 		if (IS_HASWELL(dev) || IS_BROADWELL(dev) ||
825c0e85e96SFrançois Tigeot 		    IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
826c0e85e96SFrançois Tigeot 			i915.enable_psr = 1;
827c0e85e96SFrançois Tigeot 		else
828c0e85e96SFrançois Tigeot 			i915.enable_psr = 0;
829c0e85e96SFrançois Tigeot 	}
830c0e85e96SFrançois Tigeot 
831c0e85e96SFrançois Tigeot 	/* Set link_standby x link_off defaults */
832c0e85e96SFrançois Tigeot 	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
833c0e85e96SFrançois Tigeot 		/* HSW and BDW require workarounds that we don't implement. */
834c0e85e96SFrançois Tigeot 		dev_priv->psr.link_standby = false;
835c0e85e96SFrançois Tigeot 	else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
836c0e85e96SFrançois Tigeot 		/* On VLV and CHV only standby mode is supported. */
837c0e85e96SFrançois Tigeot 		dev_priv->psr.link_standby = true;
838c0e85e96SFrançois Tigeot 	else
839c0e85e96SFrançois Tigeot 		/* For new platforms let's respect VBT back again */
840c0e85e96SFrançois Tigeot 		dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link;
841c0e85e96SFrançois Tigeot 
842c0e85e96SFrançois Tigeot 	/* Override link_standby x link_off defaults */
843c0e85e96SFrançois Tigeot 	if (i915.enable_psr == 2 && !dev_priv->psr.link_standby) {
844c0e85e96SFrançois Tigeot 		DRM_DEBUG_KMS("PSR: Forcing link standby\n");
845c0e85e96SFrançois Tigeot 		dev_priv->psr.link_standby = true;
846c0e85e96SFrançois Tigeot 	}
847c0e85e96SFrançois Tigeot 	if (i915.enable_psr == 3 && dev_priv->psr.link_standby) {
848c0e85e96SFrançois Tigeot 		DRM_DEBUG_KMS("PSR: Forcing main link off\n");
849c0e85e96SFrançois Tigeot 		dev_priv->psr.link_standby = false;
850c0e85e96SFrançois Tigeot 	}
851c0e85e96SFrançois Tigeot 
8522c9916cdSFrançois Tigeot 	INIT_DELAYED_WORK(&dev_priv->psr.work, intel_psr_work);
8532c9916cdSFrançois Tigeot 	lockinit(&dev_priv->psr.lock, "i915dpl", 0, LK_CANRECURSE);
8542c9916cdSFrançois Tigeot }
855