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