diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 86 | 
1 files changed, 61 insertions, 25 deletions
| diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5feb65725c04..46947fffd599 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1351,18 +1351,21 @@ void assert_pipe(struct drm_i915_private *dev_priv,  	bool cur_state;  	enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,  								      pipe); +	enum intel_display_power_domain power_domain;  	/* if we need the pipe quirk it must be always on */  	if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||  	    (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))  		state = true; -	if (!intel_display_power_is_enabled(dev_priv, -				POWER_DOMAIN_TRANSCODER(cpu_transcoder))) { -		cur_state = false; -	} else { +	power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); +	if (intel_display_power_get_if_enabled(dev_priv, power_domain)) {  		u32 val = I915_READ(PIPECONF(cpu_transcoder));  		cur_state = !!(val & PIPECONF_ENABLE); + +		intel_display_power_put(dev_priv, power_domain); +	} else { +		cur_state = false;  	}  	I915_STATE_WARN(cur_state != state, @@ -8171,18 +8174,22 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,  {  	struct drm_device *dev = crtc->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private; +	enum intel_display_power_domain power_domain;  	uint32_t tmp; +	bool ret; -	if (!intel_display_power_is_enabled(dev_priv, -					    POWER_DOMAIN_PIPE(crtc->pipe))) +	power_domain = POWER_DOMAIN_PIPE(crtc->pipe); +	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))  		return false;  	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;  	pipe_config->shared_dpll = DPLL_ID_PRIVATE; +	ret = false; +  	tmp = I915_READ(PIPECONF(crtc->pipe));  	if (!(tmp & PIPECONF_ENABLE)) -		return false; +		goto out;  	if (IS_G4X(dev) || IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {  		switch (tmp & PIPECONF_BPC_MASK) { @@ -8262,7 +8269,12 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,  	pipe_config->base.adjusted_mode.crtc_clock =  		pipe_config->port_clock / pipe_config->pixel_multiplier; -	return true; +	ret = true; + +out: +	intel_display_power_put(dev_priv, power_domain); + +	return ret;  }  static void ironlake_init_pch_refclk(struct drm_device *dev) @@ -9366,18 +9378,21 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,  {  	struct drm_device *dev = crtc->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private; +	enum intel_display_power_domain power_domain;  	uint32_t tmp; +	bool ret; -	if (!intel_display_power_is_enabled(dev_priv, -					    POWER_DOMAIN_PIPE(crtc->pipe))) +	power_domain = POWER_DOMAIN_PIPE(crtc->pipe); +	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))  		return false;  	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;  	pipe_config->shared_dpll = DPLL_ID_PRIVATE; +	ret = false;  	tmp = I915_READ(PIPECONF(crtc->pipe));  	if (!(tmp & PIPECONF_ENABLE)) -		return false; +		goto out;  	switch (tmp & PIPECONF_BPC_MASK) {  	case PIPECONF_6BPC: @@ -9440,7 +9455,12 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,  	ironlake_get_pfit_config(crtc, pipe_config); -	return true; +	ret = true; + +out: +	intel_display_power_put(dev_priv, power_domain); + +	return ret;  }  static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv) @@ -9950,12 +9970,17 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,  {  	struct drm_device *dev = crtc->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	enum intel_display_power_domain pfit_domain; +	enum intel_display_power_domain power_domain; +	unsigned long power_domain_mask;  	uint32_t tmp; +	bool ret; -	if (!intel_display_power_is_enabled(dev_priv, -					 POWER_DOMAIN_PIPE(crtc->pipe))) +	power_domain = POWER_DOMAIN_PIPE(crtc->pipe); +	if (!intel_display_power_get_if_enabled(dev_priv, power_domain))  		return false; +	power_domain_mask = BIT(power_domain); + +	ret = false;  	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;  	pipe_config->shared_dpll = DPLL_ID_PRIVATE; @@ -9982,13 +10007,14 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,  			pipe_config->cpu_transcoder = TRANSCODER_EDP;  	} -	if (!intel_display_power_is_enabled(dev_priv, -			POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder))) -		return false; +	power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder); +	if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) +		goto out; +	power_domain_mask |= BIT(power_domain);  	tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder));  	if (!(tmp & PIPECONF_ENABLE)) -		return false; +		goto out;  	haswell_get_ddi_port_state(crtc, pipe_config); @@ -9998,14 +10024,14 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,  		skl_init_scalers(dev, crtc, pipe_config);  	} -	pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe); -  	if (INTEL_INFO(dev)->gen >= 9) {  		pipe_config->scaler_state.scaler_id = -1;  		pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX);  	} -	if (intel_display_power_is_enabled(dev_priv, pfit_domain)) { +	power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe); +	if (intel_display_power_get_if_enabled(dev_priv, power_domain)) { +		power_domain_mask |= BIT(power_domain);  		if (INTEL_INFO(dev)->gen >= 9)  			skylake_get_pfit_config(crtc, pipe_config);  		else @@ -10023,7 +10049,13 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,  		pipe_config->pixel_multiplier = 1;  	} -	return true; +	ret = true; + +out: +	for_each_power_domain(power_domain, power_domain_mask) +		intel_display_power_put(dev_priv, power_domain); + +	return ret;  }  static void i845_update_cursor(struct drm_crtc *crtc, u32 base, bool on) @@ -13630,7 +13662,7 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,  {  	uint32_t val; -	if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS)) +	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))  		return false;  	val = I915_READ(PCH_DPLL(pll->id)); @@ -13638,6 +13670,8 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,  	hw_state->fp0 = I915_READ(PCH_FP0(pll->id));  	hw_state->fp1 = I915_READ(PCH_FP1(pll->id)); +	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); +  	return val & DPLL_VCO_ENABLE;  } @@ -15568,10 +15602,12 @@ void i915_redisable_vga(struct drm_device *dev)  	 * level, just check if the power well is enabled instead of trying to  	 * follow the "don't touch the power well if we don't need it" policy  	 * the rest of the driver uses. */ -	if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_VGA)) +	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_VGA))  		return;  	i915_redisable_vga_power_on(dev); + +	intel_display_power_put(dev_priv, POWER_DOMAIN_VGA);  }  static bool primary_get_hw_state(struct intel_plane *plane) | 
