[Intel-gfx] [PATCH 04/58] drm/i915/hdmi: convert to encoder->disable/enable

Jesse Barnes jbarnes at virtuousgeek.org
Tue Sep 4 21:24:29 CEST 2012


On Sun, 19 Aug 2012 21:12:21 +0200
Daniel Vetter <daniel.vetter at ffwll.ch> wrote:
> +/* Even simpler default implementation, if there's really no special case to
> + * consider. */
> +void intel_connector_dpms(struct drm_connector *connector, int mode)
> +{
> +	struct intel_encoder *encoder = intel_attached_encoder(connector);
> +
> +	/* All the simple cases only support two dpms states. */
> +	if (mode != DRM_MODE_DPMS_ON)
> +		mode = DRM_MODE_DPMS_OFF;
> +
> +	if (mode == connector->dpms)
> +		return;
> +
> +	connector->dpms = mode;
> +
> +	/* Only need to change hw state when actually enabled */
> +	if (encoder->base.crtc)
> +		intel_encoder_dpms(encoder, mode);
> +	else
> +		encoder->connectors_active = false;
> +}

We only ever call this under the mode_config lock right?

> +
>  static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
>  				  const struct drm_display_mode *mode,
>  				  struct drm_display_mode *adjusted_mode)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 9a5adcc..759dcba 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -140,6 +140,7 @@ struct intel_encoder {
>  	 * simple flag is enough to compute the possible_clones mask.
>  	 */
>  	bool cloneable;
> +	bool connectors_active;
>  	void (*hot_plug)(struct intel_encoder *);
>  	void (*enable)(struct intel_encoder *);
>  	void (*disable)(struct intel_encoder *);
> @@ -412,7 +413,11 @@ extern enum drm_connector_status intel_panel_detect(struct drm_device *dev);
>  extern void intel_crtc_load_lut(struct drm_crtc *crtc);
>  extern void intel_encoder_prepare(struct drm_encoder *encoder);
>  extern void intel_encoder_commit(struct drm_encoder *encoder);
> +extern void intel_encoder_noop(struct drm_encoder *encoder);
> +extern void intel_encoder_disable(struct drm_encoder *encoder);
>  extern void intel_encoder_destroy(struct drm_encoder *encoder);
> +extern void intel_encoder_dpms(struct intel_encoder *encoder, int mode);
> +extern void intel_connector_dpms(struct drm_connector *, int mode);
>  
>  static inline struct intel_encoder *intel_attached_encoder(struct drm_connector *connector)
>  {
> @@ -519,7 +524,8 @@ extern void intel_disable_gt_powersave(struct drm_device *dev);
>  extern void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv);
>  extern void ironlake_teardown_rc6(struct drm_device *dev);
>  
> -extern void intel_ddi_dpms(struct drm_encoder *encoder, int mode);
> +extern void intel_enable_ddi(struct intel_encoder *encoder);
> +extern void intel_disable_ddi(struct intel_encoder *encoder);
>  extern void intel_ddi_mode_set(struct drm_encoder *encoder,
>  				struct drm_display_mode *mode,
>  				struct drm_display_mode *adjusted_mode);
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index e4c37bb..acddaaa 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -601,11 +601,11 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
>  	intel_hdmi->set_infoframes(encoder, adjusted_mode);
>  }
>  
> -static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
> +static void intel_enable_hdmi(struct intel_encoder *encoder)
>  {
> -	struct drm_device *dev = encoder->dev;
> +	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
> +	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>  	u32 temp;
>  	u32 enable_bits = SDVO_ENABLE;
>  
> @@ -617,31 +617,12 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
>  	/* HW workaround for IBX, we need to move the port to transcoder A
>  	 * before disabling it. */
>  	if (HAS_PCH_IBX(dev)) {
> -		struct drm_crtc *crtc = encoder->crtc;
> +		struct drm_crtc *crtc = encoder->base.crtc;
>  		int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
>  
> -		if (mode != DRM_MODE_DPMS_ON) {
> -			if (temp & SDVO_PIPE_B_SELECT) {
> -				temp &= ~SDVO_PIPE_B_SELECT;
> -				I915_WRITE(intel_hdmi->sdvox_reg, temp);
> -				POSTING_READ(intel_hdmi->sdvox_reg);
> -
> -				/* Again we need to write this twice. */
> -				I915_WRITE(intel_hdmi->sdvox_reg, temp);
> -				POSTING_READ(intel_hdmi->sdvox_reg);
> -
> -				/* Transcoder selection bits only update
> -				 * effectively on vblank. */
> -				if (crtc)
> -					intel_wait_for_vblank(dev, pipe);
> -				else
> -					msleep(50);
> -			}
> -		} else {
> -			/* Restore the transcoder select bit. */
> -			if (pipe == PIPE_B)
> -				enable_bits |= SDVO_PIPE_B_SELECT;
> -		}
> +		/* Restore the transcoder select bit. */
> +		if (pipe == PIPE_B)
> +			enable_bits |= SDVO_PIPE_B_SELECT;
>  	}
>  
>  	/* HW workaround, need to toggle enable bit off and on for 12bpc, but
> @@ -652,12 +633,67 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
>  		POSTING_READ(intel_hdmi->sdvox_reg);
>  	}
>  
> -	if (mode != DRM_MODE_DPMS_ON) {
> -		temp &= ~enable_bits;
> -	} else {
> -		temp |= enable_bits;
> +	temp |= enable_bits;
> +
> +	I915_WRITE(intel_hdmi->sdvox_reg, temp);
> +	POSTING_READ(intel_hdmi->sdvox_reg);
> +
> +	/* HW workaround, need to write this twice for issue that may result
> +	 * in first write getting masked.
> +	 */
> +	if (HAS_PCH_SPLIT(dev)) {
> +		I915_WRITE(intel_hdmi->sdvox_reg, temp);
> +		POSTING_READ(intel_hdmi->sdvox_reg);
> +	}
> +}
> +
> +static void intel_disable_hdmi(struct intel_encoder *encoder)
> +{
> +	struct drm_device *dev = encoder->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
> +	u32 temp;
> +	u32 enable_bits = SDVO_ENABLE;
> +
> +	if (intel_hdmi->has_audio)
> +		enable_bits |= SDVO_AUDIO_ENABLE;
> +
> +	temp = I915_READ(intel_hdmi->sdvox_reg);
> +
> +	/* HW workaround for IBX, we need to move the port to transcoder A
> +	 * before disabling it. */
> +	if (HAS_PCH_IBX(dev)) {
> +		struct drm_crtc *crtc = encoder->base.crtc;
> +		int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
> +
> +		if (temp & SDVO_PIPE_B_SELECT) {
> +			temp &= ~SDVO_PIPE_B_SELECT;
> +			I915_WRITE(intel_hdmi->sdvox_reg, temp);
> +			POSTING_READ(intel_hdmi->sdvox_reg);
> +
> +			/* Again we need to write this twice. */
> +			I915_WRITE(intel_hdmi->sdvox_reg, temp);
> +			POSTING_READ(intel_hdmi->sdvox_reg);
> +
> +			/* Transcoder selection bits only update
> +			 * effectively on vblank. */
> +			if (crtc)
> +				intel_wait_for_vblank(dev, pipe);
> +			else
> +				msleep(50);
> +		}
>  	}

The IBX stuff can be split out into a separate function hook with a
later patch...

Reviewed-by: Jesse Barnes <jbarnes at virtuousgeek.org>

-- 
Jesse Barnes, Intel Open Source Technology Center



More information about the Intel-gfx mailing list