15ca02815Sjsg // SPDX-License-Identifier: MIT
25ca02815Sjsg /*
35ca02815Sjsg * Copyright © 2020 Intel Corporation
45ca02815Sjsg */
55ca02815Sjsg
65ca02815Sjsg #include "g4x_dp.h"
75ca02815Sjsg #include "i915_drv.h"
8*f005ef32Sjsg #include "i915_reg.h"
95ca02815Sjsg #include "intel_de.h"
101bb76ff1Sjsg #include "intel_display_power_well.h"
115ca02815Sjsg #include "intel_display_types.h"
125ca02815Sjsg #include "intel_dp.h"
13*f005ef32Sjsg #include "intel_dpio_phy.h"
145ca02815Sjsg #include "intel_dpll.h"
151bb76ff1Sjsg #include "intel_lvds.h"
16*f005ef32Sjsg #include "intel_lvds_regs.h"
175ca02815Sjsg #include "intel_pps.h"
18*f005ef32Sjsg #include "intel_pps_regs.h"
191bb76ff1Sjsg #include "intel_quirks.h"
205ca02815Sjsg
215ca02815Sjsg static void vlv_steal_power_sequencer(struct drm_i915_private *dev_priv,
225ca02815Sjsg enum pipe pipe);
235ca02815Sjsg
245ca02815Sjsg static void pps_init_delays(struct intel_dp *intel_dp);
255ca02815Sjsg static void pps_init_registers(struct intel_dp *intel_dp, bool force_disable_vdd);
265ca02815Sjsg
pps_name(struct drm_i915_private * i915,struct intel_pps * pps)27*f005ef32Sjsg static const char *pps_name(struct drm_i915_private *i915,
28*f005ef32Sjsg struct intel_pps *pps)
29*f005ef32Sjsg {
30*f005ef32Sjsg if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
31*f005ef32Sjsg switch (pps->pps_pipe) {
32*f005ef32Sjsg case INVALID_PIPE:
33*f005ef32Sjsg /*
34*f005ef32Sjsg * FIXME would be nice if we can guarantee
35*f005ef32Sjsg * to always have a valid PPS when calling this.
36*f005ef32Sjsg */
37*f005ef32Sjsg return "PPS <none>";
38*f005ef32Sjsg case PIPE_A:
39*f005ef32Sjsg return "PPS A";
40*f005ef32Sjsg case PIPE_B:
41*f005ef32Sjsg return "PPS B";
42*f005ef32Sjsg default:
43*f005ef32Sjsg MISSING_CASE(pps->pps_pipe);
44*f005ef32Sjsg break;
45*f005ef32Sjsg }
46*f005ef32Sjsg } else {
47*f005ef32Sjsg switch (pps->pps_idx) {
48*f005ef32Sjsg case 0:
49*f005ef32Sjsg return "PPS 0";
50*f005ef32Sjsg case 1:
51*f005ef32Sjsg return "PPS 1";
52*f005ef32Sjsg default:
53*f005ef32Sjsg MISSING_CASE(pps->pps_idx);
54*f005ef32Sjsg break;
55*f005ef32Sjsg }
56*f005ef32Sjsg }
57*f005ef32Sjsg
58*f005ef32Sjsg return "PPS <invalid>";
59*f005ef32Sjsg }
60*f005ef32Sjsg
intel_pps_lock(struct intel_dp * intel_dp)615ca02815Sjsg intel_wakeref_t intel_pps_lock(struct intel_dp *intel_dp)
625ca02815Sjsg {
635ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
645ca02815Sjsg intel_wakeref_t wakeref;
655ca02815Sjsg
665ca02815Sjsg /*
675ca02815Sjsg * See intel_pps_reset_all() why we need a power domain reference here.
685ca02815Sjsg */
695ca02815Sjsg wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DISPLAY_CORE);
701bb76ff1Sjsg mutex_lock(&dev_priv->display.pps.mutex);
715ca02815Sjsg
725ca02815Sjsg return wakeref;
735ca02815Sjsg }
745ca02815Sjsg
intel_pps_unlock(struct intel_dp * intel_dp,intel_wakeref_t wakeref)755ca02815Sjsg intel_wakeref_t intel_pps_unlock(struct intel_dp *intel_dp,
765ca02815Sjsg intel_wakeref_t wakeref)
775ca02815Sjsg {
785ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
795ca02815Sjsg
801bb76ff1Sjsg mutex_unlock(&dev_priv->display.pps.mutex);
815ca02815Sjsg intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
825ca02815Sjsg
835ca02815Sjsg return 0;
845ca02815Sjsg }
855ca02815Sjsg
865ca02815Sjsg static void
vlv_power_sequencer_kick(struct intel_dp * intel_dp)875ca02815Sjsg vlv_power_sequencer_kick(struct intel_dp *intel_dp)
885ca02815Sjsg {
895ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
905ca02815Sjsg struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
915ca02815Sjsg enum pipe pipe = intel_dp->pps.pps_pipe;
925ca02815Sjsg bool pll_enabled, release_cl_override = false;
935ca02815Sjsg enum dpio_phy phy = DPIO_PHY(pipe);
945ca02815Sjsg enum dpio_channel ch = vlv_pipe_to_channel(pipe);
955ca02815Sjsg u32 DP;
965ca02815Sjsg
975ca02815Sjsg if (drm_WARN(&dev_priv->drm,
985ca02815Sjsg intel_de_read(dev_priv, intel_dp->output_reg) & DP_PORT_EN,
99*f005ef32Sjsg "skipping %s kick due to [ENCODER:%d:%s] being active\n",
100*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps),
101*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name))
1025ca02815Sjsg return;
1035ca02815Sjsg
1045ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
105*f005ef32Sjsg "kicking %s for [ENCODER:%d:%s]\n",
106*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps),
107*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name);
1085ca02815Sjsg
1095ca02815Sjsg /* Preserve the BIOS-computed detected bit. This is
1105ca02815Sjsg * supposed to be read-only.
1115ca02815Sjsg */
1125ca02815Sjsg DP = intel_de_read(dev_priv, intel_dp->output_reg) & DP_DETECTED;
1135ca02815Sjsg DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
1145ca02815Sjsg DP |= DP_PORT_WIDTH(1);
1155ca02815Sjsg DP |= DP_LINK_TRAIN_PAT_1;
1165ca02815Sjsg
1175ca02815Sjsg if (IS_CHERRYVIEW(dev_priv))
1185ca02815Sjsg DP |= DP_PIPE_SEL_CHV(pipe);
1195ca02815Sjsg else
1205ca02815Sjsg DP |= DP_PIPE_SEL(pipe);
1215ca02815Sjsg
1225ca02815Sjsg pll_enabled = intel_de_read(dev_priv, DPLL(pipe)) & DPLL_VCO_ENABLE;
1235ca02815Sjsg
1245ca02815Sjsg /*
1255ca02815Sjsg * The DPLL for the pipe must be enabled for this to work.
1265ca02815Sjsg * So enable temporarily it if it's not already enabled.
1275ca02815Sjsg */
1285ca02815Sjsg if (!pll_enabled) {
1295ca02815Sjsg release_cl_override = IS_CHERRYVIEW(dev_priv) &&
1305ca02815Sjsg !chv_phy_powergate_ch(dev_priv, phy, ch, true);
1315ca02815Sjsg
1325ca02815Sjsg if (vlv_force_pll_on(dev_priv, pipe, vlv_get_dpll(dev_priv))) {
1335ca02815Sjsg drm_err(&dev_priv->drm,
134*f005ef32Sjsg "Failed to force on PLL for pipe %c!\n",
1355ca02815Sjsg pipe_name(pipe));
1365ca02815Sjsg return;
1375ca02815Sjsg }
1385ca02815Sjsg }
1395ca02815Sjsg
1405ca02815Sjsg /*
1415ca02815Sjsg * Similar magic as in intel_dp_enable_port().
1425ca02815Sjsg * We _must_ do this port enable + disable trick
1435ca02815Sjsg * to make this power sequencer lock onto the port.
1445ca02815Sjsg * Otherwise even VDD force bit won't work.
1455ca02815Sjsg */
1465ca02815Sjsg intel_de_write(dev_priv, intel_dp->output_reg, DP);
1475ca02815Sjsg intel_de_posting_read(dev_priv, intel_dp->output_reg);
1485ca02815Sjsg
1495ca02815Sjsg intel_de_write(dev_priv, intel_dp->output_reg, DP | DP_PORT_EN);
1505ca02815Sjsg intel_de_posting_read(dev_priv, intel_dp->output_reg);
1515ca02815Sjsg
1525ca02815Sjsg intel_de_write(dev_priv, intel_dp->output_reg, DP & ~DP_PORT_EN);
1535ca02815Sjsg intel_de_posting_read(dev_priv, intel_dp->output_reg);
1545ca02815Sjsg
1555ca02815Sjsg if (!pll_enabled) {
1565ca02815Sjsg vlv_force_pll_off(dev_priv, pipe);
1575ca02815Sjsg
1585ca02815Sjsg if (release_cl_override)
1595ca02815Sjsg chv_phy_powergate_ch(dev_priv, phy, ch, false);
1605ca02815Sjsg }
1615ca02815Sjsg }
1625ca02815Sjsg
vlv_find_free_pps(struct drm_i915_private * dev_priv)1635ca02815Sjsg static enum pipe vlv_find_free_pps(struct drm_i915_private *dev_priv)
1645ca02815Sjsg {
1655ca02815Sjsg struct intel_encoder *encoder;
1665ca02815Sjsg unsigned int pipes = (1 << PIPE_A) | (1 << PIPE_B);
1675ca02815Sjsg
1685ca02815Sjsg /*
1695ca02815Sjsg * We don't have power sequencer currently.
1705ca02815Sjsg * Pick one that's not used by other ports.
1715ca02815Sjsg */
1725ca02815Sjsg for_each_intel_dp(&dev_priv->drm, encoder) {
1735ca02815Sjsg struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1745ca02815Sjsg
1755ca02815Sjsg if (encoder->type == INTEL_OUTPUT_EDP) {
1765ca02815Sjsg drm_WARN_ON(&dev_priv->drm,
1775ca02815Sjsg intel_dp->pps.active_pipe != INVALID_PIPE &&
1785ca02815Sjsg intel_dp->pps.active_pipe !=
1795ca02815Sjsg intel_dp->pps.pps_pipe);
1805ca02815Sjsg
1815ca02815Sjsg if (intel_dp->pps.pps_pipe != INVALID_PIPE)
1825ca02815Sjsg pipes &= ~(1 << intel_dp->pps.pps_pipe);
1835ca02815Sjsg } else {
1845ca02815Sjsg drm_WARN_ON(&dev_priv->drm,
1855ca02815Sjsg intel_dp->pps.pps_pipe != INVALID_PIPE);
1865ca02815Sjsg
1875ca02815Sjsg if (intel_dp->pps.active_pipe != INVALID_PIPE)
1885ca02815Sjsg pipes &= ~(1 << intel_dp->pps.active_pipe);
1895ca02815Sjsg }
1905ca02815Sjsg }
1915ca02815Sjsg
1925ca02815Sjsg if (pipes == 0)
1935ca02815Sjsg return INVALID_PIPE;
1945ca02815Sjsg
1955ca02815Sjsg return ffs(pipes) - 1;
1965ca02815Sjsg }
1975ca02815Sjsg
1985ca02815Sjsg static enum pipe
vlv_power_sequencer_pipe(struct intel_dp * intel_dp)1995ca02815Sjsg vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
2005ca02815Sjsg {
2015ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
2025ca02815Sjsg struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
2035ca02815Sjsg enum pipe pipe;
2045ca02815Sjsg
2051bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
2065ca02815Sjsg
2075ca02815Sjsg /* We should never land here with regular DP ports */
2085ca02815Sjsg drm_WARN_ON(&dev_priv->drm, !intel_dp_is_edp(intel_dp));
2095ca02815Sjsg
2105ca02815Sjsg drm_WARN_ON(&dev_priv->drm, intel_dp->pps.active_pipe != INVALID_PIPE &&
2115ca02815Sjsg intel_dp->pps.active_pipe != intel_dp->pps.pps_pipe);
2125ca02815Sjsg
2135ca02815Sjsg if (intel_dp->pps.pps_pipe != INVALID_PIPE)
2145ca02815Sjsg return intel_dp->pps.pps_pipe;
2155ca02815Sjsg
2165ca02815Sjsg pipe = vlv_find_free_pps(dev_priv);
2175ca02815Sjsg
2185ca02815Sjsg /*
2195ca02815Sjsg * Didn't find one. This should not happen since there
2205ca02815Sjsg * are two power sequencers and up to two eDP ports.
2215ca02815Sjsg */
2225ca02815Sjsg if (drm_WARN_ON(&dev_priv->drm, pipe == INVALID_PIPE))
2235ca02815Sjsg pipe = PIPE_A;
2245ca02815Sjsg
2255ca02815Sjsg vlv_steal_power_sequencer(dev_priv, pipe);
2265ca02815Sjsg intel_dp->pps.pps_pipe = pipe;
2275ca02815Sjsg
2285ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
229*f005ef32Sjsg "picked %s for [ENCODER:%d:%s]\n",
230*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps),
231*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name);
2325ca02815Sjsg
2335ca02815Sjsg /* init power sequencer on this pipe and port */
2345ca02815Sjsg pps_init_delays(intel_dp);
2355ca02815Sjsg pps_init_registers(intel_dp, true);
2365ca02815Sjsg
2375ca02815Sjsg /*
2385ca02815Sjsg * Even vdd force doesn't work until we've made
2395ca02815Sjsg * the power sequencer lock in on the port.
2405ca02815Sjsg */
2415ca02815Sjsg vlv_power_sequencer_kick(intel_dp);
2425ca02815Sjsg
2435ca02815Sjsg return intel_dp->pps.pps_pipe;
2445ca02815Sjsg }
2455ca02815Sjsg
2465ca02815Sjsg static int
bxt_power_sequencer_idx(struct intel_dp * intel_dp)2475ca02815Sjsg bxt_power_sequencer_idx(struct intel_dp *intel_dp)
2485ca02815Sjsg {
2495ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
250*f005ef32Sjsg int pps_idx = intel_dp->pps.pps_idx;
2515ca02815Sjsg
2521bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
2535ca02815Sjsg
2545ca02815Sjsg /* We should never land here with regular DP ports */
2555ca02815Sjsg drm_WARN_ON(&dev_priv->drm, !intel_dp_is_edp(intel_dp));
2565ca02815Sjsg
2575ca02815Sjsg if (!intel_dp->pps.pps_reset)
258*f005ef32Sjsg return pps_idx;
2595ca02815Sjsg
2605ca02815Sjsg intel_dp->pps.pps_reset = false;
2615ca02815Sjsg
2625ca02815Sjsg /*
2635ca02815Sjsg * Only the HW needs to be reprogrammed, the SW state is fixed and
2645ca02815Sjsg * has been setup during connector init.
2655ca02815Sjsg */
2665ca02815Sjsg pps_init_registers(intel_dp, false);
2675ca02815Sjsg
268*f005ef32Sjsg return pps_idx;
2695ca02815Sjsg }
2705ca02815Sjsg
271*f005ef32Sjsg typedef bool (*pps_check)(struct drm_i915_private *dev_priv, int pps_idx);
2725ca02815Sjsg
pps_has_pp_on(struct drm_i915_private * dev_priv,int pps_idx)273*f005ef32Sjsg static bool pps_has_pp_on(struct drm_i915_private *dev_priv, int pps_idx)
2745ca02815Sjsg {
275*f005ef32Sjsg return intel_de_read(dev_priv, PP_STATUS(pps_idx)) & PP_ON;
2765ca02815Sjsg }
2775ca02815Sjsg
pps_has_vdd_on(struct drm_i915_private * dev_priv,int pps_idx)278*f005ef32Sjsg static bool pps_has_vdd_on(struct drm_i915_private *dev_priv, int pps_idx)
2795ca02815Sjsg {
280*f005ef32Sjsg return intel_de_read(dev_priv, PP_CONTROL(pps_idx)) & EDP_FORCE_VDD;
2815ca02815Sjsg }
2825ca02815Sjsg
pps_any(struct drm_i915_private * dev_priv,int pps_idx)283*f005ef32Sjsg static bool pps_any(struct drm_i915_private *dev_priv, int pps_idx)
2845ca02815Sjsg {
2855ca02815Sjsg return true;
2865ca02815Sjsg }
2875ca02815Sjsg
2885ca02815Sjsg static enum pipe
vlv_initial_pps_pipe(struct drm_i915_private * dev_priv,enum port port,pps_check check)2895ca02815Sjsg vlv_initial_pps_pipe(struct drm_i915_private *dev_priv,
290*f005ef32Sjsg enum port port, pps_check check)
2915ca02815Sjsg {
2925ca02815Sjsg enum pipe pipe;
2935ca02815Sjsg
2945ca02815Sjsg for (pipe = PIPE_A; pipe <= PIPE_B; pipe++) {
2955ca02815Sjsg u32 port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(pipe)) &
2965ca02815Sjsg PANEL_PORT_SELECT_MASK;
2975ca02815Sjsg
2985ca02815Sjsg if (port_sel != PANEL_PORT_SELECT_VLV(port))
2995ca02815Sjsg continue;
3005ca02815Sjsg
301*f005ef32Sjsg if (!check(dev_priv, pipe))
3025ca02815Sjsg continue;
3035ca02815Sjsg
3045ca02815Sjsg return pipe;
3055ca02815Sjsg }
3065ca02815Sjsg
3075ca02815Sjsg return INVALID_PIPE;
3085ca02815Sjsg }
3095ca02815Sjsg
3105ca02815Sjsg static void
vlv_initial_power_sequencer_setup(struct intel_dp * intel_dp)3115ca02815Sjsg vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp)
3125ca02815Sjsg {
3135ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
3145ca02815Sjsg struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
3155ca02815Sjsg enum port port = dig_port->base.port;
3165ca02815Sjsg
3171bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
3185ca02815Sjsg
3195ca02815Sjsg /* try to find a pipe with this port selected */
3205ca02815Sjsg /* first pick one where the panel is on */
3215ca02815Sjsg intel_dp->pps.pps_pipe = vlv_initial_pps_pipe(dev_priv, port,
322*f005ef32Sjsg pps_has_pp_on);
3235ca02815Sjsg /* didn't find one? pick one where vdd is on */
3245ca02815Sjsg if (intel_dp->pps.pps_pipe == INVALID_PIPE)
3255ca02815Sjsg intel_dp->pps.pps_pipe = vlv_initial_pps_pipe(dev_priv, port,
326*f005ef32Sjsg pps_has_vdd_on);
3275ca02815Sjsg /* didn't find one? pick one with just the correct port */
3285ca02815Sjsg if (intel_dp->pps.pps_pipe == INVALID_PIPE)
3295ca02815Sjsg intel_dp->pps.pps_pipe = vlv_initial_pps_pipe(dev_priv, port,
330*f005ef32Sjsg pps_any);
3315ca02815Sjsg
3325ca02815Sjsg /* didn't find one? just let vlv_power_sequencer_pipe() pick one when needed */
3335ca02815Sjsg if (intel_dp->pps.pps_pipe == INVALID_PIPE) {
3345ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
335*f005ef32Sjsg "[ENCODER:%d:%s] no initial power sequencer\n",
336*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name);
3375ca02815Sjsg return;
3385ca02815Sjsg }
3395ca02815Sjsg
3405ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
341*f005ef32Sjsg "[ENCODER:%d:%s] initial power sequencer: %s\n",
342*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
343*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps));
344*f005ef32Sjsg }
345*f005ef32Sjsg
intel_num_pps(struct drm_i915_private * i915)346*f005ef32Sjsg static int intel_num_pps(struct drm_i915_private *i915)
347*f005ef32Sjsg {
348*f005ef32Sjsg if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
349*f005ef32Sjsg return 2;
350*f005ef32Sjsg
351*f005ef32Sjsg if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
352*f005ef32Sjsg return 2;
353*f005ef32Sjsg
354*f005ef32Sjsg if (INTEL_PCH_TYPE(i915) >= PCH_DG1)
355*f005ef32Sjsg return 1;
356*f005ef32Sjsg
357*f005ef32Sjsg if (INTEL_PCH_TYPE(i915) >= PCH_ICP)
358*f005ef32Sjsg return 2;
359*f005ef32Sjsg
360*f005ef32Sjsg return 1;
361*f005ef32Sjsg }
362*f005ef32Sjsg
intel_pps_is_valid(struct intel_dp * intel_dp)363*f005ef32Sjsg static bool intel_pps_is_valid(struct intel_dp *intel_dp)
364*f005ef32Sjsg {
365*f005ef32Sjsg struct drm_i915_private *i915 = dp_to_i915(intel_dp);
366*f005ef32Sjsg
367*f005ef32Sjsg if (intel_dp->pps.pps_idx == 1 &&
368*f005ef32Sjsg INTEL_PCH_TYPE(i915) >= PCH_ICP &&
369*f005ef32Sjsg INTEL_PCH_TYPE(i915) < PCH_MTP)
370*f005ef32Sjsg return intel_de_read(i915, SOUTH_CHICKEN1) & ICP_SECOND_PPS_IO_SELECT;
371*f005ef32Sjsg
372*f005ef32Sjsg return true;
373*f005ef32Sjsg }
374*f005ef32Sjsg
375*f005ef32Sjsg static int
bxt_initial_pps_idx(struct drm_i915_private * i915,pps_check check)376*f005ef32Sjsg bxt_initial_pps_idx(struct drm_i915_private *i915, pps_check check)
377*f005ef32Sjsg {
378*f005ef32Sjsg int pps_idx, pps_num = intel_num_pps(i915);
379*f005ef32Sjsg
380*f005ef32Sjsg for (pps_idx = 0; pps_idx < pps_num; pps_idx++) {
381*f005ef32Sjsg if (check(i915, pps_idx))
382*f005ef32Sjsg return pps_idx;
383*f005ef32Sjsg }
384*f005ef32Sjsg
385*f005ef32Sjsg return -1;
386*f005ef32Sjsg }
387*f005ef32Sjsg
388*f005ef32Sjsg static bool
pps_initial_setup(struct intel_dp * intel_dp)389*f005ef32Sjsg pps_initial_setup(struct intel_dp *intel_dp)
390*f005ef32Sjsg {
391*f005ef32Sjsg struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
392*f005ef32Sjsg struct intel_connector *connector = intel_dp->attached_connector;
393*f005ef32Sjsg struct drm_i915_private *i915 = to_i915(encoder->base.dev);
394*f005ef32Sjsg
395*f005ef32Sjsg lockdep_assert_held(&i915->display.pps.mutex);
396*f005ef32Sjsg
397*f005ef32Sjsg if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
398*f005ef32Sjsg vlv_initial_power_sequencer_setup(intel_dp);
399*f005ef32Sjsg return true;
400*f005ef32Sjsg }
401*f005ef32Sjsg
402*f005ef32Sjsg /* first ask the VBT */
403*f005ef32Sjsg if (intel_num_pps(i915) > 1)
404*f005ef32Sjsg intel_dp->pps.pps_idx = connector->panel.vbt.backlight.controller;
405*f005ef32Sjsg else
406*f005ef32Sjsg intel_dp->pps.pps_idx = 0;
407*f005ef32Sjsg
408*f005ef32Sjsg if (drm_WARN_ON(&i915->drm, intel_dp->pps.pps_idx >= intel_num_pps(i915)))
409*f005ef32Sjsg intel_dp->pps.pps_idx = -1;
410*f005ef32Sjsg
411*f005ef32Sjsg /* VBT wasn't parsed yet? pick one where the panel is on */
412*f005ef32Sjsg if (intel_dp->pps.pps_idx < 0)
413*f005ef32Sjsg intel_dp->pps.pps_idx = bxt_initial_pps_idx(i915, pps_has_pp_on);
414*f005ef32Sjsg /* didn't find one? pick one where vdd is on */
415*f005ef32Sjsg if (intel_dp->pps.pps_idx < 0)
416*f005ef32Sjsg intel_dp->pps.pps_idx = bxt_initial_pps_idx(i915, pps_has_vdd_on);
417*f005ef32Sjsg /* didn't find one? pick any */
418*f005ef32Sjsg if (intel_dp->pps.pps_idx < 0) {
419*f005ef32Sjsg intel_dp->pps.pps_idx = bxt_initial_pps_idx(i915, pps_any);
420*f005ef32Sjsg
421*f005ef32Sjsg drm_dbg_kms(&i915->drm,
422*f005ef32Sjsg "[ENCODER:%d:%s] no initial power sequencer, assuming %s\n",
423*f005ef32Sjsg encoder->base.base.id, encoder->base.name,
424*f005ef32Sjsg pps_name(i915, &intel_dp->pps));
425*f005ef32Sjsg } else {
426*f005ef32Sjsg drm_dbg_kms(&i915->drm,
427*f005ef32Sjsg "[ENCODER:%d:%s] initial power sequencer: %s\n",
428*f005ef32Sjsg encoder->base.base.id, encoder->base.name,
429*f005ef32Sjsg pps_name(i915, &intel_dp->pps));
430*f005ef32Sjsg }
431*f005ef32Sjsg
432*f005ef32Sjsg return intel_pps_is_valid(intel_dp);
4335ca02815Sjsg }
4345ca02815Sjsg
intel_pps_reset_all(struct drm_i915_private * dev_priv)4355ca02815Sjsg void intel_pps_reset_all(struct drm_i915_private *dev_priv)
4365ca02815Sjsg {
4375ca02815Sjsg struct intel_encoder *encoder;
4385ca02815Sjsg
4395ca02815Sjsg if (drm_WARN_ON(&dev_priv->drm, !IS_LP(dev_priv)))
4405ca02815Sjsg return;
4415ca02815Sjsg
4425ca02815Sjsg if (!HAS_DISPLAY(dev_priv))
4435ca02815Sjsg return;
4445ca02815Sjsg
4455ca02815Sjsg /*
4465ca02815Sjsg * We can't grab pps_mutex here due to deadlock with power_domain
4475ca02815Sjsg * mutex when power_domain functions are called while holding pps_mutex.
4485ca02815Sjsg * That also means that in order to use pps_pipe the code needs to
4495ca02815Sjsg * hold both a power domain reference and pps_mutex, and the power domain
4505ca02815Sjsg * reference get/put must be done while _not_ holding pps_mutex.
4515ca02815Sjsg * pps_{lock,unlock}() do these steps in the correct order, so one
4525ca02815Sjsg * should use them always.
4535ca02815Sjsg */
4545ca02815Sjsg
4555ca02815Sjsg for_each_intel_dp(&dev_priv->drm, encoder) {
4565ca02815Sjsg struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
4575ca02815Sjsg
4585ca02815Sjsg drm_WARN_ON(&dev_priv->drm,
4595ca02815Sjsg intel_dp->pps.active_pipe != INVALID_PIPE);
4605ca02815Sjsg
4615ca02815Sjsg if (encoder->type != INTEL_OUTPUT_EDP)
4625ca02815Sjsg continue;
4635ca02815Sjsg
4645ca02815Sjsg if (DISPLAY_VER(dev_priv) >= 9)
4655ca02815Sjsg intel_dp->pps.pps_reset = true;
4665ca02815Sjsg else
4675ca02815Sjsg intel_dp->pps.pps_pipe = INVALID_PIPE;
4685ca02815Sjsg }
4695ca02815Sjsg }
4705ca02815Sjsg
4715ca02815Sjsg struct pps_registers {
4725ca02815Sjsg i915_reg_t pp_ctrl;
4735ca02815Sjsg i915_reg_t pp_stat;
4745ca02815Sjsg i915_reg_t pp_on;
4755ca02815Sjsg i915_reg_t pp_off;
4765ca02815Sjsg i915_reg_t pp_div;
4775ca02815Sjsg };
4785ca02815Sjsg
intel_pps_get_registers(struct intel_dp * intel_dp,struct pps_registers * regs)4795ca02815Sjsg static void intel_pps_get_registers(struct intel_dp *intel_dp,
4805ca02815Sjsg struct pps_registers *regs)
4815ca02815Sjsg {
4825ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
483*f005ef32Sjsg int pps_idx;
4845ca02815Sjsg
4855ca02815Sjsg memset(regs, 0, sizeof(*regs));
4865ca02815Sjsg
487*f005ef32Sjsg if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
4885ca02815Sjsg pps_idx = vlv_power_sequencer_pipe(intel_dp);
489*f005ef32Sjsg else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
490*f005ef32Sjsg pps_idx = bxt_power_sequencer_idx(intel_dp);
491*f005ef32Sjsg else
492*f005ef32Sjsg pps_idx = intel_dp->pps.pps_idx;
4935ca02815Sjsg
4945ca02815Sjsg regs->pp_ctrl = PP_CONTROL(pps_idx);
4955ca02815Sjsg regs->pp_stat = PP_STATUS(pps_idx);
4965ca02815Sjsg regs->pp_on = PP_ON_DELAYS(pps_idx);
4975ca02815Sjsg regs->pp_off = PP_OFF_DELAYS(pps_idx);
4985ca02815Sjsg
4995ca02815Sjsg /* Cycle delay moved from PP_DIVISOR to PP_CONTROL */
5005ca02815Sjsg if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv) ||
5015ca02815Sjsg INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
5025ca02815Sjsg regs->pp_div = INVALID_MMIO_REG;
5035ca02815Sjsg else
5045ca02815Sjsg regs->pp_div = PP_DIVISOR(pps_idx);
5055ca02815Sjsg }
5065ca02815Sjsg
5075ca02815Sjsg static i915_reg_t
_pp_ctrl_reg(struct intel_dp * intel_dp)5085ca02815Sjsg _pp_ctrl_reg(struct intel_dp *intel_dp)
5095ca02815Sjsg {
5105ca02815Sjsg struct pps_registers regs;
5115ca02815Sjsg
5125ca02815Sjsg intel_pps_get_registers(intel_dp, ®s);
5135ca02815Sjsg
5145ca02815Sjsg return regs.pp_ctrl;
5155ca02815Sjsg }
5165ca02815Sjsg
5175ca02815Sjsg static i915_reg_t
_pp_stat_reg(struct intel_dp * intel_dp)5185ca02815Sjsg _pp_stat_reg(struct intel_dp *intel_dp)
5195ca02815Sjsg {
5205ca02815Sjsg struct pps_registers regs;
5215ca02815Sjsg
5225ca02815Sjsg intel_pps_get_registers(intel_dp, ®s);
5235ca02815Sjsg
5245ca02815Sjsg return regs.pp_stat;
5255ca02815Sjsg }
5265ca02815Sjsg
edp_have_panel_power(struct intel_dp * intel_dp)5275ca02815Sjsg static bool edp_have_panel_power(struct intel_dp *intel_dp)
5285ca02815Sjsg {
5295ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
5305ca02815Sjsg
5311bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
5325ca02815Sjsg
5335ca02815Sjsg if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
5345ca02815Sjsg intel_dp->pps.pps_pipe == INVALID_PIPE)
5355ca02815Sjsg return false;
5365ca02815Sjsg
5375ca02815Sjsg return (intel_de_read(dev_priv, _pp_stat_reg(intel_dp)) & PP_ON) != 0;
5385ca02815Sjsg }
5395ca02815Sjsg
edp_have_panel_vdd(struct intel_dp * intel_dp)5405ca02815Sjsg static bool edp_have_panel_vdd(struct intel_dp *intel_dp)
5415ca02815Sjsg {
5425ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
5435ca02815Sjsg
5441bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
5455ca02815Sjsg
5465ca02815Sjsg if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
5475ca02815Sjsg intel_dp->pps.pps_pipe == INVALID_PIPE)
5485ca02815Sjsg return false;
5495ca02815Sjsg
5505ca02815Sjsg return intel_de_read(dev_priv, _pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD;
5515ca02815Sjsg }
5525ca02815Sjsg
intel_pps_check_power_unlocked(struct intel_dp * intel_dp)5535ca02815Sjsg void intel_pps_check_power_unlocked(struct intel_dp *intel_dp)
5545ca02815Sjsg {
5555ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
556*f005ef32Sjsg struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
5575ca02815Sjsg
5585ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
5595ca02815Sjsg return;
5605ca02815Sjsg
5615ca02815Sjsg if (!edp_have_panel_power(intel_dp) && !edp_have_panel_vdd(intel_dp)) {
5625ca02815Sjsg drm_WARN(&dev_priv->drm, 1,
563*f005ef32Sjsg "[ENCODER:%d:%s] %s powered off while attempting AUX CH communication.\n",
564*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
565*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps));
566*f005ef32Sjsg drm_dbg_kms(&dev_priv->drm,
567*f005ef32Sjsg "[ENCODER:%d:%s] %s PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n",
568*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
569*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps),
5705ca02815Sjsg intel_de_read(dev_priv, _pp_stat_reg(intel_dp)),
5715ca02815Sjsg intel_de_read(dev_priv, _pp_ctrl_reg(intel_dp)));
5725ca02815Sjsg }
5735ca02815Sjsg }
5745ca02815Sjsg
5755ca02815Sjsg #define IDLE_ON_MASK (PP_ON | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK)
5765ca02815Sjsg #define IDLE_ON_VALUE (PP_ON | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_ON_IDLE)
5775ca02815Sjsg
5785ca02815Sjsg #define IDLE_OFF_MASK (PP_ON | PP_SEQUENCE_MASK | 0 | 0)
5795ca02815Sjsg #define IDLE_OFF_VALUE (0 | PP_SEQUENCE_NONE | 0 | 0)
5805ca02815Sjsg
5815ca02815Sjsg #define IDLE_CYCLE_MASK (PP_ON | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK)
5825ca02815Sjsg #define IDLE_CYCLE_VALUE (0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE)
5835ca02815Sjsg
5845ca02815Sjsg static void intel_pps_verify_state(struct intel_dp *intel_dp);
5855ca02815Sjsg
wait_panel_status(struct intel_dp * intel_dp,u32 mask,u32 value)5865ca02815Sjsg static void wait_panel_status(struct intel_dp *intel_dp,
587*f005ef32Sjsg u32 mask, u32 value)
5885ca02815Sjsg {
5895ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
590*f005ef32Sjsg struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
5915ca02815Sjsg i915_reg_t pp_stat_reg, pp_ctrl_reg;
5925ca02815Sjsg
5931bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
5945ca02815Sjsg
5955ca02815Sjsg intel_pps_verify_state(intel_dp);
5965ca02815Sjsg
5975ca02815Sjsg pp_stat_reg = _pp_stat_reg(intel_dp);
5985ca02815Sjsg pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
5995ca02815Sjsg
6005ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
601*f005ef32Sjsg "[ENCODER:%d:%s] %s mask: 0x%08x value: 0x%08x PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n",
602*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
603*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps),
6045ca02815Sjsg mask, value,
6055ca02815Sjsg intel_de_read(dev_priv, pp_stat_reg),
6065ca02815Sjsg intel_de_read(dev_priv, pp_ctrl_reg));
6075ca02815Sjsg
6085ca02815Sjsg if (intel_de_wait_for_register(dev_priv, pp_stat_reg,
6095ca02815Sjsg mask, value, 5000))
6105ca02815Sjsg drm_err(&dev_priv->drm,
611*f005ef32Sjsg "[ENCODER:%d:%s] %s panel status timeout: PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n",
612*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
613*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps),
6145ca02815Sjsg intel_de_read(dev_priv, pp_stat_reg),
6155ca02815Sjsg intel_de_read(dev_priv, pp_ctrl_reg));
6165ca02815Sjsg
6175ca02815Sjsg drm_dbg_kms(&dev_priv->drm, "Wait complete\n");
6185ca02815Sjsg }
6195ca02815Sjsg
wait_panel_on(struct intel_dp * intel_dp)6205ca02815Sjsg static void wait_panel_on(struct intel_dp *intel_dp)
6215ca02815Sjsg {
6225ca02815Sjsg struct drm_i915_private *i915 = dp_to_i915(intel_dp);
623*f005ef32Sjsg struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
6245ca02815Sjsg
625*f005ef32Sjsg drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] %s wait for panel power on\n",
626*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
627*f005ef32Sjsg pps_name(i915, &intel_dp->pps));
6285ca02815Sjsg wait_panel_status(intel_dp, IDLE_ON_MASK, IDLE_ON_VALUE);
6295ca02815Sjsg }
6305ca02815Sjsg
wait_panel_off(struct intel_dp * intel_dp)6315ca02815Sjsg static void wait_panel_off(struct intel_dp *intel_dp)
6325ca02815Sjsg {
6335ca02815Sjsg struct drm_i915_private *i915 = dp_to_i915(intel_dp);
634*f005ef32Sjsg struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
6355ca02815Sjsg
636*f005ef32Sjsg drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] %s wait for panel power off time\n",
637*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
638*f005ef32Sjsg pps_name(i915, &intel_dp->pps));
6395ca02815Sjsg wait_panel_status(intel_dp, IDLE_OFF_MASK, IDLE_OFF_VALUE);
6405ca02815Sjsg }
6415ca02815Sjsg
wait_panel_power_cycle(struct intel_dp * intel_dp)6425ca02815Sjsg static void wait_panel_power_cycle(struct intel_dp *intel_dp)
6435ca02815Sjsg {
6445ca02815Sjsg struct drm_i915_private *i915 = dp_to_i915(intel_dp);
645*f005ef32Sjsg struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
6465ca02815Sjsg ktime_t panel_power_on_time;
6475ca02815Sjsg s64 panel_power_off_duration;
6485ca02815Sjsg
649*f005ef32Sjsg drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] %s wait for panel power cycle\n",
650*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
651*f005ef32Sjsg pps_name(i915, &intel_dp->pps));
6525ca02815Sjsg
6531bb76ff1Sjsg /* take the difference of current time and panel power off time
6545ca02815Sjsg * and then make panel wait for t11_t12 if needed. */
6555ca02815Sjsg panel_power_on_time = ktime_get_boottime();
6565ca02815Sjsg panel_power_off_duration = ktime_ms_delta(panel_power_on_time, intel_dp->pps.panel_power_off_time);
6575ca02815Sjsg
6585ca02815Sjsg /* When we disable the VDD override bit last we have to do the manual
6595ca02815Sjsg * wait. */
6605ca02815Sjsg if (panel_power_off_duration < (s64)intel_dp->pps.panel_power_cycle_delay)
6615ca02815Sjsg wait_remaining_ms_from_jiffies(jiffies,
6625ca02815Sjsg intel_dp->pps.panel_power_cycle_delay - panel_power_off_duration);
6635ca02815Sjsg
6645ca02815Sjsg wait_panel_status(intel_dp, IDLE_CYCLE_MASK, IDLE_CYCLE_VALUE);
6655ca02815Sjsg }
6665ca02815Sjsg
intel_pps_wait_power_cycle(struct intel_dp * intel_dp)6675ca02815Sjsg void intel_pps_wait_power_cycle(struct intel_dp *intel_dp)
6685ca02815Sjsg {
6695ca02815Sjsg intel_wakeref_t wakeref;
6705ca02815Sjsg
6715ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
6725ca02815Sjsg return;
6735ca02815Sjsg
6745ca02815Sjsg with_intel_pps_lock(intel_dp, wakeref)
6755ca02815Sjsg wait_panel_power_cycle(intel_dp);
6765ca02815Sjsg }
6775ca02815Sjsg
wait_backlight_on(struct intel_dp * intel_dp)6785ca02815Sjsg static void wait_backlight_on(struct intel_dp *intel_dp)
6795ca02815Sjsg {
6805ca02815Sjsg wait_remaining_ms_from_jiffies(intel_dp->pps.last_power_on,
6815ca02815Sjsg intel_dp->pps.backlight_on_delay);
6825ca02815Sjsg }
6835ca02815Sjsg
edp_wait_backlight_off(struct intel_dp * intel_dp)6845ca02815Sjsg static void edp_wait_backlight_off(struct intel_dp *intel_dp)
6855ca02815Sjsg {
6865ca02815Sjsg wait_remaining_ms_from_jiffies(intel_dp->pps.last_backlight_off,
6875ca02815Sjsg intel_dp->pps.backlight_off_delay);
6885ca02815Sjsg }
6895ca02815Sjsg
6905ca02815Sjsg /* Read the current pp_control value, unlocking the register if it
6915ca02815Sjsg * is locked
6925ca02815Sjsg */
6935ca02815Sjsg
ilk_get_pp_control(struct intel_dp * intel_dp)6945ca02815Sjsg static u32 ilk_get_pp_control(struct intel_dp *intel_dp)
6955ca02815Sjsg {
6965ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
6975ca02815Sjsg u32 control;
6985ca02815Sjsg
6991bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
7005ca02815Sjsg
7015ca02815Sjsg control = intel_de_read(dev_priv, _pp_ctrl_reg(intel_dp));
7025ca02815Sjsg if (drm_WARN_ON(&dev_priv->drm, !HAS_DDI(dev_priv) &&
7035ca02815Sjsg (control & PANEL_UNLOCK_MASK) != PANEL_UNLOCK_REGS)) {
7045ca02815Sjsg control &= ~PANEL_UNLOCK_MASK;
7055ca02815Sjsg control |= PANEL_UNLOCK_REGS;
7065ca02815Sjsg }
7075ca02815Sjsg return control;
7085ca02815Sjsg }
7095ca02815Sjsg
7105ca02815Sjsg /*
7115ca02815Sjsg * Must be paired with intel_pps_vdd_off_unlocked().
7125ca02815Sjsg * Must hold pps_mutex around the whole on/off sequence.
7135ca02815Sjsg * Can be nested with intel_pps_vdd_{on,off}() calls.
7145ca02815Sjsg */
intel_pps_vdd_on_unlocked(struct intel_dp * intel_dp)7155ca02815Sjsg bool intel_pps_vdd_on_unlocked(struct intel_dp *intel_dp)
7165ca02815Sjsg {
7175ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
7185ca02815Sjsg struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
7195ca02815Sjsg u32 pp;
7205ca02815Sjsg i915_reg_t pp_stat_reg, pp_ctrl_reg;
7215ca02815Sjsg bool need_to_disable = !intel_dp->pps.want_panel_vdd;
7225ca02815Sjsg
7231bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
7245ca02815Sjsg
7255ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
7265ca02815Sjsg return false;
7275ca02815Sjsg
7285ca02815Sjsg cancel_delayed_work(&intel_dp->pps.panel_vdd_work);
7295ca02815Sjsg intel_dp->pps.want_panel_vdd = true;
7305ca02815Sjsg
7315ca02815Sjsg if (edp_have_panel_vdd(intel_dp))
7325ca02815Sjsg return need_to_disable;
7335ca02815Sjsg
7345ca02815Sjsg drm_WARN_ON(&dev_priv->drm, intel_dp->pps.vdd_wakeref);
7355ca02815Sjsg intel_dp->pps.vdd_wakeref = intel_display_power_get(dev_priv,
7365ca02815Sjsg intel_aux_power_domain(dig_port));
7375ca02815Sjsg
738*f005ef32Sjsg pp_stat_reg = _pp_stat_reg(intel_dp);
739*f005ef32Sjsg pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
740*f005ef32Sjsg
741*f005ef32Sjsg drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] %s turning VDD on\n",
742*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
743*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps));
7445ca02815Sjsg
7455ca02815Sjsg if (!edp_have_panel_power(intel_dp))
7465ca02815Sjsg wait_panel_power_cycle(intel_dp);
7475ca02815Sjsg
7485ca02815Sjsg pp = ilk_get_pp_control(intel_dp);
7495ca02815Sjsg pp |= EDP_FORCE_VDD;
7505ca02815Sjsg
7515ca02815Sjsg intel_de_write(dev_priv, pp_ctrl_reg, pp);
7525ca02815Sjsg intel_de_posting_read(dev_priv, pp_ctrl_reg);
753*f005ef32Sjsg drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] %s PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n",
754*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
755*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps),
7565ca02815Sjsg intel_de_read(dev_priv, pp_stat_reg),
7575ca02815Sjsg intel_de_read(dev_priv, pp_ctrl_reg));
7585ca02815Sjsg /*
7595ca02815Sjsg * If the panel wasn't on, delay before accessing aux channel
7605ca02815Sjsg */
7615ca02815Sjsg if (!edp_have_panel_power(intel_dp)) {
7625ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
763*f005ef32Sjsg "[ENCODER:%d:%s] %s panel power wasn't enabled\n",
764*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
765*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps));
7665ca02815Sjsg drm_msleep(intel_dp->pps.panel_power_up_delay);
7675ca02815Sjsg }
7685ca02815Sjsg
7695ca02815Sjsg return need_to_disable;
7705ca02815Sjsg }
7715ca02815Sjsg
7725ca02815Sjsg /*
7735ca02815Sjsg * Must be paired with intel_pps_off().
7745ca02815Sjsg * Nested calls to these functions are not allowed since
7755ca02815Sjsg * we drop the lock. Caller must use some higher level
7765ca02815Sjsg * locking to prevent nested calls from other threads.
7775ca02815Sjsg */
intel_pps_vdd_on(struct intel_dp * intel_dp)7785ca02815Sjsg void intel_pps_vdd_on(struct intel_dp *intel_dp)
7795ca02815Sjsg {
780*f005ef32Sjsg struct drm_i915_private *i915 = dp_to_i915(intel_dp);
7815ca02815Sjsg intel_wakeref_t wakeref;
7825ca02815Sjsg bool vdd;
7835ca02815Sjsg
7845ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
7855ca02815Sjsg return;
7865ca02815Sjsg
7875ca02815Sjsg vdd = false;
7885ca02815Sjsg with_intel_pps_lock(intel_dp, wakeref)
7895ca02815Sjsg vdd = intel_pps_vdd_on_unlocked(intel_dp);
790*f005ef32Sjsg I915_STATE_WARN(i915, !vdd, "[ENCODER:%d:%s] %s VDD already requested on\n",
7915ca02815Sjsg dp_to_dig_port(intel_dp)->base.base.base.id,
792*f005ef32Sjsg dp_to_dig_port(intel_dp)->base.base.name,
793*f005ef32Sjsg pps_name(i915, &intel_dp->pps));
7945ca02815Sjsg }
7955ca02815Sjsg
intel_pps_vdd_off_sync_unlocked(struct intel_dp * intel_dp)7965ca02815Sjsg static void intel_pps_vdd_off_sync_unlocked(struct intel_dp *intel_dp)
7975ca02815Sjsg {
7985ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
7995ca02815Sjsg struct intel_digital_port *dig_port =
8005ca02815Sjsg dp_to_dig_port(intel_dp);
8015ca02815Sjsg u32 pp;
8025ca02815Sjsg i915_reg_t pp_stat_reg, pp_ctrl_reg;
8035ca02815Sjsg
8041bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
8055ca02815Sjsg
8065ca02815Sjsg drm_WARN_ON(&dev_priv->drm, intel_dp->pps.want_panel_vdd);
8075ca02815Sjsg
8085ca02815Sjsg if (!edp_have_panel_vdd(intel_dp))
8095ca02815Sjsg return;
8105ca02815Sjsg
811*f005ef32Sjsg drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] %s turning VDD off\n",
812*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
813*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps));
8145ca02815Sjsg
8155ca02815Sjsg pp = ilk_get_pp_control(intel_dp);
8165ca02815Sjsg pp &= ~EDP_FORCE_VDD;
8175ca02815Sjsg
8185ca02815Sjsg pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
8195ca02815Sjsg pp_stat_reg = _pp_stat_reg(intel_dp);
8205ca02815Sjsg
8215ca02815Sjsg intel_de_write(dev_priv, pp_ctrl_reg, pp);
8225ca02815Sjsg intel_de_posting_read(dev_priv, pp_ctrl_reg);
8235ca02815Sjsg
8245ca02815Sjsg /* Make sure sequencer is idle before allowing subsequent activity */
825*f005ef32Sjsg drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] %s PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n",
826*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
827*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps),
8285ca02815Sjsg intel_de_read(dev_priv, pp_stat_reg),
8295ca02815Sjsg intel_de_read(dev_priv, pp_ctrl_reg));
8305ca02815Sjsg
8315ca02815Sjsg if ((pp & PANEL_POWER_ON) == 0)
8325ca02815Sjsg intel_dp->pps.panel_power_off_time = ktime_get_boottime();
8335ca02815Sjsg
8345ca02815Sjsg intel_display_power_put(dev_priv,
8355ca02815Sjsg intel_aux_power_domain(dig_port),
8365ca02815Sjsg fetch_and_zero(&intel_dp->pps.vdd_wakeref));
8375ca02815Sjsg }
8385ca02815Sjsg
intel_pps_vdd_off_sync(struct intel_dp * intel_dp)8395ca02815Sjsg void intel_pps_vdd_off_sync(struct intel_dp *intel_dp)
8405ca02815Sjsg {
8415ca02815Sjsg intel_wakeref_t wakeref;
8425ca02815Sjsg
8435ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
8445ca02815Sjsg return;
8455ca02815Sjsg
8465ca02815Sjsg cancel_delayed_work_sync(&intel_dp->pps.panel_vdd_work);
8475ca02815Sjsg /*
8485ca02815Sjsg * vdd might still be enabled due to the delayed vdd off.
8495ca02815Sjsg * Make sure vdd is actually turned off here.
8505ca02815Sjsg */
8515ca02815Sjsg with_intel_pps_lock(intel_dp, wakeref)
8525ca02815Sjsg intel_pps_vdd_off_sync_unlocked(intel_dp);
8535ca02815Sjsg }
8545ca02815Sjsg
edp_panel_vdd_work(struct work_struct * __work)8555ca02815Sjsg static void edp_panel_vdd_work(struct work_struct *__work)
8565ca02815Sjsg {
8575ca02815Sjsg struct intel_pps *pps = container_of(to_delayed_work(__work),
8585ca02815Sjsg struct intel_pps, panel_vdd_work);
8595ca02815Sjsg struct intel_dp *intel_dp = container_of(pps, struct intel_dp, pps);
8605ca02815Sjsg intel_wakeref_t wakeref;
8615ca02815Sjsg
8625ca02815Sjsg with_intel_pps_lock(intel_dp, wakeref) {
8635ca02815Sjsg if (!intel_dp->pps.want_panel_vdd)
8645ca02815Sjsg intel_pps_vdd_off_sync_unlocked(intel_dp);
8655ca02815Sjsg }
8665ca02815Sjsg }
8675ca02815Sjsg
edp_panel_vdd_schedule_off(struct intel_dp * intel_dp)8685ca02815Sjsg static void edp_panel_vdd_schedule_off(struct intel_dp *intel_dp)
8695ca02815Sjsg {
870*f005ef32Sjsg struct drm_i915_private *i915 = dp_to_i915(intel_dp);
8715ca02815Sjsg unsigned long delay;
8725ca02815Sjsg
8735ca02815Sjsg /*
8741bb76ff1Sjsg * We may not yet know the real power sequencing delays,
8751bb76ff1Sjsg * so keep VDD enabled until we're done with init.
8761bb76ff1Sjsg */
8771bb76ff1Sjsg if (intel_dp->pps.initializing)
8781bb76ff1Sjsg return;
8791bb76ff1Sjsg
8801bb76ff1Sjsg /*
8815ca02815Sjsg * Queue the timer to fire a long time from now (relative to the power
8825ca02815Sjsg * down delay) to keep the panel power up across a sequence of
8835ca02815Sjsg * operations.
8845ca02815Sjsg */
8855ca02815Sjsg delay = msecs_to_jiffies(intel_dp->pps.panel_power_cycle_delay * 5);
886*f005ef32Sjsg queue_delayed_work(i915->unordered_wq,
887*f005ef32Sjsg &intel_dp->pps.panel_vdd_work, delay);
8885ca02815Sjsg }
8895ca02815Sjsg
8905ca02815Sjsg /*
8915ca02815Sjsg * Must be paired with edp_panel_vdd_on().
8925ca02815Sjsg * Must hold pps_mutex around the whole on/off sequence.
8935ca02815Sjsg * Can be nested with intel_pps_vdd_{on,off}() calls.
8945ca02815Sjsg */
intel_pps_vdd_off_unlocked(struct intel_dp * intel_dp,bool sync)8955ca02815Sjsg void intel_pps_vdd_off_unlocked(struct intel_dp *intel_dp, bool sync)
8965ca02815Sjsg {
8975ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
8985ca02815Sjsg
8991bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
9005ca02815Sjsg
9015ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
9025ca02815Sjsg return;
9035ca02815Sjsg
904*f005ef32Sjsg I915_STATE_WARN(dev_priv, !intel_dp->pps.want_panel_vdd,
905*f005ef32Sjsg "[ENCODER:%d:%s] %s VDD not forced on",
9065ca02815Sjsg dp_to_dig_port(intel_dp)->base.base.base.id,
907*f005ef32Sjsg dp_to_dig_port(intel_dp)->base.base.name,
908*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps));
9095ca02815Sjsg
9105ca02815Sjsg intel_dp->pps.want_panel_vdd = false;
9115ca02815Sjsg
9125ca02815Sjsg if (sync)
9135ca02815Sjsg intel_pps_vdd_off_sync_unlocked(intel_dp);
9145ca02815Sjsg else
9155ca02815Sjsg edp_panel_vdd_schedule_off(intel_dp);
9165ca02815Sjsg }
9175ca02815Sjsg
intel_pps_on_unlocked(struct intel_dp * intel_dp)9185ca02815Sjsg void intel_pps_on_unlocked(struct intel_dp *intel_dp)
9195ca02815Sjsg {
9205ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
9215ca02815Sjsg u32 pp;
9225ca02815Sjsg i915_reg_t pp_ctrl_reg;
9235ca02815Sjsg
9241bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
9255ca02815Sjsg
9265ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
9275ca02815Sjsg return;
9285ca02815Sjsg
929*f005ef32Sjsg drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] %s turn panel power on\n",
9305ca02815Sjsg dp_to_dig_port(intel_dp)->base.base.base.id,
931*f005ef32Sjsg dp_to_dig_port(intel_dp)->base.base.name,
932*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps));
9335ca02815Sjsg
9345ca02815Sjsg if (drm_WARN(&dev_priv->drm, edp_have_panel_power(intel_dp),
935*f005ef32Sjsg "[ENCODER:%d:%s] %s panel power already on\n",
9365ca02815Sjsg dp_to_dig_port(intel_dp)->base.base.base.id,
937*f005ef32Sjsg dp_to_dig_port(intel_dp)->base.base.name,
938*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps)))
9395ca02815Sjsg return;
9405ca02815Sjsg
9415ca02815Sjsg wait_panel_power_cycle(intel_dp);
9425ca02815Sjsg
9435ca02815Sjsg pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
9445ca02815Sjsg pp = ilk_get_pp_control(intel_dp);
9455ca02815Sjsg if (IS_IRONLAKE(dev_priv)) {
9465ca02815Sjsg /* ILK workaround: disable reset around power sequence */
9475ca02815Sjsg pp &= ~PANEL_POWER_RESET;
9485ca02815Sjsg intel_de_write(dev_priv, pp_ctrl_reg, pp);
9495ca02815Sjsg intel_de_posting_read(dev_priv, pp_ctrl_reg);
9505ca02815Sjsg }
9515ca02815Sjsg
9525ca02815Sjsg pp |= PANEL_POWER_ON;
9535ca02815Sjsg if (!IS_IRONLAKE(dev_priv))
9545ca02815Sjsg pp |= PANEL_POWER_RESET;
9555ca02815Sjsg
9565ca02815Sjsg intel_de_write(dev_priv, pp_ctrl_reg, pp);
9575ca02815Sjsg intel_de_posting_read(dev_priv, pp_ctrl_reg);
9585ca02815Sjsg
9595ca02815Sjsg wait_panel_on(intel_dp);
9605ca02815Sjsg intel_dp->pps.last_power_on = jiffies;
9615ca02815Sjsg
9625ca02815Sjsg if (IS_IRONLAKE(dev_priv)) {
9635ca02815Sjsg pp |= PANEL_POWER_RESET; /* restore panel reset bit */
9645ca02815Sjsg intel_de_write(dev_priv, pp_ctrl_reg, pp);
9655ca02815Sjsg intel_de_posting_read(dev_priv, pp_ctrl_reg);
9665ca02815Sjsg }
9675ca02815Sjsg }
9685ca02815Sjsg
intel_pps_on(struct intel_dp * intel_dp)9695ca02815Sjsg void intel_pps_on(struct intel_dp *intel_dp)
9705ca02815Sjsg {
9715ca02815Sjsg intel_wakeref_t wakeref;
9725ca02815Sjsg
9735ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
9745ca02815Sjsg return;
9755ca02815Sjsg
9765ca02815Sjsg with_intel_pps_lock(intel_dp, wakeref)
9775ca02815Sjsg intel_pps_on_unlocked(intel_dp);
9785ca02815Sjsg }
9795ca02815Sjsg
intel_pps_off_unlocked(struct intel_dp * intel_dp)9805ca02815Sjsg void intel_pps_off_unlocked(struct intel_dp *intel_dp)
9815ca02815Sjsg {
9825ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
9835ca02815Sjsg struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
9845ca02815Sjsg u32 pp;
9855ca02815Sjsg i915_reg_t pp_ctrl_reg;
9865ca02815Sjsg
9871bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
9885ca02815Sjsg
9895ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
9905ca02815Sjsg return;
9915ca02815Sjsg
992*f005ef32Sjsg drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] %s turn panel power off\n",
993*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
994*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps));
9955ca02815Sjsg
9965ca02815Sjsg drm_WARN(&dev_priv->drm, !intel_dp->pps.want_panel_vdd,
997*f005ef32Sjsg "[ENCODER:%d:%s] %s need VDD to turn off panel\n",
998*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
999*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps));
10005ca02815Sjsg
10015ca02815Sjsg pp = ilk_get_pp_control(intel_dp);
10025ca02815Sjsg /* We need to switch off panel power _and_ force vdd, for otherwise some
10035ca02815Sjsg * panels get very unhappy and cease to work. */
10045ca02815Sjsg pp &= ~(PANEL_POWER_ON | PANEL_POWER_RESET | EDP_FORCE_VDD |
10055ca02815Sjsg EDP_BLC_ENABLE);
10065ca02815Sjsg
10075ca02815Sjsg pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
10085ca02815Sjsg
10095ca02815Sjsg intel_dp->pps.want_panel_vdd = false;
10105ca02815Sjsg
10115ca02815Sjsg intel_de_write(dev_priv, pp_ctrl_reg, pp);
10125ca02815Sjsg intel_de_posting_read(dev_priv, pp_ctrl_reg);
10135ca02815Sjsg
10145ca02815Sjsg wait_panel_off(intel_dp);
10155ca02815Sjsg intel_dp->pps.panel_power_off_time = ktime_get_boottime();
10165ca02815Sjsg
10175ca02815Sjsg /* We got a reference when we enabled the VDD. */
10185ca02815Sjsg intel_display_power_put(dev_priv,
10195ca02815Sjsg intel_aux_power_domain(dig_port),
10205ca02815Sjsg fetch_and_zero(&intel_dp->pps.vdd_wakeref));
10215ca02815Sjsg }
10225ca02815Sjsg
intel_pps_off(struct intel_dp * intel_dp)10235ca02815Sjsg void intel_pps_off(struct intel_dp *intel_dp)
10245ca02815Sjsg {
10255ca02815Sjsg intel_wakeref_t wakeref;
10265ca02815Sjsg
10275ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
10285ca02815Sjsg return;
10295ca02815Sjsg
10305ca02815Sjsg with_intel_pps_lock(intel_dp, wakeref)
10315ca02815Sjsg intel_pps_off_unlocked(intel_dp);
10325ca02815Sjsg }
10335ca02815Sjsg
10345ca02815Sjsg /* Enable backlight in the panel power control. */
intel_pps_backlight_on(struct intel_dp * intel_dp)10355ca02815Sjsg void intel_pps_backlight_on(struct intel_dp *intel_dp)
10365ca02815Sjsg {
10375ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
10385ca02815Sjsg intel_wakeref_t wakeref;
10395ca02815Sjsg
10405ca02815Sjsg /*
10415ca02815Sjsg * If we enable the backlight right away following a panel power
10425ca02815Sjsg * on, we may see slight flicker as the panel syncs with the eDP
10435ca02815Sjsg * link. So delay a bit to make sure the image is solid before
10445ca02815Sjsg * allowing it to appear.
10455ca02815Sjsg */
10465ca02815Sjsg wait_backlight_on(intel_dp);
10475ca02815Sjsg
10485ca02815Sjsg with_intel_pps_lock(intel_dp, wakeref) {
10495ca02815Sjsg i915_reg_t pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
10505ca02815Sjsg u32 pp;
10515ca02815Sjsg
10525ca02815Sjsg pp = ilk_get_pp_control(intel_dp);
10535ca02815Sjsg pp |= EDP_BLC_ENABLE;
10545ca02815Sjsg
10555ca02815Sjsg intel_de_write(dev_priv, pp_ctrl_reg, pp);
10565ca02815Sjsg intel_de_posting_read(dev_priv, pp_ctrl_reg);
10575ca02815Sjsg }
10585ca02815Sjsg }
10595ca02815Sjsg
10605ca02815Sjsg /* Disable backlight in the panel power control. */
intel_pps_backlight_off(struct intel_dp * intel_dp)10615ca02815Sjsg void intel_pps_backlight_off(struct intel_dp *intel_dp)
10625ca02815Sjsg {
10635ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
10645ca02815Sjsg intel_wakeref_t wakeref;
10655ca02815Sjsg
10665ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
10675ca02815Sjsg return;
10685ca02815Sjsg
10695ca02815Sjsg with_intel_pps_lock(intel_dp, wakeref) {
10705ca02815Sjsg i915_reg_t pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
10715ca02815Sjsg u32 pp;
10725ca02815Sjsg
10735ca02815Sjsg pp = ilk_get_pp_control(intel_dp);
10745ca02815Sjsg pp &= ~EDP_BLC_ENABLE;
10755ca02815Sjsg
10765ca02815Sjsg intel_de_write(dev_priv, pp_ctrl_reg, pp);
10775ca02815Sjsg intel_de_posting_read(dev_priv, pp_ctrl_reg);
10785ca02815Sjsg }
10795ca02815Sjsg
10805ca02815Sjsg intel_dp->pps.last_backlight_off = jiffies;
10815ca02815Sjsg edp_wait_backlight_off(intel_dp);
10825ca02815Sjsg }
10835ca02815Sjsg
10845ca02815Sjsg /*
10855ca02815Sjsg * Hook for controlling the panel power control backlight through the bl_power
10865ca02815Sjsg * sysfs attribute. Take care to handle multiple calls.
10875ca02815Sjsg */
intel_pps_backlight_power(struct intel_connector * connector,bool enable)10885ca02815Sjsg void intel_pps_backlight_power(struct intel_connector *connector, bool enable)
10895ca02815Sjsg {
10905ca02815Sjsg struct drm_i915_private *i915 = to_i915(connector->base.dev);
10915ca02815Sjsg struct intel_dp *intel_dp = intel_attached_dp(connector);
10925ca02815Sjsg intel_wakeref_t wakeref;
10935ca02815Sjsg bool is_enabled;
10945ca02815Sjsg
10955ca02815Sjsg is_enabled = false;
10965ca02815Sjsg with_intel_pps_lock(intel_dp, wakeref)
10975ca02815Sjsg is_enabled = ilk_get_pp_control(intel_dp) & EDP_BLC_ENABLE;
10985ca02815Sjsg if (is_enabled == enable)
10995ca02815Sjsg return;
11005ca02815Sjsg
11015ca02815Sjsg drm_dbg_kms(&i915->drm, "panel power control backlight %s\n",
11025ca02815Sjsg enable ? "enable" : "disable");
11035ca02815Sjsg
11045ca02815Sjsg if (enable)
11055ca02815Sjsg intel_pps_backlight_on(intel_dp);
11065ca02815Sjsg else
11075ca02815Sjsg intel_pps_backlight_off(intel_dp);
11085ca02815Sjsg }
11095ca02815Sjsg
vlv_detach_power_sequencer(struct intel_dp * intel_dp)11105ca02815Sjsg static void vlv_detach_power_sequencer(struct intel_dp *intel_dp)
11115ca02815Sjsg {
11125ca02815Sjsg struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
11135ca02815Sjsg struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
11145ca02815Sjsg enum pipe pipe = intel_dp->pps.pps_pipe;
11155ca02815Sjsg i915_reg_t pp_on_reg = PP_ON_DELAYS(pipe);
11165ca02815Sjsg
11175ca02815Sjsg drm_WARN_ON(&dev_priv->drm, intel_dp->pps.active_pipe != INVALID_PIPE);
11185ca02815Sjsg
11195ca02815Sjsg if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B))
11205ca02815Sjsg return;
11215ca02815Sjsg
11225ca02815Sjsg intel_pps_vdd_off_sync_unlocked(intel_dp);
11235ca02815Sjsg
11245ca02815Sjsg /*
11255ca02815Sjsg * VLV seems to get confused when multiple power sequencers
11265ca02815Sjsg * have the same port selected (even if only one has power/vdd
11275ca02815Sjsg * enabled). The failure manifests as vlv_wait_port_ready() failing
11285ca02815Sjsg * CHV on the other hand doesn't seem to mind having the same port
11295ca02815Sjsg * selected in multiple power sequencers, but let's clear the
11305ca02815Sjsg * port select always when logically disconnecting a power sequencer
11315ca02815Sjsg * from a port.
11325ca02815Sjsg */
11335ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
1134*f005ef32Sjsg "detaching %s from [ENCODER:%d:%s]\n",
1135*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps),
1136*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name);
11375ca02815Sjsg intel_de_write(dev_priv, pp_on_reg, 0);
11385ca02815Sjsg intel_de_posting_read(dev_priv, pp_on_reg);
11395ca02815Sjsg
11405ca02815Sjsg intel_dp->pps.pps_pipe = INVALID_PIPE;
11415ca02815Sjsg }
11425ca02815Sjsg
vlv_steal_power_sequencer(struct drm_i915_private * dev_priv,enum pipe pipe)11435ca02815Sjsg static void vlv_steal_power_sequencer(struct drm_i915_private *dev_priv,
11445ca02815Sjsg enum pipe pipe)
11455ca02815Sjsg {
11465ca02815Sjsg struct intel_encoder *encoder;
11475ca02815Sjsg
11481bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
11495ca02815Sjsg
11505ca02815Sjsg for_each_intel_dp(&dev_priv->drm, encoder) {
11515ca02815Sjsg struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
11525ca02815Sjsg
11535ca02815Sjsg drm_WARN(&dev_priv->drm, intel_dp->pps.active_pipe == pipe,
1154*f005ef32Sjsg "stealing PPS %c from active [ENCODER:%d:%s]\n",
11555ca02815Sjsg pipe_name(pipe), encoder->base.base.id,
11565ca02815Sjsg encoder->base.name);
11575ca02815Sjsg
11585ca02815Sjsg if (intel_dp->pps.pps_pipe != pipe)
11595ca02815Sjsg continue;
11605ca02815Sjsg
11615ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
1162*f005ef32Sjsg "stealing PPS %c from [ENCODER:%d:%s]\n",
11635ca02815Sjsg pipe_name(pipe), encoder->base.base.id,
11645ca02815Sjsg encoder->base.name);
11655ca02815Sjsg
11665ca02815Sjsg /* make sure vdd is off before we steal it */
11675ca02815Sjsg vlv_detach_power_sequencer(intel_dp);
11685ca02815Sjsg }
11695ca02815Sjsg }
11705ca02815Sjsg
vlv_pps_init(struct intel_encoder * encoder,const struct intel_crtc_state * crtc_state)11715ca02815Sjsg void vlv_pps_init(struct intel_encoder *encoder,
11725ca02815Sjsg const struct intel_crtc_state *crtc_state)
11735ca02815Sjsg {
11745ca02815Sjsg struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
11755ca02815Sjsg struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
11765ca02815Sjsg struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
11775ca02815Sjsg
11781bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
11795ca02815Sjsg
11805ca02815Sjsg drm_WARN_ON(&dev_priv->drm, intel_dp->pps.active_pipe != INVALID_PIPE);
11815ca02815Sjsg
11825ca02815Sjsg if (intel_dp->pps.pps_pipe != INVALID_PIPE &&
11835ca02815Sjsg intel_dp->pps.pps_pipe != crtc->pipe) {
11845ca02815Sjsg /*
11855ca02815Sjsg * If another power sequencer was being used on this
11865ca02815Sjsg * port previously make sure to turn off vdd there while
11875ca02815Sjsg * we still have control of it.
11885ca02815Sjsg */
11895ca02815Sjsg vlv_detach_power_sequencer(intel_dp);
11905ca02815Sjsg }
11915ca02815Sjsg
11925ca02815Sjsg /*
11935ca02815Sjsg * We may be stealing the power
11945ca02815Sjsg * sequencer from another port.
11955ca02815Sjsg */
11965ca02815Sjsg vlv_steal_power_sequencer(dev_priv, crtc->pipe);
11975ca02815Sjsg
11985ca02815Sjsg intel_dp->pps.active_pipe = crtc->pipe;
11995ca02815Sjsg
12005ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
12015ca02815Sjsg return;
12025ca02815Sjsg
12035ca02815Sjsg /* now it's all ours */
12045ca02815Sjsg intel_dp->pps.pps_pipe = crtc->pipe;
12055ca02815Sjsg
12065ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
1207*f005ef32Sjsg "initializing %s for [ENCODER:%d:%s]\n",
1208*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps),
1209*f005ef32Sjsg encoder->base.base.id, encoder->base.name);
12105ca02815Sjsg
12115ca02815Sjsg /* init power sequencer on this pipe and port */
12125ca02815Sjsg pps_init_delays(intel_dp);
12135ca02815Sjsg pps_init_registers(intel_dp, true);
12145ca02815Sjsg }
12155ca02815Sjsg
pps_vdd_init(struct intel_dp * intel_dp)12161bb76ff1Sjsg static void pps_vdd_init(struct intel_dp *intel_dp)
12175ca02815Sjsg {
12185ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
12195ca02815Sjsg struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
12205ca02815Sjsg
12211bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
12225ca02815Sjsg
12235ca02815Sjsg if (!edp_have_panel_vdd(intel_dp))
12245ca02815Sjsg return;
12255ca02815Sjsg
12265ca02815Sjsg /*
12275ca02815Sjsg * The VDD bit needs a power domain reference, so if the bit is
12285ca02815Sjsg * already enabled when we boot or resume, grab this reference and
12295ca02815Sjsg * schedule a vdd off, so we don't hold on to the reference
12305ca02815Sjsg * indefinitely.
12315ca02815Sjsg */
12325ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
1233*f005ef32Sjsg "[ENCODER:%d:%s] %s VDD left on by BIOS, adjusting state tracking\n",
1234*f005ef32Sjsg dig_port->base.base.base.id, dig_port->base.base.name,
1235*f005ef32Sjsg pps_name(dev_priv, &intel_dp->pps));
12365ca02815Sjsg drm_WARN_ON(&dev_priv->drm, intel_dp->pps.vdd_wakeref);
12375ca02815Sjsg intel_dp->pps.vdd_wakeref = intel_display_power_get(dev_priv,
12385ca02815Sjsg intel_aux_power_domain(dig_port));
12395ca02815Sjsg }
12405ca02815Sjsg
intel_pps_have_panel_power_or_vdd(struct intel_dp * intel_dp)12419572d05fSjsg bool intel_pps_have_panel_power_or_vdd(struct intel_dp *intel_dp)
12425ca02815Sjsg {
12435ca02815Sjsg intel_wakeref_t wakeref;
12445ca02815Sjsg bool have_power = false;
12455ca02815Sjsg
12465ca02815Sjsg with_intel_pps_lock(intel_dp, wakeref) {
12479572d05fSjsg have_power = edp_have_panel_power(intel_dp) ||
12485ca02815Sjsg edp_have_panel_vdd(intel_dp);
12495ca02815Sjsg }
12505ca02815Sjsg
12515ca02815Sjsg return have_power;
12525ca02815Sjsg }
12535ca02815Sjsg
pps_init_timestamps(struct intel_dp * intel_dp)12545ca02815Sjsg static void pps_init_timestamps(struct intel_dp *intel_dp)
12555ca02815Sjsg {
1256*f005ef32Sjsg /*
1257*f005ef32Sjsg * Initialize panel power off time to 0, assuming panel power could have
1258*f005ef32Sjsg * been toggled between kernel boot and now only by a previously loaded
1259*f005ef32Sjsg * and removed i915, which has already ensured sufficient power off
1260*f005ef32Sjsg * delay at module remove.
1261*f005ef32Sjsg */
1262*f005ef32Sjsg intel_dp->pps.panel_power_off_time = 0;
12635ca02815Sjsg intel_dp->pps.last_power_on = jiffies;
12645ca02815Sjsg intel_dp->pps.last_backlight_off = jiffies;
12655ca02815Sjsg }
12665ca02815Sjsg
12675ca02815Sjsg static void
intel_pps_readout_hw_state(struct intel_dp * intel_dp,struct edp_power_seq * seq)12685ca02815Sjsg intel_pps_readout_hw_state(struct intel_dp *intel_dp, struct edp_power_seq *seq)
12695ca02815Sjsg {
12705ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
12715ca02815Sjsg u32 pp_on, pp_off, pp_ctl;
12725ca02815Sjsg struct pps_registers regs;
12735ca02815Sjsg
12745ca02815Sjsg intel_pps_get_registers(intel_dp, ®s);
12755ca02815Sjsg
12765ca02815Sjsg pp_ctl = ilk_get_pp_control(intel_dp);
12775ca02815Sjsg
12785ca02815Sjsg /* Ensure PPS is unlocked */
12795ca02815Sjsg if (!HAS_DDI(dev_priv))
12805ca02815Sjsg intel_de_write(dev_priv, regs.pp_ctrl, pp_ctl);
12815ca02815Sjsg
12825ca02815Sjsg pp_on = intel_de_read(dev_priv, regs.pp_on);
12835ca02815Sjsg pp_off = intel_de_read(dev_priv, regs.pp_off);
12845ca02815Sjsg
12855ca02815Sjsg /* Pull timing values out of registers */
12865ca02815Sjsg seq->t1_t3 = REG_FIELD_GET(PANEL_POWER_UP_DELAY_MASK, pp_on);
12875ca02815Sjsg seq->t8 = REG_FIELD_GET(PANEL_LIGHT_ON_DELAY_MASK, pp_on);
12885ca02815Sjsg seq->t9 = REG_FIELD_GET(PANEL_LIGHT_OFF_DELAY_MASK, pp_off);
12895ca02815Sjsg seq->t10 = REG_FIELD_GET(PANEL_POWER_DOWN_DELAY_MASK, pp_off);
12905ca02815Sjsg
12915ca02815Sjsg if (i915_mmio_reg_valid(regs.pp_div)) {
12925ca02815Sjsg u32 pp_div;
12935ca02815Sjsg
12945ca02815Sjsg pp_div = intel_de_read(dev_priv, regs.pp_div);
12955ca02815Sjsg
12965ca02815Sjsg seq->t11_t12 = REG_FIELD_GET(PANEL_POWER_CYCLE_DELAY_MASK, pp_div) * 1000;
12975ca02815Sjsg } else {
12985ca02815Sjsg seq->t11_t12 = REG_FIELD_GET(BXT_POWER_CYCLE_DELAY_MASK, pp_ctl) * 1000;
12995ca02815Sjsg }
13005ca02815Sjsg }
13015ca02815Sjsg
13025ca02815Sjsg static void
intel_pps_dump_state(struct intel_dp * intel_dp,const char * state_name,const struct edp_power_seq * seq)13031bb76ff1Sjsg intel_pps_dump_state(struct intel_dp *intel_dp, const char *state_name,
13041bb76ff1Sjsg const struct edp_power_seq *seq)
13055ca02815Sjsg {
13061bb76ff1Sjsg struct drm_i915_private *i915 = dp_to_i915(intel_dp);
13071bb76ff1Sjsg
13081bb76ff1Sjsg drm_dbg_kms(&i915->drm, "%s t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
13095ca02815Sjsg state_name,
13105ca02815Sjsg seq->t1_t3, seq->t8, seq->t9, seq->t10, seq->t11_t12);
13115ca02815Sjsg }
13125ca02815Sjsg
13135ca02815Sjsg static void
intel_pps_verify_state(struct intel_dp * intel_dp)13145ca02815Sjsg intel_pps_verify_state(struct intel_dp *intel_dp)
13155ca02815Sjsg {
13161bb76ff1Sjsg struct drm_i915_private *i915 = dp_to_i915(intel_dp);
13175ca02815Sjsg struct edp_power_seq hw;
13185ca02815Sjsg struct edp_power_seq *sw = &intel_dp->pps.pps_delays;
13195ca02815Sjsg
13205ca02815Sjsg intel_pps_readout_hw_state(intel_dp, &hw);
13215ca02815Sjsg
13225ca02815Sjsg if (hw.t1_t3 != sw->t1_t3 || hw.t8 != sw->t8 || hw.t9 != sw->t9 ||
13235ca02815Sjsg hw.t10 != sw->t10 || hw.t11_t12 != sw->t11_t12) {
13241bb76ff1Sjsg drm_err(&i915->drm, "PPS state mismatch\n");
13251bb76ff1Sjsg intel_pps_dump_state(intel_dp, "sw", sw);
13261bb76ff1Sjsg intel_pps_dump_state(intel_dp, "hw", &hw);
13275ca02815Sjsg }
13285ca02815Sjsg }
13295ca02815Sjsg
pps_delays_valid(struct edp_power_seq * delays)13301bb76ff1Sjsg static bool pps_delays_valid(struct edp_power_seq *delays)
13311bb76ff1Sjsg {
13321bb76ff1Sjsg return delays->t1_t3 || delays->t8 || delays->t9 ||
13331bb76ff1Sjsg delays->t10 || delays->t11_t12;
13341bb76ff1Sjsg }
13351bb76ff1Sjsg
pps_init_delays_bios(struct intel_dp * intel_dp,struct edp_power_seq * bios)13361bb76ff1Sjsg static void pps_init_delays_bios(struct intel_dp *intel_dp,
13371bb76ff1Sjsg struct edp_power_seq *bios)
13381bb76ff1Sjsg {
13391bb76ff1Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
13401bb76ff1Sjsg
13411bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
13421bb76ff1Sjsg
13431bb76ff1Sjsg if (!pps_delays_valid(&intel_dp->pps.bios_pps_delays))
13441bb76ff1Sjsg intel_pps_readout_hw_state(intel_dp, &intel_dp->pps.bios_pps_delays);
13451bb76ff1Sjsg
13461bb76ff1Sjsg *bios = intel_dp->pps.bios_pps_delays;
13471bb76ff1Sjsg
13481bb76ff1Sjsg intel_pps_dump_state(intel_dp, "bios", bios);
13491bb76ff1Sjsg }
13501bb76ff1Sjsg
pps_init_delays_vbt(struct intel_dp * intel_dp,struct edp_power_seq * vbt)13511bb76ff1Sjsg static void pps_init_delays_vbt(struct intel_dp *intel_dp,
13521bb76ff1Sjsg struct edp_power_seq *vbt)
13531bb76ff1Sjsg {
13541bb76ff1Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
13551bb76ff1Sjsg struct intel_connector *connector = intel_dp->attached_connector;
13561bb76ff1Sjsg
13571bb76ff1Sjsg *vbt = connector->panel.vbt.edp.pps;
13581bb76ff1Sjsg
13591bb76ff1Sjsg if (!pps_delays_valid(vbt))
13601bb76ff1Sjsg return;
13611bb76ff1Sjsg
13621bb76ff1Sjsg /* On Toshiba Satellite P50-C-18C system the VBT T12 delay
13631bb76ff1Sjsg * of 500ms appears to be too short. Ocassionally the panel
13641bb76ff1Sjsg * just fails to power back on. Increasing the delay to 800ms
13651bb76ff1Sjsg * seems sufficient to avoid this problem.
13661bb76ff1Sjsg */
13671bb76ff1Sjsg if (intel_has_quirk(dev_priv, QUIRK_INCREASE_T12_DELAY)) {
13681bb76ff1Sjsg vbt->t11_t12 = max_t(u16, vbt->t11_t12, 1300 * 10);
13691bb76ff1Sjsg drm_dbg_kms(&dev_priv->drm,
13701bb76ff1Sjsg "Increasing T12 panel delay as per the quirk to %d\n",
13711bb76ff1Sjsg vbt->t11_t12);
13721bb76ff1Sjsg }
13731bb76ff1Sjsg
13741bb76ff1Sjsg /* T11_T12 delay is special and actually in units of 100ms, but zero
13751bb76ff1Sjsg * based in the hw (so we need to add 100 ms). But the sw vbt
13761bb76ff1Sjsg * table multiplies it with 1000 to make it in units of 100usec,
13771bb76ff1Sjsg * too. */
13781bb76ff1Sjsg vbt->t11_t12 += 100 * 10;
13791bb76ff1Sjsg
13801bb76ff1Sjsg intel_pps_dump_state(intel_dp, "vbt", vbt);
13811bb76ff1Sjsg }
13821bb76ff1Sjsg
pps_init_delays_spec(struct intel_dp * intel_dp,struct edp_power_seq * spec)13831bb76ff1Sjsg static void pps_init_delays_spec(struct intel_dp *intel_dp,
13841bb76ff1Sjsg struct edp_power_seq *spec)
13851bb76ff1Sjsg {
13861bb76ff1Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
13871bb76ff1Sjsg
13881bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
13891bb76ff1Sjsg
13901bb76ff1Sjsg /* Upper limits from eDP 1.3 spec. Note that we use the clunky units of
13911bb76ff1Sjsg * our hw here, which are all in 100usec. */
13921bb76ff1Sjsg spec->t1_t3 = 210 * 10;
13931bb76ff1Sjsg spec->t8 = 50 * 10; /* no limit for t8, use t7 instead */
13941bb76ff1Sjsg spec->t9 = 50 * 10; /* no limit for t9, make it symmetric with t8 */
13951bb76ff1Sjsg spec->t10 = 500 * 10;
13961bb76ff1Sjsg /* This one is special and actually in units of 100ms, but zero
13971bb76ff1Sjsg * based in the hw (so we need to add 100 ms). But the sw vbt
13981bb76ff1Sjsg * table multiplies it with 1000 to make it in units of 100usec,
13991bb76ff1Sjsg * too. */
14001bb76ff1Sjsg spec->t11_t12 = (510 + 100) * 10;
14011bb76ff1Sjsg
14021bb76ff1Sjsg intel_pps_dump_state(intel_dp, "spec", spec);
14031bb76ff1Sjsg }
14041bb76ff1Sjsg
pps_init_delays(struct intel_dp * intel_dp)14055ca02815Sjsg static void pps_init_delays(struct intel_dp *intel_dp)
14065ca02815Sjsg {
14075ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
14085ca02815Sjsg struct edp_power_seq cur, vbt, spec,
14095ca02815Sjsg *final = &intel_dp->pps.pps_delays;
14105ca02815Sjsg
14111bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
14125ca02815Sjsg
14135ca02815Sjsg /* already initialized? */
14141bb76ff1Sjsg if (pps_delays_valid(final))
14155ca02815Sjsg return;
14165ca02815Sjsg
14171bb76ff1Sjsg pps_init_delays_bios(intel_dp, &cur);
14181bb76ff1Sjsg pps_init_delays_vbt(intel_dp, &vbt);
14191bb76ff1Sjsg pps_init_delays_spec(intel_dp, &spec);
14205ca02815Sjsg
14215ca02815Sjsg /* Use the max of the register settings and vbt. If both are
14225ca02815Sjsg * unset, fall back to the spec limits. */
14235ca02815Sjsg #define assign_final(field) final->field = (max(cur.field, vbt.field) == 0 ? \
14245ca02815Sjsg spec.field : \
14255ca02815Sjsg max(cur.field, vbt.field))
14265ca02815Sjsg assign_final(t1_t3);
14275ca02815Sjsg assign_final(t8);
14285ca02815Sjsg assign_final(t9);
14295ca02815Sjsg assign_final(t10);
14305ca02815Sjsg assign_final(t11_t12);
14315ca02815Sjsg #undef assign_final
14325ca02815Sjsg
14335ca02815Sjsg #define get_delay(field) (DIV_ROUND_UP(final->field, 10))
14345ca02815Sjsg intel_dp->pps.panel_power_up_delay = get_delay(t1_t3);
14355ca02815Sjsg intel_dp->pps.backlight_on_delay = get_delay(t8);
14365ca02815Sjsg intel_dp->pps.backlight_off_delay = get_delay(t9);
14375ca02815Sjsg intel_dp->pps.panel_power_down_delay = get_delay(t10);
14385ca02815Sjsg intel_dp->pps.panel_power_cycle_delay = get_delay(t11_t12);
14395ca02815Sjsg #undef get_delay
14405ca02815Sjsg
14415ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
14425ca02815Sjsg "panel power up delay %d, power down delay %d, power cycle delay %d\n",
14435ca02815Sjsg intel_dp->pps.panel_power_up_delay,
14445ca02815Sjsg intel_dp->pps.panel_power_down_delay,
14455ca02815Sjsg intel_dp->pps.panel_power_cycle_delay);
14465ca02815Sjsg
14475ca02815Sjsg drm_dbg_kms(&dev_priv->drm, "backlight on delay %d, off delay %d\n",
14485ca02815Sjsg intel_dp->pps.backlight_on_delay,
14495ca02815Sjsg intel_dp->pps.backlight_off_delay);
14505ca02815Sjsg
14515ca02815Sjsg /*
14525ca02815Sjsg * We override the HW backlight delays to 1 because we do manual waits
14535ca02815Sjsg * on them. For T8, even BSpec recommends doing it. For T9, if we
14545ca02815Sjsg * don't do this, we'll end up waiting for the backlight off delay
14555ca02815Sjsg * twice: once when we do the manual sleep, and once when we disable
14565ca02815Sjsg * the panel and wait for the PP_STATUS bit to become zero.
14575ca02815Sjsg */
14585ca02815Sjsg final->t8 = 1;
14595ca02815Sjsg final->t9 = 1;
14605ca02815Sjsg
14615ca02815Sjsg /*
14625ca02815Sjsg * HW has only a 100msec granularity for t11_t12 so round it up
14635ca02815Sjsg * accordingly.
14645ca02815Sjsg */
14655ca02815Sjsg final->t11_t12 = roundup(final->t11_t12, 100 * 10);
14665ca02815Sjsg }
14675ca02815Sjsg
pps_init_registers(struct intel_dp * intel_dp,bool force_disable_vdd)14685ca02815Sjsg static void pps_init_registers(struct intel_dp *intel_dp, bool force_disable_vdd)
14695ca02815Sjsg {
14705ca02815Sjsg struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
14715ca02815Sjsg u32 pp_on, pp_off, port_sel = 0;
14725ca02815Sjsg int div = RUNTIME_INFO(dev_priv)->rawclk_freq / 1000;
14735ca02815Sjsg struct pps_registers regs;
14745ca02815Sjsg enum port port = dp_to_dig_port(intel_dp)->base.port;
14755ca02815Sjsg const struct edp_power_seq *seq = &intel_dp->pps.pps_delays;
14765ca02815Sjsg
14771bb76ff1Sjsg lockdep_assert_held(&dev_priv->display.pps.mutex);
14785ca02815Sjsg
14795ca02815Sjsg intel_pps_get_registers(intel_dp, ®s);
14805ca02815Sjsg
14815ca02815Sjsg /*
14825ca02815Sjsg * On some VLV machines the BIOS can leave the VDD
14835ca02815Sjsg * enabled even on power sequencers which aren't
14845ca02815Sjsg * hooked up to any port. This would mess up the
14855ca02815Sjsg * power domain tracking the first time we pick
14865ca02815Sjsg * one of these power sequencers for use since
14875ca02815Sjsg * intel_pps_vdd_on_unlocked() would notice that the VDD was
14885ca02815Sjsg * already on and therefore wouldn't grab the power
14895ca02815Sjsg * domain reference. Disable VDD first to avoid this.
14905ca02815Sjsg * This also avoids spuriously turning the VDD on as
14915ca02815Sjsg * soon as the new power sequencer gets initialized.
14925ca02815Sjsg */
14935ca02815Sjsg if (force_disable_vdd) {
14945ca02815Sjsg u32 pp = ilk_get_pp_control(intel_dp);
14955ca02815Sjsg
14965ca02815Sjsg drm_WARN(&dev_priv->drm, pp & PANEL_POWER_ON,
14975ca02815Sjsg "Panel power already on\n");
14985ca02815Sjsg
14995ca02815Sjsg if (pp & EDP_FORCE_VDD)
15005ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
15015ca02815Sjsg "VDD already on, disabling first\n");
15025ca02815Sjsg
15035ca02815Sjsg pp &= ~EDP_FORCE_VDD;
15045ca02815Sjsg
15055ca02815Sjsg intel_de_write(dev_priv, regs.pp_ctrl, pp);
15065ca02815Sjsg }
15075ca02815Sjsg
15085ca02815Sjsg pp_on = REG_FIELD_PREP(PANEL_POWER_UP_DELAY_MASK, seq->t1_t3) |
15095ca02815Sjsg REG_FIELD_PREP(PANEL_LIGHT_ON_DELAY_MASK, seq->t8);
15105ca02815Sjsg pp_off = REG_FIELD_PREP(PANEL_LIGHT_OFF_DELAY_MASK, seq->t9) |
15115ca02815Sjsg REG_FIELD_PREP(PANEL_POWER_DOWN_DELAY_MASK, seq->t10);
15125ca02815Sjsg
15135ca02815Sjsg /* Haswell doesn't have any port selection bits for the panel
15145ca02815Sjsg * power sequencer any more. */
15155ca02815Sjsg if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
15165ca02815Sjsg port_sel = PANEL_PORT_SELECT_VLV(port);
15175ca02815Sjsg } else if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) {
15185ca02815Sjsg switch (port) {
15195ca02815Sjsg case PORT_A:
15205ca02815Sjsg port_sel = PANEL_PORT_SELECT_DPA;
15215ca02815Sjsg break;
15225ca02815Sjsg case PORT_C:
15235ca02815Sjsg port_sel = PANEL_PORT_SELECT_DPC;
15245ca02815Sjsg break;
15255ca02815Sjsg case PORT_D:
15265ca02815Sjsg port_sel = PANEL_PORT_SELECT_DPD;
15275ca02815Sjsg break;
15285ca02815Sjsg default:
15295ca02815Sjsg MISSING_CASE(port);
15305ca02815Sjsg break;
15315ca02815Sjsg }
15325ca02815Sjsg }
15335ca02815Sjsg
15345ca02815Sjsg pp_on |= port_sel;
15355ca02815Sjsg
15365ca02815Sjsg intel_de_write(dev_priv, regs.pp_on, pp_on);
15375ca02815Sjsg intel_de_write(dev_priv, regs.pp_off, pp_off);
15385ca02815Sjsg
15395ca02815Sjsg /*
15405ca02815Sjsg * Compute the divisor for the pp clock, simply match the Bspec formula.
15415ca02815Sjsg */
1542*f005ef32Sjsg if (i915_mmio_reg_valid(regs.pp_div))
15435ca02815Sjsg intel_de_write(dev_priv, regs.pp_div,
15445ca02815Sjsg REG_FIELD_PREP(PP_REFERENCE_DIVIDER_MASK, (100 * div) / 2 - 1) | REG_FIELD_PREP(PANEL_POWER_CYCLE_DELAY_MASK, DIV_ROUND_UP(seq->t11_t12, 1000)));
1545*f005ef32Sjsg else
1546*f005ef32Sjsg intel_de_rmw(dev_priv, regs.pp_ctrl, BXT_POWER_CYCLE_DELAY_MASK,
1547*f005ef32Sjsg REG_FIELD_PREP(BXT_POWER_CYCLE_DELAY_MASK,
1548*f005ef32Sjsg DIV_ROUND_UP(seq->t11_t12, 1000)));
15495ca02815Sjsg
15505ca02815Sjsg drm_dbg_kms(&dev_priv->drm,
15515ca02815Sjsg "panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n",
15525ca02815Sjsg intel_de_read(dev_priv, regs.pp_on),
15535ca02815Sjsg intel_de_read(dev_priv, regs.pp_off),
15545ca02815Sjsg i915_mmio_reg_valid(regs.pp_div) ?
15555ca02815Sjsg intel_de_read(dev_priv, regs.pp_div) :
15565ca02815Sjsg (intel_de_read(dev_priv, regs.pp_ctrl) & BXT_POWER_CYCLE_DELAY_MASK));
15575ca02815Sjsg }
15585ca02815Sjsg
intel_pps_encoder_reset(struct intel_dp * intel_dp)15595ca02815Sjsg void intel_pps_encoder_reset(struct intel_dp *intel_dp)
15605ca02815Sjsg {
15615ca02815Sjsg struct drm_i915_private *i915 = dp_to_i915(intel_dp);
15625ca02815Sjsg intel_wakeref_t wakeref;
15635ca02815Sjsg
15645ca02815Sjsg if (!intel_dp_is_edp(intel_dp))
15655ca02815Sjsg return;
15665ca02815Sjsg
15675ca02815Sjsg with_intel_pps_lock(intel_dp, wakeref) {
15685ca02815Sjsg /*
15695ca02815Sjsg * Reinit the power sequencer also on the resume path, in case
15705ca02815Sjsg * BIOS did something nasty with it.
15715ca02815Sjsg */
15725ca02815Sjsg if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
15735ca02815Sjsg vlv_initial_power_sequencer_setup(intel_dp);
15745ca02815Sjsg
15755ca02815Sjsg pps_init_delays(intel_dp);
15765ca02815Sjsg pps_init_registers(intel_dp, false);
15771bb76ff1Sjsg pps_vdd_init(intel_dp);
15785ca02815Sjsg
15791bb76ff1Sjsg if (edp_have_panel_vdd(intel_dp))
15801bb76ff1Sjsg edp_panel_vdd_schedule_off(intel_dp);
15815ca02815Sjsg }
15825ca02815Sjsg }
15835ca02815Sjsg
intel_pps_init(struct intel_dp * intel_dp)1584*f005ef32Sjsg bool intel_pps_init(struct intel_dp *intel_dp)
15855ca02815Sjsg {
15861bb76ff1Sjsg intel_wakeref_t wakeref;
1587*f005ef32Sjsg bool ret;
15881bb76ff1Sjsg
15891bb76ff1Sjsg intel_dp->pps.initializing = true;
15905ca02815Sjsg INIT_DELAYED_WORK(&intel_dp->pps.panel_vdd_work, edp_panel_vdd_work);
15915ca02815Sjsg
15925ca02815Sjsg pps_init_timestamps(intel_dp);
15935ca02815Sjsg
15941bb76ff1Sjsg with_intel_pps_lock(intel_dp, wakeref) {
1595*f005ef32Sjsg ret = pps_initial_setup(intel_dp);
15961bb76ff1Sjsg
15971bb76ff1Sjsg pps_init_delays(intel_dp);
15981bb76ff1Sjsg pps_init_registers(intel_dp, false);
15991bb76ff1Sjsg pps_vdd_init(intel_dp);
16001bb76ff1Sjsg }
1601*f005ef32Sjsg
1602*f005ef32Sjsg return ret;
1603*f005ef32Sjsg }
1604*f005ef32Sjsg
pps_init_late(struct intel_dp * intel_dp)1605*f005ef32Sjsg static void pps_init_late(struct intel_dp *intel_dp)
1606*f005ef32Sjsg {
1607*f005ef32Sjsg struct drm_i915_private *i915 = dp_to_i915(intel_dp);
1608*f005ef32Sjsg struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
1609*f005ef32Sjsg struct intel_connector *connector = intel_dp->attached_connector;
1610*f005ef32Sjsg
1611*f005ef32Sjsg if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
1612*f005ef32Sjsg return;
1613*f005ef32Sjsg
1614*f005ef32Sjsg if (intel_num_pps(i915) < 2)
1615*f005ef32Sjsg return;
1616*f005ef32Sjsg
1617*f005ef32Sjsg drm_WARN(&i915->drm, connector->panel.vbt.backlight.controller >= 0 &&
1618*f005ef32Sjsg intel_dp->pps.pps_idx != connector->panel.vbt.backlight.controller,
1619*f005ef32Sjsg "[ENCODER:%d:%s] power sequencer mismatch: %d (initial) vs. %d (VBT)\n",
1620*f005ef32Sjsg encoder->base.base.id, encoder->base.name,
1621*f005ef32Sjsg intel_dp->pps.pps_idx, connector->panel.vbt.backlight.controller);
1622*f005ef32Sjsg
1623*f005ef32Sjsg if (connector->panel.vbt.backlight.controller >= 0)
1624*f005ef32Sjsg intel_dp->pps.pps_idx = connector->panel.vbt.backlight.controller;
16251bb76ff1Sjsg }
16261bb76ff1Sjsg
intel_pps_init_late(struct intel_dp * intel_dp)16271bb76ff1Sjsg void intel_pps_init_late(struct intel_dp *intel_dp)
16281bb76ff1Sjsg {
16291bb76ff1Sjsg intel_wakeref_t wakeref;
16301bb76ff1Sjsg
16311bb76ff1Sjsg with_intel_pps_lock(intel_dp, wakeref) {
16321bb76ff1Sjsg /* Reinit delays after per-panel info has been parsed from VBT */
1633*f005ef32Sjsg pps_init_late(intel_dp);
1634*f005ef32Sjsg
16351bb76ff1Sjsg memset(&intel_dp->pps.pps_delays, 0, sizeof(intel_dp->pps.pps_delays));
16361bb76ff1Sjsg pps_init_delays(intel_dp);
16371bb76ff1Sjsg pps_init_registers(intel_dp, false);
16381bb76ff1Sjsg
16391bb76ff1Sjsg intel_dp->pps.initializing = false;
16401bb76ff1Sjsg
16411bb76ff1Sjsg if (edp_have_panel_vdd(intel_dp))
16421bb76ff1Sjsg edp_panel_vdd_schedule_off(intel_dp);
16431bb76ff1Sjsg }
16445ca02815Sjsg }
16455ca02815Sjsg
intel_pps_unlock_regs_wa(struct drm_i915_private * dev_priv)16465ca02815Sjsg void intel_pps_unlock_regs_wa(struct drm_i915_private *dev_priv)
16475ca02815Sjsg {
16485ca02815Sjsg int pps_num;
16495ca02815Sjsg int pps_idx;
16505ca02815Sjsg
16515ca02815Sjsg if (!HAS_DISPLAY(dev_priv) || HAS_DDI(dev_priv))
16525ca02815Sjsg return;
16535ca02815Sjsg /*
16545ca02815Sjsg * This w/a is needed at least on CPT/PPT, but to be sure apply it
16555ca02815Sjsg * everywhere where registers can be write protected.
16565ca02815Sjsg */
1657*f005ef32Sjsg pps_num = intel_num_pps(dev_priv);
16585ca02815Sjsg
1659*f005ef32Sjsg for (pps_idx = 0; pps_idx < pps_num; pps_idx++)
1660*f005ef32Sjsg intel_de_rmw(dev_priv, PP_CONTROL(pps_idx),
1661*f005ef32Sjsg PANEL_UNLOCK_MASK, PANEL_UNLOCK_REGS);
16625ca02815Sjsg }
16635ca02815Sjsg
intel_pps_setup(struct drm_i915_private * i915)16645ca02815Sjsg void intel_pps_setup(struct drm_i915_private *i915)
16655ca02815Sjsg {
16665ca02815Sjsg if (HAS_PCH_SPLIT(i915) || IS_GEMINILAKE(i915) || IS_BROXTON(i915))
16671bb76ff1Sjsg i915->display.pps.mmio_base = PCH_PPS_BASE;
16685ca02815Sjsg else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
16691bb76ff1Sjsg i915->display.pps.mmio_base = VLV_PPS_BASE;
16705ca02815Sjsg else
16711bb76ff1Sjsg i915->display.pps.mmio_base = PPS_BASE;
16721bb76ff1Sjsg }
16731bb76ff1Sjsg
assert_pps_unlocked(struct drm_i915_private * dev_priv,enum pipe pipe)16741bb76ff1Sjsg void assert_pps_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe)
16751bb76ff1Sjsg {
16761bb76ff1Sjsg i915_reg_t pp_reg;
16771bb76ff1Sjsg u32 val;
16781bb76ff1Sjsg enum pipe panel_pipe = INVALID_PIPE;
16791bb76ff1Sjsg bool locked = true;
16801bb76ff1Sjsg
16811bb76ff1Sjsg if (drm_WARN_ON(&dev_priv->drm, HAS_DDI(dev_priv)))
16821bb76ff1Sjsg return;
16831bb76ff1Sjsg
16841bb76ff1Sjsg if (HAS_PCH_SPLIT(dev_priv)) {
16851bb76ff1Sjsg u32 port_sel;
16861bb76ff1Sjsg
16871bb76ff1Sjsg pp_reg = PP_CONTROL(0);
16881bb76ff1Sjsg port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK;
16891bb76ff1Sjsg
16901bb76ff1Sjsg switch (port_sel) {
16911bb76ff1Sjsg case PANEL_PORT_SELECT_LVDS:
16921bb76ff1Sjsg intel_lvds_port_enabled(dev_priv, PCH_LVDS, &panel_pipe);
16931bb76ff1Sjsg break;
16941bb76ff1Sjsg case PANEL_PORT_SELECT_DPA:
16951bb76ff1Sjsg g4x_dp_port_enabled(dev_priv, DP_A, PORT_A, &panel_pipe);
16961bb76ff1Sjsg break;
16971bb76ff1Sjsg case PANEL_PORT_SELECT_DPC:
16981bb76ff1Sjsg g4x_dp_port_enabled(dev_priv, PCH_DP_C, PORT_C, &panel_pipe);
16991bb76ff1Sjsg break;
17001bb76ff1Sjsg case PANEL_PORT_SELECT_DPD:
17011bb76ff1Sjsg g4x_dp_port_enabled(dev_priv, PCH_DP_D, PORT_D, &panel_pipe);
17021bb76ff1Sjsg break;
17031bb76ff1Sjsg default:
17041bb76ff1Sjsg MISSING_CASE(port_sel);
17051bb76ff1Sjsg break;
17061bb76ff1Sjsg }
17071bb76ff1Sjsg } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
17081bb76ff1Sjsg /* presumably write lock depends on pipe, not port select */
17091bb76ff1Sjsg pp_reg = PP_CONTROL(pipe);
17101bb76ff1Sjsg panel_pipe = pipe;
17111bb76ff1Sjsg } else {
17121bb76ff1Sjsg u32 port_sel;
17131bb76ff1Sjsg
17141bb76ff1Sjsg pp_reg = PP_CONTROL(0);
17151bb76ff1Sjsg port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK;
17161bb76ff1Sjsg
17171bb76ff1Sjsg drm_WARN_ON(&dev_priv->drm,
17181bb76ff1Sjsg port_sel != PANEL_PORT_SELECT_LVDS);
17191bb76ff1Sjsg intel_lvds_port_enabled(dev_priv, LVDS, &panel_pipe);
17201bb76ff1Sjsg }
17211bb76ff1Sjsg
17221bb76ff1Sjsg val = intel_de_read(dev_priv, pp_reg);
17231bb76ff1Sjsg if (!(val & PANEL_POWER_ON) ||
17241bb76ff1Sjsg ((val & PANEL_UNLOCK_MASK) == PANEL_UNLOCK_REGS))
17251bb76ff1Sjsg locked = false;
17261bb76ff1Sjsg
1727*f005ef32Sjsg I915_STATE_WARN(dev_priv, panel_pipe == pipe && locked,
17281bb76ff1Sjsg "panel assertion failure, pipe %c regs locked\n",
17291bb76ff1Sjsg pipe_name(pipe));
17305ca02815Sjsg }
1731