On Sun, 19 Aug 2012 21:12:21 +0200
Daniel Vetter <daniel.vet...@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 <jbar...@virtuousgeek.org>

-- 
Jesse Barnes, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to