On VLV/BYT, backlight controls a per-pipe, so when adjusting the
backlight we need to pass the correct info.  So make the externally
visible backlight functions take a connector argument, which can be used
internally to figure out the pipe backlight to adjust.

Signed-off-by: Jesse Barnes <jbar...@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c  |  8 +++++
 drivers/gpu/drm/i915/intel_dp.c       |  5 ++-
 drivers/gpu/drm/i915/intel_drv.h      |  8 +++--
 drivers/gpu/drm/i915/intel_lvds.c     |  9 +++--
 drivers/gpu/drm/i915/intel_opregion.c | 28 ++++++++++++++-
 drivers/gpu/drm/i915/intel_panel.c    | 66 +++++++++++++++++++++--------------
 6 files changed, 88 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 9a7136c..d6a1868 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9716,6 +9716,14 @@ static void intel_crtc_init(struct drm_device *dev, int 
pipe)
        drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
 }
 
+enum pipe intel_get_pipe_from_connector(struct intel_connector *connector)
+{
+       struct intel_encoder *encoder = connector->encoder;
+       struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+
+       return crtc->pipe;
+}
+
 int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
                                struct drm_file *file)
 {
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 95a3159..ef69d31 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1252,7 +1252,6 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
        struct drm_device *dev = intel_dig_port->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe;
        u32 pp;
        u32 pp_ctrl_reg;
 
@@ -1275,7 +1274,7 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
        I915_WRITE(pp_ctrl_reg, pp);
        POSTING_READ(pp_ctrl_reg);
 
-       intel_panel_enable_backlight(dev, pipe);
+       intel_panel_enable_backlight(intel_dp->attached_connector);
 }
 
 void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
@@ -1288,7 +1287,7 @@ void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
        if (!is_edp(intel_dp))
                return;
 
-       intel_panel_disable_backlight(dev);
+       intel_panel_disable_backlight(intel_dp->attached_connector);
 
        DRM_DEBUG_KMS("\n");
        pp = ironlake_get_pp_control(intel_dp);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a17a86a..e9b7540 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -619,6 +619,7 @@ void intel_connector_attach_encoder(struct intel_connector 
*connector,
 struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
 struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
                                             struct drm_crtc *crtc);
+enum pipe intel_get_pipe_from_connector(struct intel_connector *connector);
 int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
 enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
@@ -767,10 +768,11 @@ void intel_pch_panel_fitting(struct intel_crtc *crtc,
 void intel_gmch_panel_fitting(struct intel_crtc *crtc,
                              struct intel_crtc_config *pipe_config,
                              int fitting_mode);
-void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max);
+void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
+                              u32 max);
 int intel_panel_setup_backlight(struct drm_connector *connector);
-void intel_panel_enable_backlight(struct drm_device *dev, enum pipe pipe);
-void intel_panel_disable_backlight(struct drm_device *dev);
+void intel_panel_enable_backlight(struct intel_connector *connector);
+void intel_panel_disable_backlight(struct intel_connector *connector);
 void intel_panel_destroy_backlight(struct drm_device *dev);
 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 fb3f8ef..f3069ae2 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -206,7 +206,8 @@ static void intel_enable_lvds(struct intel_encoder *encoder)
 {
        struct drm_device *dev = encoder->base.dev;
        struct intel_lvds_encoder *lvds_encoder = 
to_lvds_encoder(&encoder->base);
-       struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+       struct intel_connector *intel_connector =
+               &lvds_encoder->attached_connector->base;
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 ctl_reg, stat_reg;
 
@@ -225,13 +226,15 @@ static void intel_enable_lvds(struct intel_encoder 
*encoder)
        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_crtc->pipe);
+       intel_panel_enable_backlight(intel_connector);
 }
 
 static void intel_disable_lvds(struct intel_encoder *encoder)
 {
        struct drm_device *dev = encoder->base.dev;
        struct intel_lvds_encoder *lvds_encoder = 
to_lvds_encoder(&encoder->base);
+       struct intel_connector *intel_connector =
+               &lvds_encoder->attached_connector->base;
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 ctl_reg, stat_reg;
 
@@ -243,7 +246,7 @@ static void intel_disable_lvds(struct intel_encoder 
*encoder)
                stat_reg = PP_STATUS;
        }
 
-       intel_panel_disable_backlight(dev);
+       intel_panel_disable_backlight(intel_connector);
 
        I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
        if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000))
diff --git a/drivers/gpu/drm/i915/intel_opregion.c 
b/drivers/gpu/drm/i915/intel_opregion.c
index 2acf5ca..2404e1c 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -395,6 +395,11 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 
bclp)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct opregion_asle __iomem *asle = dev_priv->opregion.asle;
+       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
+       struct drm_encoder *encoder;
+       struct drm_connector *connector;
+       struct intel_connector *intel_connector = NULL;
+       bool found = false;
 
        DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
 
@@ -405,7 +410,28 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 
bclp)
        if (bclp > 255)
                return ASLC_BACKLIGHT_FAILED;
 
-       intel_panel_set_backlight(dev, bclp, 255);
+       /*
+        * Could match the OpRegion connector here instead, but we'd
+        * also need to verify the connector could handle a backlight
+        * call.
+        */
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+               if (encoder->crtc == crtc) {
+                       found = true;
+                       break;
+               }
+
+       if (!found)
+               return ASLC_BACKLIGHT_FAILED;
+
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+               if (connector->encoder == encoder)
+                       intel_connector = to_intel_connector(connector);
+
+       if (!found)
+               return ASLC_BACKLIGHT_FAILED;
+
+       intel_panel_set_backlight(intel_connector, bclp, 255);
        iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv);
 
        return 0;
diff --git a/drivers/gpu/drm/i915/intel_panel.c 
b/drivers/gpu/drm/i915/intel_panel.c
index 5468416..5122f58 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -341,7 +341,7 @@ static int is_backlight_combination_mode(struct drm_device 
*dev)
 /* 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)
+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;
@@ -380,11 +380,12 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev)
        return val;
 }
 
-static u32 intel_panel_get_max_backlight(struct drm_device *dev)
+static u32 intel_panel_get_max_backlight(struct drm_device *dev,
+                                        enum pipe pipe)
 {
        u32 max;
 
-       max = i915_read_blc_pwm_ctl(dev);
+       max = i915_read_blc_pwm_ctl(dev, pipe);
 
        if (HAS_PCH_SPLIT(dev)) {
                max >>= 16;
@@ -410,7 +411,8 @@ MODULE_PARM_DESC(invert_brightness, "Invert backlight 
brightness "
        "to dri-de...@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, u32 val)
+static u32 intel_panel_compute_brightness(struct drm_device *dev,
+                                         enum pipe pipe, u32 val)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
@@ -419,7 +421,7 @@ static u32 intel_panel_compute_brightness(struct drm_device 
*dev, u32 val)
 
        if (i915_panel_invert_brightness > 0 ||
            dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
-               u32 max = intel_panel_get_max_backlight(dev);
+               u32 max = intel_panel_get_max_backlight(dev, pipe);
                if (max)
                        return max - val;
        }
@@ -427,7 +429,8 @@ static u32 intel_panel_compute_brightness(struct drm_device 
*dev, u32 val)
        return val;
 }
 
-static u32 intel_panel_get_backlight(struct drm_device *dev)
+static u32 intel_panel_get_backlight(struct drm_device *dev,
+                                    enum pipe pipe)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 val;
@@ -450,7 +453,7 @@ static u32 intel_panel_get_backlight(struct drm_device *dev)
                }
        }
 
-       val = intel_panel_compute_brightness(dev, val);
+       val = intel_panel_compute_brightness(dev, pipe, val);
 
        spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
 
@@ -466,19 +469,19 @@ static void intel_pch_panel_set_backlight(struct 
drm_device *dev, u32 level)
 }
 
 static void intel_panel_actually_set_backlight(struct drm_device *dev,
-                                              u32 level)
+                                              enum pipe pipe, u32 level)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 tmp;
 
        DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
-       level = intel_panel_compute_brightness(dev, 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);
+               u32 max = intel_panel_get_max_backlight(dev, pipe);
                u8 lbpc;
 
                /* we're screwed, but keep behaviour backwards compatible */
@@ -498,15 +501,18 @@ static void intel_panel_actually_set_backlight(struct 
drm_device *dev,
 }
 
 /* set backlight brightness to level in range [0..max] */
-void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max)
+void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
+                              u32 max)
 {
+       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 freq;
        unsigned long flags;
 
        spin_lock_irqsave(&dev_priv->backlight.lock, flags);
 
-       freq = intel_panel_get_max_backlight(dev);
+       freq = intel_panel_get_max_backlight(dev, pipe);
        if (!freq) {
                /* we are screwed, bail out */
                goto out;
@@ -523,14 +529,16 @@ void intel_panel_set_backlight(struct drm_device *dev, 
u32 level, u32 max)
                dev_priv->backlight.device->props.brightness = level;
 
        if (dev_priv->backlight.enabled)
-               intel_panel_actually_set_backlight(dev, level);
+               intel_panel_actually_set_backlight(dev, pipe, level);
 out:
        spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
 }
 
-void intel_panel_disable_backlight(struct drm_device *dev)
+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;
+       enum pipe pipe = intel_get_pipe_from_connector(connector);
        unsigned long flags;
 
        /*
@@ -547,7 +555,7 @@ void intel_panel_disable_backlight(struct drm_device *dev)
        spin_lock_irqsave(&dev_priv->backlight.lock, flags);
 
        dev_priv->backlight.enabled = false;
-       intel_panel_actually_set_backlight(dev, 0);
+       intel_panel_actually_set_backlight(dev, pipe, 0);
 
        if (INTEL_INFO(dev)->gen >= 4) {
                uint32_t reg, tmp;
@@ -566,10 +574,11 @@ void intel_panel_disable_backlight(struct drm_device *dev)
        spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
 }
 
-void intel_panel_enable_backlight(struct drm_device *dev,
-                                 enum pipe pipe)
+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;
+       enum pipe pipe = intel_get_pipe_from_connector(connector);
        enum transcoder cpu_transcoder =
                intel_pipe_to_cpu_transcoder(dev_priv, pipe);
        unsigned long flags;
@@ -577,7 +586,8 @@ void intel_panel_enable_backlight(struct drm_device *dev,
        spin_lock_irqsave(&dev_priv->backlight.lock, flags);
 
        if (dev_priv->backlight.level == 0) {
-               dev_priv->backlight.level = intel_panel_get_max_backlight(dev);
+               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;
@@ -627,7 +637,8 @@ set_level:
         * registers are set.
         */
        dev_priv->backlight.enabled = true;
-       intel_panel_actually_set_backlight(dev, dev_priv->backlight.level);
+       intel_panel_actually_set_backlight(dev, pipe,
+                                          dev_priv->backlight.level);
 
        spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
 }
@@ -650,7 +661,7 @@ static void intel_panel_init_backlight(struct drm_device 
*dev)
 
        intel_panel_init_backlight_regs(dev);
 
-       dev_priv->backlight.level = intel_panel_get_backlight(dev);
+       dev_priv->backlight.level = intel_panel_get_backlight(dev, 0);
        dev_priv->backlight.enabled = dev_priv->backlight.level != 0;
 }
 
@@ -679,16 +690,17 @@ intel_panel_detect(struct drm_device *dev)
 #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
 static int intel_panel_update_status(struct backlight_device *bd)
 {
-       struct drm_device *dev = bl_get_data(bd);
-       intel_panel_set_backlight(dev, bd->props.brightness,
+       struct intel_connector *connector = bl_get_data(bd);
+       intel_panel_set_backlight(connector, bd->props.brightness,
                                  bd->props.max_brightness);
        return 0;
 }
 
 static int intel_panel_get_brightness(struct backlight_device *bd)
 {
-       struct drm_device *dev = bl_get_data(bd);
-       return intel_panel_get_backlight(dev);
+       struct intel_connector *connector = bl_get_data(bd);
+       enum pipe pipe = intel_get_pipe_from_connector(connector);
+       return intel_panel_get_backlight(connector->base.dev, pipe);
 }
 
 static const struct backlight_ops intel_panel_bl_ops = {
@@ -708,12 +720,13 @@ int intel_panel_setup_backlight(struct drm_connector 
*connector)
        if (WARN_ON(dev_priv->backlight.device))
                return -ENODEV;
 
+       /* Just create a device for pipe 0 */
        memset(&props, 0, sizeof(props));
        props.type = BACKLIGHT_RAW;
        props.brightness = dev_priv->backlight.level;
 
        spin_lock_irqsave(&dev_priv->backlight.lock, flags);
-       props.max_brightness = intel_panel_get_max_backlight(dev);
+       props.max_brightness = intel_panel_get_max_backlight(dev, 0);
        spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
 
        if (props.max_brightness == 0) {
@@ -722,7 +735,8 @@ int intel_panel_setup_backlight(struct drm_connector 
*connector)
        }
        dev_priv->backlight.device =
                backlight_device_register("intel_backlight",
-                                         &connector->kdev, dev,
+                                         &connector->kdev,
+                                         to_intel_connector(connector),
                                          &intel_panel_bl_ops, &props);
 
        if (IS_ERR(dev_priv->backlight.device)) {
-- 
1.8.3.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to