[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