On Tue, Jun 05, 2012 at 10:07:10AM +0200, Daniel Vetter wrote: > On gen4+ we have a bitfield to specify from which pipe the backlight > controller should take it's clock. For PCH split platforms we've > already set these up, but only at initialization time. And without > taking into account the 3rd pipe added with ivb. > > For gen4, we've completely ignored these. Although we do restrict lvds > to the 2nd pipe, so this is only a problem on machines where we boot > up with the lvds on the first pipe. > > So restructure the code to enable the backlight on the right pipe at > modeset time. > > v2: For odd reasons panel_enable_backlight gets called twice in a > modeset, so we can't WARN_ON in there if the backlight controller is > switched on already. Note that further inspections showed that nothing odd is going on, these are just dpms on/off calls from Xorg. I've simply forgotten to update the commit message and the comment in the code ... -Daniel > > Tested-By: Kamal Mostafa <kamal at canonical.com> > Bugzilla: https://bugs.launchpad.net/bugs/954661 > Cc: Carsten Emde <C.Emde at osadl.org> > Signed-Off-by: Daniel Vetter <daniel.vetter at ffwll.ch> > --- > drivers/gpu/drm/i915/intel_drv.h | 3 +- > drivers/gpu/drm/i915/intel_lvds.c | 32 +++++------------------------ > drivers/gpu/drm/i915/intel_panel.c | 38 +++++++++++++++++++++++++++++++++++- > 3 files changed, 45 insertions(+), 28 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 39d7b07..2fc2623 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -377,7 +377,8 @@ extern u32 intel_panel_get_max_backlight(struct drm_device *dev); > extern u32 intel_panel_get_backlight(struct drm_device *dev); > extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); > extern int intel_panel_setup_backlight(struct drm_device *dev); > -extern void intel_panel_enable_backlight(struct drm_device *dev); > +extern void intel_panel_enable_backlight(struct drm_device *dev, > + enum pipe pipe); > extern void intel_panel_disable_backlight(struct drm_device *dev); > extern void intel_panel_destroy_backlight(struct drm_device *dev); > extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); > diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c > index a7269e6..492db77 100644 > --- a/drivers/gpu/drm/i915/intel_lvds.c > +++ b/drivers/gpu/drm/i915/intel_lvds.c > @@ -71,6 +71,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) > static void intel_lvds_enable(struct intel_lvds *intel_lvds) > { > struct drm_device *dev = intel_lvds->base.base.dev; > + struct intel_crtc *intel_crtc = to_intel_crtc(intel_lvds->base.base.crtc); > struct drm_i915_private *dev_priv = dev->dev_private; > u32 ctl_reg, lvds_reg, stat_reg; > > @@ -107,7 +108,7 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds) > if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) > DRM_ERROR("timed out waiting for panel to power on\n"); > > - intel_panel_enable_backlight(dev); > + intel_panel_enable_backlight(dev, intel_crtc->pipe); > } > > static void intel_lvds_disable(struct intel_lvds *intel_lvds) > @@ -1074,35 +1075,14 @@ bool intel_lvds_init(struct drm_device *dev) > goto failed; > > out: > + /* > + * Unlock registers and just > + * leave them unlocked > + */ > if (HAS_PCH_SPLIT(dev)) { > - u32 pwm; > - > - pipe = (I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT) ? 1 : 0; > - > - /* make sure PWM is enabled and locked to the LVDS pipe */ > - pwm = I915_READ(BLC_PWM_CPU_CTL2); > - if (pipe == 0 && (pwm & BLM_PIPE_B)) > - I915_WRITE(BLC_PWM_CPU_CTL2, pwm & ~BLM_PWM_ENABLE); > - if (pipe) > - pwm |= BLM_PIPE_B; > - else > - pwm &= ~BLM_PIPE_B; > - I915_WRITE(BLC_PWM_CPU_CTL2, pwm | BLM_PWM_ENABLE); > - > - pwm = I915_READ(BLC_PWM_PCH_CTL1); > - pwm |= BLM_PCH_PWM_ENABLE; > - I915_WRITE(BLC_PWM_PCH_CTL1, pwm); > - /* > - * Unlock registers and just > - * leave them unlocked > - */ > I915_WRITE(PCH_PP_CONTROL, > I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); > } else { > - /* > - * Unlock registers and just > - * leave them unlocked > - */ > I915_WRITE(PP_CONTROL, > I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); > } > diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c > index 2a1625d..5e52639 100644 > --- a/drivers/gpu/drm/i915/intel_panel.c > +++ b/drivers/gpu/drm/i915/intel_panel.c > @@ -287,9 +287,18 @@ void intel_panel_disable_backlight(struct drm_device *dev) > > dev_priv->backlight_enabled = false; > intel_panel_actually_set_backlight(dev, 0); > + > + if (INTEL_INFO(dev)->gen >= 4) { > + uint32_t reg; > + > + reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2; > + > + I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE); > + } > } > > -void intel_panel_enable_backlight(struct drm_device *dev) > +void intel_panel_enable_backlight(struct drm_device *dev, > + enum pipe pipe) > { > struct drm_i915_private *dev_priv = dev->dev_private; > > @@ -298,6 +307,33 @@ void intel_panel_enable_backlight(struct drm_device *dev) > > dev_priv->backlight_enabled = true; > intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); > + > + if (INTEL_INFO(dev)->gen >= 4) { > + uint32_t reg, tmp; > + > + reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2; > + > + > + tmp = I915_READ(reg); > + > + /* While modesetting this code gets called twice, hence don't > + * adjust the backlight pipe if the backlight pwm is enabled > + * again already. */ > + if (tmp & BLM_PWM_ENABLE) > + return; > + > + if (dev_priv->num_pipe == 3) > + tmp &= ~BLM_PIPE_SELECT_IVB; > + else > + tmp &= ~BLM_PIPE_SELECT; > + > + tmp |= BLM_PIPE(pipe); > + tmp &= ~BLM_PWM_ENABLE; > + > + I915_WRITE(reg, tmp); > + POSTING_READ(reg); > + I915_WRITE(reg, tmp | BLM_PWM_ENABLE); > + } > } > > static void intel_panel_init_backlight(struct drm_device *dev) > -- > 1.7.7.6 > -- Daniel Vetter Mail: daniel at ffwll.ch Mobile: +41 (0)79 365 57 48