From db31af1d4e815e141295b0bdf8da3e77885001d5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Nov 2013 16:48:53 +0200 Subject: drm/i915: clean up backlight conditional build I've always felt the backlight device conditional build has been all backwards. Make it feel right. Gently move things towards connector based stuff while at it. There should be no functional changes. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 65 ++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 28 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index f161ac02c4f6..a0d13d3173ee 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -709,16 +709,6 @@ static void intel_panel_init_backlight_regs(struct drm_device *dev) } } -static void intel_panel_init_backlight(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - intel_panel_init_backlight_regs(dev); - - dev_priv->backlight.level = intel_panel_get_backlight(dev, 0); - dev_priv->backlight.enabled = dev_priv->backlight.level != 0; -} - enum drm_connector_status intel_panel_detect(struct drm_device *dev) { @@ -742,7 +732,7 @@ intel_panel_detect(struct drm_device *dev) } #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) -static int intel_panel_update_status(struct backlight_device *bd) +static int intel_backlight_device_update_status(struct backlight_device *bd) { struct intel_connector *connector = bl_get_data(bd); struct drm_device *dev = connector->base.dev; @@ -756,7 +746,7 @@ static int intel_panel_update_status(struct backlight_device *bd) return 0; } -static int intel_panel_get_brightness(struct backlight_device *bd) +static int intel_backlight_device_get_brightness(struct backlight_device *bd) { struct intel_connector *connector = bl_get_data(bd); struct drm_device *dev = connector->base.dev; @@ -771,20 +761,18 @@ static int intel_panel_get_brightness(struct backlight_device *bd) return intel_panel_get_backlight(connector->base.dev, pipe); } -static const struct backlight_ops intel_panel_bl_ops = { - .update_status = intel_panel_update_status, - .get_brightness = intel_panel_get_brightness, +static const struct backlight_ops intel_backlight_device_ops = { + .update_status = intel_backlight_device_update_status, + .get_brightness = intel_backlight_device_get_brightness, }; -int intel_panel_setup_backlight(struct drm_connector *connector) +static int intel_backlight_device_register(struct intel_connector *connector) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct backlight_properties props; unsigned long flags; - intel_panel_init_backlight(dev); - if (WARN_ON(dev_priv->backlight.device)) return -ENODEV; @@ -802,9 +790,9 @@ int intel_panel_setup_backlight(struct drm_connector *connector) } dev_priv->backlight.device = backlight_device_register("intel_backlight", - connector->kdev, - to_intel_connector(connector), - &intel_panel_bl_ops, &props); + connector->base.kdev, + connector, + &intel_backlight_device_ops, &props); if (IS_ERR(dev_priv->backlight.device)) { DRM_ERROR("Failed to register backlight: %ld\n", @@ -815,26 +803,47 @@ int intel_panel_setup_backlight(struct drm_connector *connector) return 0; } -void intel_panel_destroy_backlight(struct drm_device *dev) +static void intel_backlight_device_unregister(struct intel_connector *connector) { + struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; if (dev_priv->backlight.device) { backlight_device_unregister(dev_priv->backlight.device); dev_priv->backlight.device = NULL; } } -#else +#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */ +static int intel_backlight_device_register(struct intel_connector *connector) +{ + return 0; +} +static void intel_backlight_device_unregister(struct intel_connector *connector) +{ +} +#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ + int intel_panel_setup_backlight(struct drm_connector *connector) { - intel_panel_init_backlight(connector->dev); + struct drm_device *dev = connector->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_connector *intel_connector = to_intel_connector(connector); + + intel_panel_init_backlight_regs(dev); + + dev_priv->backlight.level = intel_panel_get_backlight(dev, 0); + dev_priv->backlight.enabled = dev_priv->backlight.level != 0; + + intel_backlight_device_register(intel_connector); + return 0; } -void intel_panel_destroy_backlight(struct drm_device *dev) +void intel_panel_destroy_backlight(struct drm_connector *connector) { - return; + struct intel_connector *intel_connector = to_intel_connector(connector); + + intel_backlight_device_unregister(intel_connector); } -#endif int intel_panel_init(struct intel_panel *panel, struct drm_display_mode *fixed_mode) -- cgit v1.2.3 From 58c68779e48fa6d60b97fadc3dcac61a6c318c4c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Nov 2013 16:48:54 +0200 Subject: drm/i915: make backlight info per-connector Move from dev_priv to connector->panel. We still don't allow multiple sysfs interfaces, though. There should be no functional changes, except for a slight reordering of connector backlight and sysfs destroy calls. (This change happens now that the backlight device is actually per-connector, even though the destroy calls became per-connector earlier.) Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 85 +++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 38 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index a0d13d3173ee..0a4aeaf96865 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -346,7 +346,7 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev, enum pipe pipe) struct drm_i915_private *dev_priv = dev->dev_private; u32 val; - WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight.lock)); + WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock)); /* Restore the CTL value if it lost, e.g. GPU reset */ @@ -449,7 +449,7 @@ static u32 intel_panel_get_backlight(struct drm_device *dev, unsigned long flags; int reg; - spin_lock_irqsave(&dev_priv->backlight.lock, flags); + spin_lock_irqsave(&dev_priv->backlight_lock, flags); if (HAS_PCH_SPLIT(dev)) { val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; @@ -473,7 +473,7 @@ static u32 intel_panel_get_backlight(struct drm_device *dev, val = intel_panel_compute_brightness(dev, pipe, val); - spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); + spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val); return val; @@ -530,6 +530,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level, { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); u32 freq; unsigned long flags; @@ -537,7 +538,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level, if (pipe == INVALID_PIPE) return; - spin_lock_irqsave(&dev_priv->backlight.lock, flags); + spin_lock_irqsave(&dev_priv->backlight_lock, flags); freq = intel_panel_get_max_backlight(dev, pipe); if (!freq) { @@ -551,20 +552,21 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level, else level = freq / max * level; - dev_priv->backlight.level = level; - if (dev_priv->backlight.device) - dev_priv->backlight.device->props.brightness = level; + panel->backlight.level = level; + if (panel->backlight.device) + panel->backlight.device->props.brightness = level; - if (dev_priv->backlight.enabled) + if (panel->backlight.enabled) intel_panel_actually_set_backlight(dev, pipe, level); out: - spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); + spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); } void intel_panel_disable_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); unsigned long flags; @@ -582,9 +584,9 @@ void intel_panel_disable_backlight(struct intel_connector *connector) return; } - spin_lock_irqsave(&dev_priv->backlight.lock, flags); + spin_lock_irqsave(&dev_priv->backlight_lock, flags); - dev_priv->backlight.enabled = false; + panel->backlight.enabled = false; intel_panel_actually_set_backlight(dev, pipe, 0); if (INTEL_INFO(dev)->gen >= 4) { @@ -606,13 +608,14 @@ void intel_panel_disable_backlight(struct intel_connector *connector) } } - spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); + spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); } void intel_panel_enable_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, pipe); @@ -623,14 +626,14 @@ void intel_panel_enable_backlight(struct intel_connector *connector) DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); - spin_lock_irqsave(&dev_priv->backlight.lock, flags); + spin_lock_irqsave(&dev_priv->backlight_lock, flags); - if (dev_priv->backlight.level == 0) { - dev_priv->backlight.level = intel_panel_get_max_backlight(dev, - pipe); - if (dev_priv->backlight.device) - dev_priv->backlight.device->props.brightness = - dev_priv->backlight.level; + if (panel->backlight.level == 0) { + panel->backlight.level = intel_panel_get_max_backlight(dev, + pipe); + if (panel->backlight.device) + panel->backlight.device->props.brightness = + panel->backlight.level; } if (INTEL_INFO(dev)->gen >= 4) { @@ -680,11 +683,11 @@ set_level: * BLC_PWM_CPU_CTL may be cleared to zero automatically when these * registers are set. */ - dev_priv->backlight.enabled = true; + panel->backlight.enabled = true; intel_panel_actually_set_backlight(dev, pipe, - dev_priv->backlight.level); + panel->backlight.level); - spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); + spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); } /* FIXME: use VBT vals to init PWM_CTL and PWM_CTL2 correctly */ @@ -770,34 +773,40 @@ static int intel_backlight_device_register(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_panel *panel = &connector->panel; struct backlight_properties props; unsigned long flags; - if (WARN_ON(dev_priv->backlight.device)) + if (WARN_ON(panel->backlight.device)) return -ENODEV; memset(&props, 0, sizeof(props)); props.type = BACKLIGHT_RAW; - props.brightness = dev_priv->backlight.level; + props.brightness = panel->backlight.level; - spin_lock_irqsave(&dev_priv->backlight.lock, flags); + spin_lock_irqsave(&dev_priv->backlight_lock, flags); props.max_brightness = intel_panel_get_max_backlight(dev, 0); - spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); + spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); if (props.max_brightness == 0) { DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n"); return -ENODEV; } - dev_priv->backlight.device = + + /* + * Note: using the same name independent of the connector prevents + * registration of multiple backlight devices in the driver. + */ + panel->backlight.device = backlight_device_register("intel_backlight", connector->base.kdev, connector, &intel_backlight_device_ops, &props); - if (IS_ERR(dev_priv->backlight.device)) { + if (IS_ERR(panel->backlight.device)) { DRM_ERROR("Failed to register backlight: %ld\n", - PTR_ERR(dev_priv->backlight.device)); - dev_priv->backlight.device = NULL; + PTR_ERR(panel->backlight.device)); + panel->backlight.device = NULL; return -ENODEV; } return 0; @@ -805,11 +814,11 @@ static int intel_backlight_device_register(struct intel_connector *connector) static void intel_backlight_device_unregister(struct intel_connector *connector) { - struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - if (dev_priv->backlight.device) { - backlight_device_unregister(dev_priv->backlight.device); - dev_priv->backlight.device = NULL; + struct intel_panel *panel = &connector->panel; + + if (panel->backlight.device) { + backlight_device_unregister(panel->backlight.device); + panel->backlight.device = NULL; } } #else /* CONFIG_BACKLIGHT_CLASS_DEVICE */ @@ -825,13 +834,13 @@ static void intel_backlight_device_unregister(struct intel_connector *connector) int intel_panel_setup_backlight(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_connector *intel_connector = to_intel_connector(connector); + struct intel_panel *panel = &intel_connector->panel; intel_panel_init_backlight_regs(dev); - dev_priv->backlight.level = intel_panel_get_backlight(dev, 0); - dev_priv->backlight.enabled = dev_priv->backlight.level != 0; + panel->backlight.level = intel_panel_get_backlight(dev, 0); + panel->backlight.enabled = panel->backlight.level != 0; intel_backlight_device_register(intel_connector); -- cgit v1.2.3 From c91c9f32843a1b433de5a1ead4789a6bc8d3d914 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Nov 2013 16:48:55 +0200 Subject: drm/i915: make asle notifications update backlight on all connectors ALthough usually there's only one connector that supports backlight, this also finds the correct connector. Before, we only updated the connector on pipe A, which might not be the one with backlight. (This only made a difference on BYT.) Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 0a4aeaf96865..c80bffc21b5b 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -844,13 +844,17 @@ int intel_panel_setup_backlight(struct drm_connector *connector) intel_backlight_device_register(intel_connector); + panel->backlight.present = true; + return 0; } void intel_panel_destroy_backlight(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); + struct intel_panel *panel = &intel_connector->panel; + panel->backlight.present = false; intel_backlight_device_unregister(intel_connector); } -- cgit v1.2.3 From 7bd688cd66db93f6430f6e2b3145ee5686daa315 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Nov 2013 16:48:56 +0200 Subject: drm/i915: handle backlight through chip specific functions The backlight code has grown rather hairy, not least because the hardware registers and bits have repeatedly been shuffled around. And this isn't expected to get any easier with new hardware. Make things easier for our (read: my) poor brains, and split the code up into chip specific functions. There should be no functional changes. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 642 +++++++++++++++++++++++++------------ 1 file changed, 434 insertions(+), 208 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index c80bffc21b5b..a821949a9c7a 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -338,79 +338,117 @@ static int is_backlight_combination_mode(struct drm_device *dev) return 0; } -/* XXX: query mode clock or hardware clock and program max PWM appropriately - * when it's 0. - */ -static u32 i915_read_blc_pwm_ctl(struct drm_device *dev, enum pipe pipe) +static u32 pch_get_max_backlight(struct intel_connector *connector) { + struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; u32 val; - WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock)); + val = I915_READ(BLC_PWM_PCH_CTL2); + if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) { + dev_priv->regfile.saveBLC_PWM_CTL2 = val; + } else if (val == 0) { + val = dev_priv->regfile.saveBLC_PWM_CTL2; + I915_WRITE(BLC_PWM_PCH_CTL2, val); + } - /* Restore the CTL value if it lost, e.g. GPU reset */ + val >>= 16; - if (HAS_PCH_SPLIT(dev_priv->dev)) { - val = I915_READ(BLC_PWM_PCH_CTL2); - if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) { - dev_priv->regfile.saveBLC_PWM_CTL2 = val; - } else if (val == 0) { - val = dev_priv->regfile.saveBLC_PWM_CTL2; - I915_WRITE(BLC_PWM_PCH_CTL2, val); - } - } else if (IS_VALLEYVIEW(dev)) { - val = I915_READ(VLV_BLC_PWM_CTL(pipe)); - if (dev_priv->regfile.saveBLC_PWM_CTL == 0) { - dev_priv->regfile.saveBLC_PWM_CTL = val; - dev_priv->regfile.saveBLC_PWM_CTL2 = - I915_READ(VLV_BLC_PWM_CTL2(pipe)); - } else if (val == 0) { - val = dev_priv->regfile.saveBLC_PWM_CTL; - I915_WRITE(VLV_BLC_PWM_CTL(pipe), val); - I915_WRITE(VLV_BLC_PWM_CTL2(pipe), - dev_priv->regfile.saveBLC_PWM_CTL2); - } + return val; +} - if (!val) - val = 0x0f42ffff; - } else { - val = I915_READ(BLC_PWM_CTL); - if (dev_priv->regfile.saveBLC_PWM_CTL == 0) { - dev_priv->regfile.saveBLC_PWM_CTL = val; - if (INTEL_INFO(dev)->gen >= 4) - dev_priv->regfile.saveBLC_PWM_CTL2 = - I915_READ(BLC_PWM_CTL2); - } else if (val == 0) { - val = dev_priv->regfile.saveBLC_PWM_CTL; - I915_WRITE(BLC_PWM_CTL, val); - if (INTEL_INFO(dev)->gen >= 4) - I915_WRITE(BLC_PWM_CTL2, - dev_priv->regfile.saveBLC_PWM_CTL2); - } +static u32 i9xx_get_max_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val; + + val = I915_READ(BLC_PWM_CTL); + if (dev_priv->regfile.saveBLC_PWM_CTL == 0) { + dev_priv->regfile.saveBLC_PWM_CTL = val; + } else if (val == 0) { + val = dev_priv->regfile.saveBLC_PWM_CTL; + I915_WRITE(BLC_PWM_CTL, val); } + val >>= 17; + + if (is_backlight_combination_mode(dev)) + val *= 0xff; + return val; } -static u32 intel_panel_get_max_backlight(struct drm_device *dev, - enum pipe pipe) +static u32 i965_get_max_backlight(struct intel_connector *connector) { - u32 max; + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val; + + val = I915_READ(BLC_PWM_CTL); + if (dev_priv->regfile.saveBLC_PWM_CTL == 0) { + dev_priv->regfile.saveBLC_PWM_CTL = val; + dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); + } else if (val == 0) { + val = dev_priv->regfile.saveBLC_PWM_CTL; + I915_WRITE(BLC_PWM_CTL, val); + I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2); + } - max = i915_read_blc_pwm_ctl(dev, pipe); + val >>= 16; - if (HAS_PCH_SPLIT(dev)) { - max >>= 16; - } else { - if (INTEL_INFO(dev)->gen < 4) - max >>= 17; - else - max >>= 16; + if (is_backlight_combination_mode(dev)) + val *= 0xff; + + return val; +} + +static u32 _vlv_get_max_backlight(struct drm_device *dev, enum pipe pipe) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val; - if (is_backlight_combination_mode(dev)) - max *= 0xff; + val = I915_READ(VLV_BLC_PWM_CTL(pipe)); + if (dev_priv->regfile.saveBLC_PWM_CTL == 0) { + dev_priv->regfile.saveBLC_PWM_CTL = val; + dev_priv->regfile.saveBLC_PWM_CTL2 = + I915_READ(VLV_BLC_PWM_CTL2(pipe)); + } else if (val == 0) { + val = dev_priv->regfile.saveBLC_PWM_CTL; + I915_WRITE(VLV_BLC_PWM_CTL(pipe), val); + I915_WRITE(VLV_BLC_PWM_CTL2(pipe), + dev_priv->regfile.saveBLC_PWM_CTL2); } + if (!val) + val = 0x0f42ffff; + + val >>= 16; + + return val; +} + +static u32 vlv_get_max_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + enum pipe pipe = intel_get_pipe_from_connector(connector); + + return _vlv_get_max_backlight(dev, pipe); +} + +/* XXX: query mode clock or hardware clock and program max PWM appropriately + * when it's 0. + */ +static u32 intel_panel_get_max_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 max; + + WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock)); + + max = dev_priv->display.get_max_backlight(connector); + DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); return max; @@ -423,9 +461,10 @@ MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness " "to dri-devel@lists.freedesktop.org, if your machine needs it. " "It will then be included in an upcoming module version."); module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600); -static u32 intel_panel_compute_brightness(struct drm_device *dev, - enum pipe pipe, u32 val) +static u32 intel_panel_compute_brightness(struct intel_connector *connector, + u32 val) { + struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; if (i915_panel_invert_brightness < 0) @@ -433,7 +472,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, if (i915_panel_invert_brightness > 0 || dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { - u32 max = intel_panel_get_max_backlight(dev, pipe); + u32 max = intel_panel_get_max_backlight(connector); if (max) return max - val; } @@ -441,37 +480,60 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, return val; } -static u32 intel_panel_get_backlight(struct drm_device *dev, - enum pipe pipe) +static u32 pch_get_backlight(struct intel_connector *connector) { + struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - u32 val; - unsigned long flags; - int reg; - spin_lock_irqsave(&dev_priv->backlight_lock, flags); + return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; +} - if (HAS_PCH_SPLIT(dev)) { - val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; - } else { - if (IS_VALLEYVIEW(dev)) - reg = VLV_BLC_PWM_CTL(pipe); - else - reg = BLC_PWM_CTL; +static u32 i9xx_get_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val; - val = I915_READ(reg) & BACKLIGHT_DUTY_CYCLE_MASK; - if (INTEL_INFO(dev)->gen < 4) - val >>= 1; + val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; + if (INTEL_INFO(dev)->gen < 4) + val >>= 1; - if (is_backlight_combination_mode(dev)) { - u8 lbpc; + if (is_backlight_combination_mode(dev)) { + u8 lbpc; - pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc); - val *= lbpc; - } + pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc); + val *= lbpc; } - val = intel_panel_compute_brightness(dev, pipe, val); + return val; +} + +static u32 _vlv_get_backlight(struct drm_device *dev, enum pipe pipe) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK; +} + +static u32 vlv_get_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + enum pipe pipe = intel_get_pipe_from_connector(connector); + + return _vlv_get_backlight(dev, pipe); +} + +static u32 intel_panel_get_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val; + unsigned long flags; + + spin_lock_irqsave(&dev_priv->backlight_lock, flags); + + val = dev_priv->display.get_backlight(connector); + val = intel_panel_compute_brightness(connector, val); spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); @@ -479,28 +541,24 @@ static u32 intel_panel_get_backlight(struct drm_device *dev, return val; } -static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level) +static void pch_set_backlight(struct intel_connector *connector, u32 level) { + struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - u32 val = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; - I915_WRITE(BLC_PWM_CPU_CTL, val | level); + u32 tmp; + + tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; + I915_WRITE(BLC_PWM_CPU_CTL, tmp | level); } -static void intel_panel_actually_set_backlight(struct drm_device *dev, - enum pipe pipe, u32 level) +static void i9xx_set_backlight(struct intel_connector *connector, u32 level) { + struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; u32 tmp; - int reg; - - DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); - level = intel_panel_compute_brightness(dev, pipe, level); - - if (HAS_PCH_SPLIT(dev)) - return intel_pch_panel_set_backlight(dev, level); if (is_backlight_combination_mode(dev)) { - u32 max = intel_panel_get_max_backlight(dev, pipe); + u32 max = intel_panel_get_max_backlight(connector); u8 lbpc; /* we're screwed, but keep behaviour backwards compatible */ @@ -512,16 +570,34 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev, pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc); } - if (IS_VALLEYVIEW(dev)) - reg = VLV_BLC_PWM_CTL(pipe); - else - reg = BLC_PWM_CTL; - - tmp = I915_READ(reg); if (INTEL_INFO(dev)->gen < 4) level <<= 1; - tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK; - I915_WRITE(reg, tmp | level); + + tmp = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; + I915_WRITE(BLC_PWM_CTL, tmp | level); +} + +static void vlv_set_backlight(struct intel_connector *connector, u32 level) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe = intel_get_pipe_from_connector(connector); + u32 tmp; + + tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK; + I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level); +} + +static void +intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); + + level = intel_panel_compute_brightness(connector, level); + dev_priv->display.set_backlight(connector, level); } /* set backlight brightness to level in range [0..max] */ @@ -540,7 +616,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level, spin_lock_irqsave(&dev_priv->backlight_lock, flags); - freq = intel_panel_get_max_backlight(dev, pipe); + freq = intel_panel_get_max_backlight(connector); if (!freq) { /* we are screwed, bail out */ goto out; @@ -557,11 +633,45 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level, panel->backlight.device->props.brightness = level; if (panel->backlight.enabled) - intel_panel_actually_set_backlight(dev, pipe, level); + intel_panel_actually_set_backlight(connector, level); out: spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); } +static void pch_disable_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 tmp; + + tmp = I915_READ(BLC_PWM_CPU_CTL2); + I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); + + tmp = I915_READ(BLC_PWM_PCH_CTL1); + I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); +} + +static void i965_disable_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 tmp; + + tmp = I915_READ(BLC_PWM_CTL2); + I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE); +} + +static void vlv_disable_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe = intel_get_pipe_from_connector(connector); + u32 tmp; + + tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe)); + I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE); +} + void intel_panel_disable_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; @@ -587,28 +697,100 @@ void intel_panel_disable_backlight(struct intel_connector *connector) spin_lock_irqsave(&dev_priv->backlight_lock, flags); panel->backlight.enabled = false; - intel_panel_actually_set_backlight(dev, pipe, 0); + intel_panel_actually_set_backlight(connector, 0); - if (INTEL_INFO(dev)->gen >= 4) { - uint32_t reg, tmp; + if (dev_priv->display.disable_backlight) + dev_priv->display.disable_backlight(connector); - if (HAS_PCH_SPLIT(dev)) - reg = BLC_PWM_CPU_CTL2; - else if (IS_VALLEYVIEW(dev)) - reg = VLV_BLC_PWM_CTL2(pipe); - else - reg = BLC_PWM_CTL2; + spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); +} - I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE); +static void pch_enable_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe = intel_get_pipe_from_connector(connector); + enum transcoder cpu_transcoder = + intel_pipe_to_cpu_transcoder(dev_priv, pipe); + u32 tmp; - if (HAS_PCH_SPLIT(dev)) { - tmp = I915_READ(BLC_PWM_PCH_CTL1); - tmp &= ~BLM_PCH_PWM_ENABLE; - I915_WRITE(BLC_PWM_PCH_CTL1, tmp); - } + tmp = I915_READ(BLC_PWM_CPU_CTL2); + + /* Note that this can also get called through dpms changes. And + * we don't track the backlight dpms state, hence check whether + * we have to do anything first. */ + if (tmp & BLM_PWM_ENABLE) + return; + + if (INTEL_INFO(dev)->num_pipes == 3) + tmp &= ~BLM_PIPE_SELECT_IVB; + else + tmp &= ~BLM_PIPE_SELECT; + + if (cpu_transcoder == TRANSCODER_EDP) + tmp |= BLM_TRANSCODER_EDP; + else + tmp |= BLM_PIPE(cpu_transcoder); + tmp &= ~BLM_PWM_ENABLE; + + I915_WRITE(BLC_PWM_CPU_CTL2, tmp); + POSTING_READ(BLC_PWM_CPU_CTL2); + I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE); + + if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) { + tmp = I915_READ(BLC_PWM_PCH_CTL1); + tmp |= BLM_PCH_PWM_ENABLE; + tmp &= ~BLM_PCH_OVERRIDE_ENABLE; + I915_WRITE(BLC_PWM_PCH_CTL1, tmp); } +} - spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); +static void i965_enable_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe = intel_get_pipe_from_connector(connector); + u32 tmp; + + tmp = I915_READ(BLC_PWM_CTL2); + + /* Note that this can also get called through dpms changes. And + * we don't track the backlight dpms state, hence check whether + * we have to do anything first. */ + if (tmp & BLM_PWM_ENABLE) + return; + + tmp &= ~BLM_PIPE_SELECT; + tmp |= BLM_PIPE(pipe); + tmp &= ~BLM_PWM_ENABLE; + + I915_WRITE(BLC_PWM_CTL2, tmp); + POSTING_READ(BLC_PWM_CTL2); + I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE); +} + +static void vlv_enable_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum pipe pipe = intel_get_pipe_from_connector(connector); + u32 tmp; + + tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe)); + + /* Note that this can also get called through dpms changes. And + * we don't track the backlight dpms state, hence check whether + * we have to do anything first. */ + if (tmp & BLM_PWM_ENABLE) + return; + + tmp &= ~BLM_PIPE_SELECT; + tmp |= BLM_PIPE(pipe); + tmp &= ~BLM_PWM_ENABLE; + + I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp); + POSTING_READ(VLV_BLC_PWM_CTL2(pipe)); + I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE); } void intel_panel_enable_backlight(struct intel_connector *connector) @@ -617,8 +799,6 @@ void intel_panel_enable_backlight(struct intel_connector *connector) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); - enum transcoder cpu_transcoder = - intel_pipe_to_cpu_transcoder(dev_priv, pipe); unsigned long flags; if (pipe == INVALID_PIPE) @@ -629,89 +809,25 @@ void intel_panel_enable_backlight(struct intel_connector *connector) spin_lock_irqsave(&dev_priv->backlight_lock, flags); if (panel->backlight.level == 0) { - panel->backlight.level = intel_panel_get_max_backlight(dev, - pipe); + panel->backlight.level = intel_panel_get_max_backlight(connector); if (panel->backlight.device) panel->backlight.device->props.brightness = panel->backlight.level; } - if (INTEL_INFO(dev)->gen >= 4) { - uint32_t reg, tmp; - - if (HAS_PCH_SPLIT(dev)) - reg = BLC_PWM_CPU_CTL2; - else if (IS_VALLEYVIEW(dev)) - reg = VLV_BLC_PWM_CTL2(pipe); - else - reg = BLC_PWM_CTL2; - - tmp = I915_READ(reg); - - /* Note that this can also get called through dpms changes. And - * we don't track the backlight dpms state, hence check whether - * we have to do anything first. */ - if (tmp & BLM_PWM_ENABLE) - goto set_level; - - if (INTEL_INFO(dev)->num_pipes == 3) - tmp &= ~BLM_PIPE_SELECT_IVB; - else - tmp &= ~BLM_PIPE_SELECT; - - if (cpu_transcoder == TRANSCODER_EDP) - tmp |= BLM_TRANSCODER_EDP; - else - tmp |= BLM_PIPE(cpu_transcoder); - tmp &= ~BLM_PWM_ENABLE; - - I915_WRITE(reg, tmp); - POSTING_READ(reg); - I915_WRITE(reg, tmp | BLM_PWM_ENABLE); - - if (HAS_PCH_SPLIT(dev) && - !(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) { - tmp = I915_READ(BLC_PWM_PCH_CTL1); - tmp |= BLM_PCH_PWM_ENABLE; - tmp &= ~BLM_PCH_OVERRIDE_ENABLE; - I915_WRITE(BLC_PWM_PCH_CTL1, tmp); - } - } + if (dev_priv->display.enable_backlight) + dev_priv->display.enable_backlight(connector); -set_level: /* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1. * BLC_PWM_CPU_CTL may be cleared to zero automatically when these * registers are set. */ panel->backlight.enabled = true; - intel_panel_actually_set_backlight(dev, pipe, - panel->backlight.level); + intel_panel_actually_set_backlight(connector, panel->backlight.level); spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); } -/* FIXME: use VBT vals to init PWM_CTL and PWM_CTL2 correctly */ -static void intel_panel_init_backlight_regs(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (IS_VALLEYVIEW(dev)) { - enum pipe pipe; - - for_each_pipe(pipe) { - u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe)); - - /* Skip if the modulation freq is already set */ - if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK) - continue; - - cur_val &= BACKLIGHT_DUTY_CYCLE_MASK; - I915_WRITE(VLV_BLC_PWM_CTL(pipe), (0xf42 << 16) | - cur_val); - } - } -} - enum drm_connector_status intel_panel_detect(struct drm_device *dev) { @@ -753,15 +869,13 @@ static int intel_backlight_device_get_brightness(struct backlight_device *bd) { struct intel_connector *connector = bl_get_data(bd); struct drm_device *dev = connector->base.dev; - enum pipe pipe; + int ret; mutex_lock(&dev->mode_config.mutex); - pipe = intel_get_pipe_from_connector(connector); + ret = intel_panel_get_backlight(connector); mutex_unlock(&dev->mode_config.mutex); - if (pipe == INVALID_PIPE) - return 0; - return intel_panel_get_backlight(connector->base.dev, pipe); + return ret; } static const struct backlight_ops intel_backlight_device_ops = { @@ -771,27 +885,18 @@ static const struct backlight_ops intel_backlight_device_ops = { static int intel_backlight_device_register(struct intel_connector *connector) { - struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; struct backlight_properties props; - unsigned long flags; if (WARN_ON(panel->backlight.device)) return -ENODEV; + BUG_ON(panel->backlight.max == 0); + memset(&props, 0, sizeof(props)); props.type = BACKLIGHT_RAW; props.brightness = panel->backlight.level; - - spin_lock_irqsave(&dev_priv->backlight_lock, flags); - props.max_brightness = intel_panel_get_max_backlight(dev, 0); - spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); - - if (props.max_brightness == 0) { - DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n"); - return -ENODEV; - } + props.max_brightness = panel->backlight.max; /* * Note: using the same name independent of the connector prevents @@ -831,15 +936,102 @@ static void intel_backlight_device_unregister(struct intel_connector *connector) } #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ +/* Note: The setup hooks can't assume pipe is set! */ +static int pch_setup_backlight(struct intel_connector *connector) +{ + struct intel_panel *panel = &connector->panel; + u32 val; + + panel->backlight.max = pch_get_max_backlight(connector); + if (!panel->backlight.max) + return -ENODEV; + + val = pch_get_backlight(connector); + panel->backlight.level = intel_panel_compute_brightness(connector, val); + + return 0; +} + +static int i9xx_setup_backlight(struct intel_connector *connector) +{ + struct intel_panel *panel = &connector->panel; + u32 val; + + panel->backlight.max = i9xx_get_max_backlight(connector); + if (!panel->backlight.max) + return -ENODEV; + + val = i9xx_get_backlight(connector); + panel->backlight.level = intel_panel_compute_brightness(connector, val); + + return 0; +} + +static int i965_setup_backlight(struct intel_connector *connector) +{ + struct intel_panel *panel = &connector->panel; + u32 val; + + panel->backlight.max = i965_get_max_backlight(connector); + if (!panel->backlight.max) + return -ENODEV; + + val = i9xx_get_backlight(connector); + panel->backlight.level = intel_panel_compute_brightness(connector, val); + + return 0; +} + +static int vlv_setup_backlight(struct intel_connector *connector) +{ + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_panel *panel = &connector->panel; + enum pipe pipe; + u32 val; + + for_each_pipe(pipe) { + u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe)); + + /* Skip if the modulation freq is already set */ + if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK) + continue; + + cur_val &= BACKLIGHT_DUTY_CYCLE_MASK; + I915_WRITE(VLV_BLC_PWM_CTL(pipe), (0xf42 << 16) | + cur_val); + } + + panel->backlight.max = _vlv_get_max_backlight(dev, PIPE_A); + if (!panel->backlight.max) + return -ENODEV; + + val = _vlv_get_backlight(dev, PIPE_A); + panel->backlight.level = intel_panel_compute_brightness(connector, val); + + return 0; +} + int intel_panel_setup_backlight(struct drm_connector *connector) { struct drm_device *dev = connector->dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_panel *panel = &intel_connector->panel; + unsigned long flags; + int ret; - intel_panel_init_backlight_regs(dev); + /* set level and max in panel struct */ + spin_lock_irqsave(&dev_priv->backlight_lock, flags); + ret = dev_priv->display.setup_backlight(intel_connector); + spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); + + if (ret) { + DRM_DEBUG_KMS("failed to setup backlight for connector %s\n", + drm_get_connector_name(connector)); + return ret; + } - panel->backlight.level = intel_panel_get_backlight(dev, 0); panel->backlight.enabled = panel->backlight.level != 0; intel_backlight_device_register(intel_connector); @@ -858,6 +1050,40 @@ void intel_panel_destroy_backlight(struct drm_connector *connector) intel_backlight_device_unregister(intel_connector); } +/* Set up chip specific backlight functions */ +void intel_panel_init_backlight_funcs(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (HAS_PCH_SPLIT(dev)) { + dev_priv->display.setup_backlight = pch_setup_backlight; + dev_priv->display.enable_backlight = pch_enable_backlight; + dev_priv->display.disable_backlight = pch_disable_backlight; + dev_priv->display.set_backlight = pch_set_backlight; + dev_priv->display.get_backlight = pch_get_backlight; + dev_priv->display.get_max_backlight = pch_get_max_backlight; + } else if (IS_VALLEYVIEW(dev)) { + dev_priv->display.setup_backlight = vlv_setup_backlight; + dev_priv->display.enable_backlight = vlv_enable_backlight; + dev_priv->display.disable_backlight = vlv_disable_backlight; + dev_priv->display.set_backlight = vlv_set_backlight; + dev_priv->display.get_backlight = vlv_get_backlight; + dev_priv->display.get_max_backlight = vlv_get_max_backlight; + } else if (IS_GEN4(dev)) { + dev_priv->display.setup_backlight = i965_setup_backlight; + dev_priv->display.enable_backlight = i965_enable_backlight; + dev_priv->display.disable_backlight = i965_disable_backlight; + dev_priv->display.set_backlight = i9xx_set_backlight; + dev_priv->display.get_backlight = i9xx_get_backlight; + dev_priv->display.get_max_backlight = i965_get_max_backlight; + } else { + dev_priv->display.setup_backlight = i9xx_setup_backlight; + dev_priv->display.set_backlight = i9xx_set_backlight; + dev_priv->display.get_backlight = i9xx_get_backlight; + dev_priv->display.get_max_backlight = i9xx_get_max_backlight; + } +} + int intel_panel_init(struct intel_panel *panel, struct drm_display_mode *fixed_mode) { -- cgit v1.2.3 From b329b32854eca71853ce1e3e06b573c25b262d5f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Nov 2013 16:48:57 +0200 Subject: drm/i915: fix gen2-gen3 backlight set Citing Jani's response to Imre's question in the review discussion: > According to the gen2/3 bspec I have, the correct mask is > BACKLIGHT_DUTY_CYCLE_MASK_PNV only in case of IS_PINEVIEW(dev), for > everything else it's BACKLIGHT_DUTY_CYCLE_MASK. What you say is correct, but we've treated all gen2/3 similar to PNV since commit ca88479c1c3b7b1a9f94320745f5331e1de77f80 Author: Keith Packard Date: Fri Nov 18 11:09:24 2011 -0800 drm/i915: Treat pre-gen4 backlight duty cycle value consistently i.e. we only use the high 15 bits for all gen2/3. For non-PNV this just means the lowest bit is always zero. For PNV the lowest bit has a different meaning in both the PWM freq and duty cycle fields. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak [danvet: Make the commit message less empty.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index a821949a9c7a..e82b2dd93eef 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -555,7 +555,7 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - u32 tmp; + u32 tmp, mask; if (is_backlight_combination_mode(dev)) { u32 max = intel_panel_get_max_backlight(connector); @@ -570,10 +570,14 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level) pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc); } - if (INTEL_INFO(dev)->gen < 4) + if (IS_GEN4(dev)) { + mask = BACKLIGHT_DUTY_CYCLE_MASK; + } else { level <<= 1; + mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV; + } - tmp = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; + tmp = I915_READ(BLC_PWM_CTL) & ~mask; I915_WRITE(BLC_PWM_CTL, tmp | level); } -- cgit v1.2.3 From ab51c86a88ba09ec657b1e02aa7824938afb7bd3 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Nov 2013 16:48:58 +0200 Subject: drm/i915: vlv does not have pipe field in backlight registers It has per pipe registers. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index e82b2dd93eef..5bd64db9a9bf 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -788,8 +788,6 @@ static void vlv_enable_backlight(struct intel_connector *connector) if (tmp & BLM_PWM_ENABLE) return; - tmp &= ~BLM_PIPE_SELECT; - tmp |= BLM_PIPE(pipe); tmp &= ~BLM_PWM_ENABLE; I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp); -- cgit v1.2.3 From 3bd712e545996658f4bc6c61ff99d7bae2a8cfcf Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Nov 2013 16:48:59 +0200 Subject: drm/i915: move backlight level setting in enable/disable to hooks This allows more flexibility in the ordering of the register writes, and lets us drop level setting altogether as necessary on a per platform basis. For gen2-gen3, this is the only thing that happens in enable/disable. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 48 ++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 5bd64db9a9bf..ed6b1eccb7dd 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -648,6 +648,8 @@ static void pch_disable_backlight(struct intel_connector *connector) struct drm_i915_private *dev_priv = dev->dev_private; u32 tmp; + intel_panel_actually_set_backlight(connector, 0); + tmp = I915_READ(BLC_PWM_CPU_CTL2); I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE); @@ -655,12 +657,19 @@ static void pch_disable_backlight(struct intel_connector *connector) I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE); } +static void i9xx_disable_backlight(struct intel_connector *connector) +{ + intel_panel_actually_set_backlight(connector, 0); +} + static void i965_disable_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; u32 tmp; + intel_panel_actually_set_backlight(connector, 0); + tmp = I915_READ(BLC_PWM_CTL2); I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE); } @@ -672,6 +681,8 @@ static void vlv_disable_backlight(struct intel_connector *connector) enum pipe pipe = intel_get_pipe_from_connector(connector); u32 tmp; + intel_panel_actually_set_backlight(connector, 0); + tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe)); I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE); } @@ -701,10 +712,7 @@ void intel_panel_disable_backlight(struct intel_connector *connector) spin_lock_irqsave(&dev_priv->backlight_lock, flags); panel->backlight.enabled = false; - intel_panel_actually_set_backlight(connector, 0); - - if (dev_priv->display.disable_backlight) - dev_priv->display.disable_backlight(connector); + dev_priv->display.disable_backlight(connector); spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); } @@ -713,6 +721,7 @@ static void pch_enable_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, pipe); @@ -747,12 +756,27 @@ static void pch_enable_backlight(struct intel_connector *connector) tmp &= ~BLM_PCH_OVERRIDE_ENABLE; I915_WRITE(BLC_PWM_PCH_CTL1, tmp); } + + /* + * Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1. + * BLC_PWM_CPU_CTL may be cleared to zero automatically when these + * registers are set. + */ + intel_panel_actually_set_backlight(connector, panel->backlight.level); +} + +static void i9xx_enable_backlight(struct intel_connector *connector) +{ + struct intel_panel *panel = &connector->panel; + + intel_panel_actually_set_backlight(connector, panel->backlight.level); } static void i965_enable_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); u32 tmp; @@ -771,12 +795,15 @@ static void i965_enable_backlight(struct intel_connector *connector) I915_WRITE(BLC_PWM_CTL2, tmp); POSTING_READ(BLC_PWM_CTL2); I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE); + + intel_panel_actually_set_backlight(connector, panel->backlight.level); } static void vlv_enable_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); u32 tmp; @@ -793,6 +820,8 @@ static void vlv_enable_backlight(struct intel_connector *connector) I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp); POSTING_READ(VLV_BLC_PWM_CTL2(pipe)); I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE); + + intel_panel_actually_set_backlight(connector, panel->backlight.level); } void intel_panel_enable_backlight(struct intel_connector *connector) @@ -817,15 +846,8 @@ void intel_panel_enable_backlight(struct intel_connector *connector) panel->backlight.level; } - if (dev_priv->display.enable_backlight) - dev_priv->display.enable_backlight(connector); - - /* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1. - * BLC_PWM_CPU_CTL may be cleared to zero automatically when these - * registers are set. - */ + dev_priv->display.enable_backlight(connector); panel->backlight.enabled = true; - intel_panel_actually_set_backlight(connector, panel->backlight.level); spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); } @@ -1080,6 +1102,8 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev) dev_priv->display.get_max_backlight = i965_get_max_backlight; } else { dev_priv->display.setup_backlight = i9xx_setup_backlight; + dev_priv->display.enable_backlight = i9xx_enable_backlight; + dev_priv->display.disable_backlight = i9xx_disable_backlight; dev_priv->display.set_backlight = i9xx_set_backlight; dev_priv->display.get_backlight = i9xx_get_backlight; dev_priv->display.get_max_backlight = i9xx_get_max_backlight; -- cgit v1.2.3 From f91c15e0808e612abacdb0fbca557b23fe2aa4d1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Nov 2013 16:49:00 +0200 Subject: drm/i915: use the initialized backlight max value instead of reading it We now have the max backlight value cached. Use it. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 45 ++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index ed6b1eccb7dd..9a55b36370b3 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -436,9 +436,6 @@ static u32 vlv_get_max_backlight(struct intel_connector *connector) return _vlv_get_max_backlight(dev, pipe); } -/* XXX: query mode clock or hardware clock and program max PWM appropriately - * when it's 0. - */ static u32 intel_panel_get_max_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; @@ -466,15 +463,16 @@ static u32 intel_panel_compute_brightness(struct intel_connector *connector, { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_panel *panel = &connector->panel; + + WARN_ON(panel->backlight.max == 0); if (i915_panel_invert_brightness < 0) return val; if (i915_panel_invert_brightness > 0 || dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { - u32 max = intel_panel_get_max_backlight(connector); - if (max) - return max - val; + return panel->backlight.max - val; } return val; @@ -555,17 +553,15 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_panel *panel = &connector->panel; u32 tmp, mask; + WARN_ON(panel->backlight.max == 0); + if (is_backlight_combination_mode(dev)) { - u32 max = intel_panel_get_max_backlight(connector); u8 lbpc; - /* we're screwed, but keep behaviour backwards compatible */ - if (!max) - max = 1; - - lbpc = level * 0xfe / max + 1; + lbpc = level * 0xfe / panel->backlight.max + 1; level /= lbpc; pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc); } @@ -620,13 +616,10 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level, spin_lock_irqsave(&dev_priv->backlight_lock, flags); - freq = intel_panel_get_max_backlight(connector); - if (!freq) { - /* we are screwed, bail out */ - goto out; - } + WARN_ON(panel->backlight.max == 0); - /* scale to hardware, but be careful to not overflow */ + /* scale to hardware max, but be careful to not overflow */ + freq = panel->backlight.max; if (freq < max) level = level * freq / max; else @@ -638,7 +631,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level, if (panel->backlight.enabled) intel_panel_actually_set_backlight(connector, level); -out: + spin_unlock_irqrestore(&dev_priv->backlight_lock, flags); } @@ -839,8 +832,13 @@ void intel_panel_enable_backlight(struct intel_connector *connector) spin_lock_irqsave(&dev_priv->backlight_lock, flags); + /* XXX: transitional, call to make sure freq is set */ + intel_panel_get_max_backlight(connector); + + WARN_ON(panel->backlight.max == 0); + if (panel->backlight.level == 0) { - panel->backlight.level = intel_panel_get_max_backlight(connector); + panel->backlight.level = panel->backlight.max; if (panel->backlight.device) panel->backlight.device->props.brightness = panel->backlight.level; @@ -960,7 +958,12 @@ static void intel_backlight_device_unregister(struct intel_connector *connector) } #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ -/* Note: The setup hooks can't assume pipe is set! */ +/* + * Note: The setup hooks can't assume pipe is set! + * + * XXX: Query mode clock or hardware clock and program PWM modulation frequency + * appropriately when it's 0. Use VBT and/or sane defaults. + */ static int pch_setup_backlight(struct intel_connector *connector) { struct intel_panel *panel = &connector->panel; -- cgit v1.2.3 From c445b3b1e02a40666b7e4bea58bce0c4723eba4f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Nov 2013 16:49:01 +0200 Subject: drm/i915: debug print on backlight register Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 9a55b36370b3..3dd9f57da69c 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1065,6 +1065,12 @@ int intel_panel_setup_backlight(struct drm_connector *connector) panel->backlight.present = true; + DRM_DEBUG_KMS("backlight initialized, %s, brightness %u/%u, " + "sysfs interface %sregistered\n", + panel->backlight.enabled ? "enabled" : "disabled", + panel->backlight.level, panel->backlight.max, + panel->backlight.device ? "" : "not "); + return 0; } -- cgit v1.2.3 From 636baebfa62fa31b204bc5a816700bd2fd135e57 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Nov 2013 16:49:02 +0200 Subject: drm/i915: gather backlight information at setup Prepare for being able to use the information at enable. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 68 +++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 3dd9f57da69c..0e8f0a3d3bf6 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -490,13 +490,14 @@ static u32 i9xx_get_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_panel *panel = &connector->panel; u32 val; val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; if (INTEL_INFO(dev)->gen < 4) val >>= 1; - if (is_backlight_combination_mode(dev)) { + if (panel->backlight.combination_mode) { u8 lbpc; pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc); @@ -558,7 +559,7 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level) WARN_ON(panel->backlight.max == 0); - if (is_backlight_combination_mode(dev)) { + if (panel->backlight.combination_mode) { u8 lbpc; lbpc = level * 0xfe / panel->backlight.max + 1; @@ -966,46 +967,84 @@ static void intel_backlight_device_unregister(struct intel_connector *connector) */ static int pch_setup_backlight(struct intel_connector *connector) { + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; - u32 val; + u32 cpu_ctl2, pch_ctl1, pch_ctl2, val; - panel->backlight.max = pch_get_max_backlight(connector); + pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); + panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY; + + pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2); + panel->backlight.max = pch_ctl2 >> 16; if (!panel->backlight.max) return -ENODEV; val = pch_get_backlight(connector); panel->backlight.level = intel_panel_compute_brightness(connector, val); + cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2); + panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) && + (pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0; + return 0; } static int i9xx_setup_backlight(struct intel_connector *connector) { + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; - u32 val; + u32 ctl, val; + + ctl = I915_READ(BLC_PWM_CTL); + + if (IS_GEN2(dev)) + panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE; + + if (IS_PINEVIEW(dev)) + panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV; + + panel->backlight.max = ctl >> 17; + if (panel->backlight.combination_mode) + panel->backlight.max *= 0xff; - panel->backlight.max = i9xx_get_max_backlight(connector); if (!panel->backlight.max) return -ENODEV; val = i9xx_get_backlight(connector); panel->backlight.level = intel_panel_compute_brightness(connector, val); + panel->backlight.enabled = panel->backlight.level != 0; + return 0; } static int i965_setup_backlight(struct intel_connector *connector) { + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; - u32 val; + u32 ctl, ctl2, val; + + ctl2 = I915_READ(BLC_PWM_CTL2); + panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE; + panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; + + ctl = I915_READ(BLC_PWM_CTL); + panel->backlight.max = ctl >> 16; + if (panel->backlight.combination_mode) + panel->backlight.max *= 0xff; - panel->backlight.max = i965_get_max_backlight(connector); if (!panel->backlight.max) return -ENODEV; val = i9xx_get_backlight(connector); panel->backlight.level = intel_panel_compute_brightness(connector, val); + panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) && + panel->backlight.level != 0; + return 0; } @@ -1015,7 +1054,7 @@ static int vlv_setup_backlight(struct intel_connector *connector) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; enum pipe pipe; - u32 val; + u32 ctl, ctl2, val; for_each_pipe(pipe) { u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe)); @@ -1029,13 +1068,20 @@ static int vlv_setup_backlight(struct intel_connector *connector) cur_val); } - panel->backlight.max = _vlv_get_max_backlight(dev, PIPE_A); + ctl2 = I915_READ(VLV_BLC_PWM_CTL2(PIPE_A)); + panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965; + + ctl = I915_READ(VLV_BLC_PWM_CTL(PIPE_A)); + panel->backlight.max = ctl >> 16; if (!panel->backlight.max) return -ENODEV; val = _vlv_get_backlight(dev, PIPE_A); panel->backlight.level = intel_panel_compute_brightness(connector, val); + panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) && + panel->backlight.level != 0; + return 0; } @@ -1059,8 +1105,6 @@ int intel_panel_setup_backlight(struct drm_connector *connector) return ret; } - panel->backlight.enabled = panel->backlight.level != 0; - intel_backlight_device_register(intel_connector); panel->backlight.present = true; -- cgit v1.2.3 From b35684b8fa94e04f55fd38bf672b737741d2f9e2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 14 Nov 2013 12:13:41 +0200 Subject: drm/i915: do full backlight setup at enable time We should now have all the information we need to do a full initialization of the backlight registers. v2: Keep QUIRK_NO_PCH_PWM_ENABLE for now (Imre). Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 149 +++++++++++++++++++++++-------------- 1 file changed, 93 insertions(+), 56 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 0e8f0a3d3bf6..0986472d4254 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -719,50 +719,75 @@ static void pch_enable_backlight(struct intel_connector *connector) enum pipe pipe = intel_get_pipe_from_connector(connector); enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, pipe); - u32 tmp; - - tmp = I915_READ(BLC_PWM_CPU_CTL2); + u32 cpu_ctl2, pch_ctl1, pch_ctl2; - /* Note that this can also get called through dpms changes. And - * we don't track the backlight dpms state, hence check whether - * we have to do anything first. */ - if (tmp & BLM_PWM_ENABLE) - return; + cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2); + if (cpu_ctl2 & BLM_PWM_ENABLE) { + WARN(1, "cpu backlight already enabled\n"); + cpu_ctl2 &= ~BLM_PWM_ENABLE; + I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2); + } - if (INTEL_INFO(dev)->num_pipes == 3) - tmp &= ~BLM_PIPE_SELECT_IVB; - else - tmp &= ~BLM_PIPE_SELECT; + pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1); + if (pch_ctl1 & BLM_PCH_PWM_ENABLE) { + DRM_DEBUG_KMS("pch backlight already enabled\n"); + pch_ctl1 &= ~BLM_PCH_PWM_ENABLE; + I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); + } if (cpu_transcoder == TRANSCODER_EDP) - tmp |= BLM_TRANSCODER_EDP; + cpu_ctl2 = BLM_TRANSCODER_EDP; else - tmp |= BLM_PIPE(cpu_transcoder); - tmp &= ~BLM_PWM_ENABLE; - - I915_WRITE(BLC_PWM_CPU_CTL2, tmp); + cpu_ctl2 = BLM_PIPE(cpu_transcoder); + I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2); POSTING_READ(BLC_PWM_CPU_CTL2); - I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE); - - if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) { - tmp = I915_READ(BLC_PWM_PCH_CTL1); - tmp |= BLM_PCH_PWM_ENABLE; - tmp &= ~BLM_PCH_OVERRIDE_ENABLE; - I915_WRITE(BLC_PWM_PCH_CTL1, tmp); - } + I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE); - /* - * Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1. - * BLC_PWM_CPU_CTL may be cleared to zero automatically when these - * registers are set. - */ + /* This won't stick until the above enable. */ intel_panel_actually_set_backlight(connector, panel->backlight.level); + + pch_ctl2 = panel->backlight.max << 16; + I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2); + + /* XXX: transitional */ + if (dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE) + return; + + pch_ctl1 = 0; + if (panel->backlight.active_low_pwm) + pch_ctl1 |= BLM_PCH_POLARITY; + I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1); + POSTING_READ(BLC_PWM_PCH_CTL1); + I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE); } static void i9xx_enable_backlight(struct intel_connector *connector) { + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; + u32 ctl, freq; + + ctl = I915_READ(BLC_PWM_CTL); + if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) { + WARN(1, "backlight already enabled\n"); + I915_WRITE(BLC_PWM_CTL, 0); + } + freq = panel->backlight.max; + if (panel->backlight.combination_mode) + freq /= 0xff; + + ctl = freq << 17; + if (IS_GEN2(dev) && panel->backlight.combination_mode) + ctl |= BLM_LEGACY_MODE; + if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm) + ctl |= BLM_POLARITY_PNV; + + I915_WRITE(BLC_PWM_CTL, ctl); + POSTING_READ(BLC_PWM_CTL); + + /* XXX: combine this into above write? */ intel_panel_actually_set_backlight(connector, panel->backlight.level); } @@ -772,25 +797,33 @@ static void i965_enable_backlight(struct intel_connector *connector) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); - u32 tmp; + u32 ctl, ctl2, freq; - tmp = I915_READ(BLC_PWM_CTL2); + ctl2 = I915_READ(BLC_PWM_CTL2); + if (ctl2 & BLM_PWM_ENABLE) { + WARN(1, "backlight already enabled\n"); + ctl2 &= ~BLM_PWM_ENABLE; + I915_WRITE(BLC_PWM_CTL2, ctl2); + } - /* Note that this can also get called through dpms changes. And - * we don't track the backlight dpms state, hence check whether - * we have to do anything first. */ - if (tmp & BLM_PWM_ENABLE) - return; + freq = panel->backlight.max; + if (panel->backlight.combination_mode) + freq /= 0xff; - tmp &= ~BLM_PIPE_SELECT; - tmp |= BLM_PIPE(pipe); - tmp &= ~BLM_PWM_ENABLE; - - I915_WRITE(BLC_PWM_CTL2, tmp); - POSTING_READ(BLC_PWM_CTL2); - I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE); + ctl = freq << 16; + I915_WRITE(BLC_PWM_CTL, ctl); + /* XXX: combine this into above write? */ intel_panel_actually_set_backlight(connector, panel->backlight.level); + + ctl2 = BLM_PIPE(pipe); + if (panel->backlight.combination_mode) + ctl2 |= BLM_COMBINATION_MODE; + if (panel->backlight.active_low_pwm) + ctl2 |= BLM_POLARITY_I965; + I915_WRITE(BLC_PWM_CTL2, ctl2); + POSTING_READ(BLC_PWM_CTL2); + I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE); } static void vlv_enable_backlight(struct intel_connector *connector) @@ -799,23 +832,27 @@ static void vlv_enable_backlight(struct intel_connector *connector) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_panel *panel = &connector->panel; enum pipe pipe = intel_get_pipe_from_connector(connector); - u32 tmp; + u32 ctl, ctl2; - tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe)); + ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe)); + if (ctl2 & BLM_PWM_ENABLE) { + WARN(1, "backlight already enabled\n"); + ctl2 &= ~BLM_PWM_ENABLE; + I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2); + } - /* Note that this can also get called through dpms changes. And - * we don't track the backlight dpms state, hence check whether - * we have to do anything first. */ - if (tmp & BLM_PWM_ENABLE) - return; + ctl = panel->backlight.max << 16; + I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl); - tmp &= ~BLM_PWM_ENABLE; + /* XXX: combine this into above write? */ + intel_panel_actually_set_backlight(connector, panel->backlight.level); - I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp); + ctl2 = 0; + if (panel->backlight.active_low_pwm) + ctl2 |= BLM_POLARITY_I965; + I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2); POSTING_READ(VLV_BLC_PWM_CTL2(pipe)); - I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE); - - intel_panel_actually_set_backlight(connector, panel->backlight.level); + I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE); } void intel_panel_enable_backlight(struct intel_connector *connector) -- cgit v1.2.3 From bc0bb9fd1c7810407ab810d204bbaecb255fddde Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 14 Nov 2013 12:14:29 +0200 Subject: drm/i915: remove QUIRK_NO_PCH_PWM_ENABLE The quirk was added as what I'd say was a stopgap measure in commit e85843bec6c2ea7c10ec61238396891cc2b753a9 Author: Kamal Mostafa Date: Fri Jul 19 15:02:01 2013 -0700 drm/i915: quirk no PCH_PWM_ENABLE for Dell XPS13 backlight without really digging into what was going on. Also, as mentioned in the related bug [1], having the quirk regressed some of the machines it was supposed to fix to begin with, and there were patches posted to disable the quirk on such machines [2]! The fact is, we do need the BLM_PCH_PWM_ENABLE bit set to have backlight. With the quirk, we've relied on BIOS to have set it, and our save/restore code to retain it. With the full backlight setup at enable, we have no place for things that rely on previous state. With the per platform hooks, we've also made a change in the PCH platform enable order: setting the backlight duty cycle between CPU and PCH PWM enable. Some experimenting and commit 770c12312ad617172b1a65b911d3e6564fc5aca8 Author: Takashi Iwai Date: Sat Aug 11 08:56:42 2012 +0200 drm/i915: Fix blank panel at reopening lid indicate that we can't set the backlight before enabling CPU PWM; the value just won't stick. But AFAICT we should do it before enabling the PCH PWM. Finally, any fallout we should fix properly, preferrably without quirks, and absolutely without quirks that rely on existing state. With the per platform hooks have much more flexibility to adjust the sequence as required by platforms. [1] https://bugzilla.kernel.org/show_bug.cgi?id=47941 [2] http://lkml.kernel.org/r/1378229848-29113-1-git-send-email-kamal@canonical.com Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 0986472d4254..da088e33dd19 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -749,10 +749,6 @@ static void pch_enable_backlight(struct intel_connector *connector) pch_ctl2 = panel->backlight.max << 16; I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2); - /* XXX: transitional */ - if (dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE) - return; - pch_ctl1 = 0; if (panel->backlight.active_low_pwm) pch_ctl1 |= BLM_PCH_POLARITY; -- cgit v1.2.3 From 58cad0768ca204599561bdb5509fb4ffc92603cb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 8 Nov 2013 16:49:04 +0200 Subject: drm/i915: nuke get max backlight functions No longer needed. We now have fully cached max backlight values. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 133 ------------------------------------- 1 file changed, 133 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index da088e33dd19..eadfe338dbeb 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -325,132 +325,6 @@ out: pipe_config->gmch_pfit.lvds_border_bits = border; } -static int is_backlight_combination_mode(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (IS_GEN4(dev)) - return I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE; - - if (IS_GEN2(dev)) - return I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE; - - return 0; -} - -static u32 pch_get_max_backlight(struct intel_connector *connector) -{ - struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 val; - - val = I915_READ(BLC_PWM_PCH_CTL2); - if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) { - dev_priv->regfile.saveBLC_PWM_CTL2 = val; - } else if (val == 0) { - val = dev_priv->regfile.saveBLC_PWM_CTL2; - I915_WRITE(BLC_PWM_PCH_CTL2, val); - } - - val >>= 16; - - return val; -} - -static u32 i9xx_get_max_backlight(struct intel_connector *connector) -{ - struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 val; - - val = I915_READ(BLC_PWM_CTL); - if (dev_priv->regfile.saveBLC_PWM_CTL == 0) { - dev_priv->regfile.saveBLC_PWM_CTL = val; - } else if (val == 0) { - val = dev_priv->regfile.saveBLC_PWM_CTL; - I915_WRITE(BLC_PWM_CTL, val); - } - - val >>= 17; - - if (is_backlight_combination_mode(dev)) - val *= 0xff; - - return val; -} - -static u32 i965_get_max_backlight(struct intel_connector *connector) -{ - struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 val; - - val = I915_READ(BLC_PWM_CTL); - if (dev_priv->regfile.saveBLC_PWM_CTL == 0) { - dev_priv->regfile.saveBLC_PWM_CTL = val; - dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); - } else if (val == 0) { - val = dev_priv->regfile.saveBLC_PWM_CTL; - I915_WRITE(BLC_PWM_CTL, val); - I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2); - } - - val >>= 16; - - if (is_backlight_combination_mode(dev)) - val *= 0xff; - - return val; -} - -static u32 _vlv_get_max_backlight(struct drm_device *dev, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 val; - - val = I915_READ(VLV_BLC_PWM_CTL(pipe)); - if (dev_priv->regfile.saveBLC_PWM_CTL == 0) { - dev_priv->regfile.saveBLC_PWM_CTL = val; - dev_priv->regfile.saveBLC_PWM_CTL2 = - I915_READ(VLV_BLC_PWM_CTL2(pipe)); - } else if (val == 0) { - val = dev_priv->regfile.saveBLC_PWM_CTL; - I915_WRITE(VLV_BLC_PWM_CTL(pipe), val); - I915_WRITE(VLV_BLC_PWM_CTL2(pipe), - dev_priv->regfile.saveBLC_PWM_CTL2); - } - - if (!val) - val = 0x0f42ffff; - - val >>= 16; - - return val; -} - -static u32 vlv_get_max_backlight(struct intel_connector *connector) -{ - struct drm_device *dev = connector->base.dev; - enum pipe pipe = intel_get_pipe_from_connector(connector); - - return _vlv_get_max_backlight(dev, pipe); -} - -static u32 intel_panel_get_max_backlight(struct intel_connector *connector) -{ - struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 max; - - WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock)); - - max = dev_priv->display.get_max_backlight(connector); - - DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); - - return max; -} - static int i915_panel_invert_brightness; MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness " "(-1 force normal, 0 machine defaults, 1 force inversion), please " @@ -866,9 +740,6 @@ void intel_panel_enable_backlight(struct intel_connector *connector) spin_lock_irqsave(&dev_priv->backlight_lock, flags); - /* XXX: transitional, call to make sure freq is set */ - intel_panel_get_max_backlight(connector); - WARN_ON(panel->backlight.max == 0); if (panel->backlight.level == 0) { @@ -1171,28 +1042,24 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev) dev_priv->display.disable_backlight = pch_disable_backlight; dev_priv->display.set_backlight = pch_set_backlight; dev_priv->display.get_backlight = pch_get_backlight; - dev_priv->display.get_max_backlight = pch_get_max_backlight; } else if (IS_VALLEYVIEW(dev)) { dev_priv->display.setup_backlight = vlv_setup_backlight; dev_priv->display.enable_backlight = vlv_enable_backlight; dev_priv->display.disable_backlight = vlv_disable_backlight; dev_priv->display.set_backlight = vlv_set_backlight; dev_priv->display.get_backlight = vlv_get_backlight; - dev_priv->display.get_max_backlight = vlv_get_max_backlight; } else if (IS_GEN4(dev)) { dev_priv->display.setup_backlight = i965_setup_backlight; dev_priv->display.enable_backlight = i965_enable_backlight; dev_priv->display.disable_backlight = i965_disable_backlight; dev_priv->display.set_backlight = i9xx_set_backlight; dev_priv->display.get_backlight = i9xx_get_backlight; - dev_priv->display.get_max_backlight = i965_get_max_backlight; } else { dev_priv->display.setup_backlight = i9xx_setup_backlight; dev_priv->display.enable_backlight = i9xx_enable_backlight; dev_priv->display.disable_backlight = i9xx_disable_backlight; dev_priv->display.set_backlight = i9xx_set_backlight; dev_priv->display.get_backlight = i9xx_get_backlight; - dev_priv->display.get_max_backlight = i9xx_get_max_backlight; } } -- cgit v1.2.3 From ec9ed1976c256333567932b4acced34c072b57a7 Mon Sep 17 00:00:00 2001 From: Vandana Kannan Date: Tue, 10 Dec 2013 13:37:36 +0530 Subject: drm/i915: Make downclock deduction common for all panels If one mode of a internal panel has more than one refresh rate, then a reduced clock is found for the LFP (LVDS/eDP). This enables switching between low and high frequency dynamically. Moving downclock calculation to intel_panel so that it is common for LVDS and eDP. Signed-off-by: Vandana Kannan Signed-off-by: Pradeep Bhat Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 57 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index e480cf41c536..b0f6e6cc4354 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1104,6 +1104,59 @@ void intel_panel_destroy_backlight(struct drm_connector *connector) intel_backlight_device_unregister(intel_connector); } +/** + * intel_find_panel_downclock - find the reduced downclock for LVDS in EDID + * @dev: drm device + * @fixed_mode : panel native mode + * @connector: LVDS/eDP connector + * + * Return downclock_avail + * Find the reduced downclock for LVDS/eDP in EDID. + */ +struct drm_display_mode * +intel_find_panel_downclock(struct drm_device *dev, + struct drm_display_mode *fixed_mode, + struct drm_connector *connector) +{ + struct drm_display_mode *scan, *tmp_mode; + int temp_downclock; + + temp_downclock = fixed_mode->clock; + tmp_mode = NULL; + + list_for_each_entry(scan, &connector->probed_modes, head) { + /* + * If one mode has the same resolution with the fixed_panel + * mode while they have the different refresh rate, it means + * that the reduced downclock is found. In such + * case we can set the different FPx0/1 to dynamically select + * between low and high frequency. + */ + if (scan->hdisplay == fixed_mode->hdisplay && + scan->hsync_start == fixed_mode->hsync_start && + scan->hsync_end == fixed_mode->hsync_end && + scan->htotal == fixed_mode->htotal && + scan->vdisplay == fixed_mode->vdisplay && + scan->vsync_start == fixed_mode->vsync_start && + scan->vsync_end == fixed_mode->vsync_end && + scan->vtotal == fixed_mode->vtotal) { + if (scan->clock < temp_downclock) { + /* + * The downclock is already found. But we + * expect to find the lower downclock. + */ + temp_downclock = scan->clock; + tmp_mode = scan; + } + } + } + + if (temp_downclock < fixed_mode->clock) + return drm_mode_duplicate(dev, tmp_mode); + else + return NULL; +} + /* Set up chip specific backlight functions */ void intel_panel_init_backlight_funcs(struct drm_device *dev) { @@ -1157,4 +1210,8 @@ void intel_panel_fini(struct intel_panel *panel) if (panel->fixed_mode) drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode); + + if (panel->downclock_mode) + drm_mode_destroy(intel_connector->base.dev, + panel->downclock_mode); } -- cgit v1.2.3 From c8c8fb33b37766acf6474784b0d5245dab9a1690 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 27 Nov 2013 18:21:54 -0200 Subject: drm/i915: add some runtime PM get/put calls These are needed when we cat the debugfs and sysfs files. V2: - Rebase V3: - Rebase V4: - Rebase Signed-off-by: Paulo Zanoni Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index b0f6e6cc4354..20ebc3e83d39 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -845,11 +845,14 @@ static int intel_backlight_device_get_brightness(struct backlight_device *bd) { struct intel_connector *connector = bl_get_data(bd); struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; int ret; + intel_runtime_pm_get(dev_priv); mutex_lock(&dev->mode_config.mutex); ret = intel_panel_get_backlight(connector); mutex_unlock(&dev->mode_config.mutex); + intel_runtime_pm_put(dev_priv); return ret; } -- cgit v1.2.3 From dc5a43636c2fd50c694f16d042e0639fff5044fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 16 Jan 2014 18:27:15 +0200 Subject: drm/i915: Eliminate lots of WARNs when there's no backlight present MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit My 855gm doesn't register the intel backlight but it still ends up calling the backlight code to enable/disable the backlight via the LVDS code. This leads to some WARNs due to backlight.max being 0. Let's have intel_panel_enable_backlight() and intel_panel_disable_backlight() check whether there's a backlight present or not. Also move the backlight.present check from asle_set_backlight() into intel_panel_set_backlight() for some extra symmetry. Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_panel.c') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 20ebc3e83d39..350de359123a 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -502,7 +502,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level, u32 freq; unsigned long flags; - if (pipe == INVALID_PIPE) + if (!panel->backlight.present || pipe == INVALID_PIPE) return; spin_lock_irqsave(&dev_priv->backlight_lock, flags); @@ -579,7 +579,7 @@ void intel_panel_disable_backlight(struct intel_connector *connector) enum pipe pipe = intel_get_pipe_from_connector(connector); unsigned long flags; - if (pipe == INVALID_PIPE) + if (!panel->backlight.present || pipe == INVALID_PIPE) return; /* @@ -782,7 +782,7 @@ void intel_panel_enable_backlight(struct intel_connector *connector) enum pipe pipe = intel_get_pipe_from_connector(connector); unsigned long flags; - if (pipe == INVALID_PIPE) + if (!panel->backlight.present || pipe == INVALID_PIPE) return; DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); -- cgit v1.2.3