diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_pps.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_pps.c | 59 | 
1 files changed, 59 insertions, 0 deletions
| diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index a36ec4a818ff..e9c679bb1b2e 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -9,6 +9,7 @@  #include "intel_display_types.h"  #include "intel_dp.h"  #include "intel_dpll.h" +#include "intel_lvds.h"  #include "intel_pps.h"  static void vlv_steal_power_sequencer(struct drm_i915_private *dev_priv, @@ -1408,3 +1409,61 @@ void intel_pps_setup(struct drm_i915_private *i915)  	else  		i915->pps_mmio_base = PPS_BASE;  } + +void assert_pps_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe) +{ +	i915_reg_t pp_reg; +	u32 val; +	enum pipe panel_pipe = INVALID_PIPE; +	bool locked = true; + +	if (drm_WARN_ON(&dev_priv->drm, HAS_DDI(dev_priv))) +		return; + +	if (HAS_PCH_SPLIT(dev_priv)) { +		u32 port_sel; + +		pp_reg = PP_CONTROL(0); +		port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK; + +		switch (port_sel) { +		case PANEL_PORT_SELECT_LVDS: +			intel_lvds_port_enabled(dev_priv, PCH_LVDS, &panel_pipe); +			break; +		case PANEL_PORT_SELECT_DPA: +			g4x_dp_port_enabled(dev_priv, DP_A, PORT_A, &panel_pipe); +			break; +		case PANEL_PORT_SELECT_DPC: +			g4x_dp_port_enabled(dev_priv, PCH_DP_C, PORT_C, &panel_pipe); +			break; +		case PANEL_PORT_SELECT_DPD: +			g4x_dp_port_enabled(dev_priv, PCH_DP_D, PORT_D, &panel_pipe); +			break; +		default: +			MISSING_CASE(port_sel); +			break; +		} +	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { +		/* presumably write lock depends on pipe, not port select */ +		pp_reg = PP_CONTROL(pipe); +		panel_pipe = pipe; +	} else { +		u32 port_sel; + +		pp_reg = PP_CONTROL(0); +		port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK; + +		drm_WARN_ON(&dev_priv->drm, +			    port_sel != PANEL_PORT_SELECT_LVDS); +		intel_lvds_port_enabled(dev_priv, LVDS, &panel_pipe); +	} + +	val = intel_de_read(dev_priv, pp_reg); +	if (!(val & PANEL_POWER_ON) || +	    ((val & PANEL_UNLOCK_MASK) == PANEL_UNLOCK_REGS)) +		locked = false; + +	I915_STATE_WARN(panel_pipe == pipe && locked, +			"panel assertion failure, pipe %c regs locked\n", +			pipe_name(pipe)); +} | 
