aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2013-10-31 12:55:49 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-11-06 11:56:28 -0500
commit752aa88a1e784c22d514db3b440e49427b58259e (patch)
tree755926ad23793496c41b601a9cbb42950a57416e
parent91a60f20712179e56b7a6c3d332a5f6f9a54aa11 (diff)
drm/i915: make backlight functions take a connector
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. v2: make connector pipe lookup check for NULL crtc (Jani) fixup connector check in ASLE code (Jani) v3: make sure we take the mode config lock around lookups (Daniel) v4: fix double unlock in panel_get_brightness (Daniel) v5: push ASLE work into a work queue (Daniel) v6: separate ASLE work to a prep patch, rebase (Jani) Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_display.c12
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c5
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h8
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c9
-rw-r--r--drivers/gpu/drm/i915/intel_opregion.c38
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c86
7 files changed, 122 insertions, 37 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8b37b3531c27..b2023d7c1d6b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -54,6 +54,7 @@
54#define DRIVER_DATE "20080730" 54#define DRIVER_DATE "20080730"
55 55
56enum pipe { 56enum pipe {
57 INVALID_PIPE = -1,
57 PIPE_A = 0, 58 PIPE_A = 0,
58 PIPE_B, 59 PIPE_B,
59 PIPE_C, 60 PIPE_C,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e31a740e1663..73f036bddb6f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9874,6 +9874,18 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
9874 drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); 9874 drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
9875} 9875}
9876 9876
9877enum pipe intel_get_pipe_from_connector(struct intel_connector *connector)
9878{
9879 struct drm_encoder *encoder = connector->base.encoder;
9880
9881 WARN_ON(!mutex_is_locked(&connector->base.dev->mode_config.mutex));
9882
9883 if (!encoder)
9884 return INVALID_PIPE;
9885
9886 return to_intel_crtc(encoder->crtc)->pipe;
9887}
9888
9877int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, 9889int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
9878 struct drm_file *file) 9890 struct drm_file *file)
9879{ 9891{
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index d58fbb6b5ffd..4609eedf52aa 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1249,7 +1249,6 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
1249 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); 1249 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
1250 struct drm_device *dev = intel_dig_port->base.base.dev; 1250 struct drm_device *dev = intel_dig_port->base.base.dev;
1251 struct drm_i915_private *dev_priv = dev->dev_private; 1251 struct drm_i915_private *dev_priv = dev->dev_private;
1252 int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe;
1253 u32 pp; 1252 u32 pp;
1254 u32 pp_ctrl_reg; 1253 u32 pp_ctrl_reg;
1255 1254
@@ -1272,7 +1271,7 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
1272 I915_WRITE(pp_ctrl_reg, pp); 1271 I915_WRITE(pp_ctrl_reg, pp);
1273 POSTING_READ(pp_ctrl_reg); 1272 POSTING_READ(pp_ctrl_reg);
1274 1273
1275 intel_panel_enable_backlight(dev, pipe); 1274 intel_panel_enable_backlight(intel_dp->attached_connector);
1276} 1275}
1277 1276
1278void ironlake_edp_backlight_off(struct intel_dp *intel_dp) 1277void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
@@ -1285,7 +1284,7 @@ void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
1285 if (!is_edp(intel_dp)) 1284 if (!is_edp(intel_dp))
1286 return; 1285 return;
1287 1286
1288 intel_panel_disable_backlight(dev); 1287 intel_panel_disable_backlight(intel_dp->attached_connector);
1289 1288
1290 DRM_DEBUG_KMS("\n"); 1289 DRM_DEBUG_KMS("\n");
1291 pp = ironlake_get_pp_control(intel_dp); 1290 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 9d2624fd92c2..1e49aa8f5377 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -630,6 +630,7 @@ void intel_connector_attach_encoder(struct intel_connector *connector,
630struct drm_encoder *intel_best_encoder(struct drm_connector *connector); 630struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
631struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, 631struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
632 struct drm_crtc *crtc); 632 struct drm_crtc *crtc);
633enum pipe intel_get_pipe_from_connector(struct intel_connector *connector);
633int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, 634int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
634 struct drm_file *file_priv); 635 struct drm_file *file_priv);
635enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, 636enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
@@ -802,10 +803,11 @@ void intel_pch_panel_fitting(struct intel_crtc *crtc,
802void intel_gmch_panel_fitting(struct intel_crtc *crtc, 803void intel_gmch_panel_fitting(struct intel_crtc *crtc,
803 struct intel_crtc_config *pipe_config, 804 struct intel_crtc_config *pipe_config,
804 int fitting_mode); 805 int fitting_mode);
805void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max); 806void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
807 u32 max);
806int intel_panel_setup_backlight(struct drm_connector *connector); 808int intel_panel_setup_backlight(struct drm_connector *connector);
807void intel_panel_enable_backlight(struct drm_device *dev, enum pipe pipe); 809void intel_panel_enable_backlight(struct intel_connector *connector);
808void intel_panel_disable_backlight(struct drm_device *dev); 810void intel_panel_disable_backlight(struct intel_connector *connector);
809void intel_panel_destroy_backlight(struct drm_device *dev); 811void intel_panel_destroy_backlight(struct drm_device *dev);
810enum drm_connector_status intel_panel_detect(struct drm_device *dev); 812enum drm_connector_status intel_panel_detect(struct drm_device *dev);
811 813
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index b0ef55833087..c3b4da7895ed 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)
206{ 206{
207 struct drm_device *dev = encoder->base.dev; 207 struct drm_device *dev = encoder->base.dev;
208 struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); 208 struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
209 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); 209 struct intel_connector *intel_connector =
210 &lvds_encoder->attached_connector->base;
210 struct drm_i915_private *dev_priv = dev->dev_private; 211 struct drm_i915_private *dev_priv = dev->dev_private;
211 u32 ctl_reg, stat_reg; 212 u32 ctl_reg, stat_reg;
212 213
@@ -225,13 +226,15 @@ static void intel_enable_lvds(struct intel_encoder *encoder)
225 if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) 226 if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000))
226 DRM_ERROR("timed out waiting for panel to power on\n"); 227 DRM_ERROR("timed out waiting for panel to power on\n");
227 228
228 intel_panel_enable_backlight(dev, intel_crtc->pipe); 229 intel_panel_enable_backlight(intel_connector);
229} 230}
230 231
231static void intel_disable_lvds(struct intel_encoder *encoder) 232static void intel_disable_lvds(struct intel_encoder *encoder)
232{ 233{
233 struct drm_device *dev = encoder->base.dev; 234 struct drm_device *dev = encoder->base.dev;
234 struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); 235 struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
236 struct intel_connector *intel_connector =
237 &lvds_encoder->attached_connector->base;
235 struct drm_i915_private *dev_priv = dev->dev_private; 238 struct drm_i915_private *dev_priv = dev->dev_private;
236 u32 ctl_reg, stat_reg; 239 u32 ctl_reg, stat_reg;
237 240
@@ -243,7 +246,7 @@ static void intel_disable_lvds(struct intel_encoder *encoder)
243 stat_reg = PP_STATUS; 246 stat_reg = PP_STATUS;
244 } 247 }
245 248
246 intel_panel_disable_backlight(dev); 249 intel_panel_disable_backlight(intel_connector);
247 250
248 I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); 251 I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
249 if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000)) 252 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 892d520175d8..91b68dca0641 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -396,7 +396,13 @@ int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
396static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) 396static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
397{ 397{
398 struct drm_i915_private *dev_priv = dev->dev_private; 398 struct drm_i915_private *dev_priv = dev->dev_private;
399 struct drm_encoder *encoder;
400 struct drm_connector *connector;
401 struct intel_connector *intel_connector = NULL;
402 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
399 struct opregion_asle __iomem *asle = dev_priv->opregion.asle; 403 struct opregion_asle __iomem *asle = dev_priv->opregion.asle;
404 u32 ret = 0;
405 bool found = false;
400 406
401 DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); 407 DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
402 408
@@ -407,11 +413,39 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
407 if (bclp > 255) 413 if (bclp > 255)
408 return ASLC_BACKLIGHT_FAILED; 414 return ASLC_BACKLIGHT_FAILED;
409 415
416 mutex_lock(&dev->mode_config.mutex);
417 /*
418 * Could match the OpRegion connector here instead, but we'd also need
419 * to verify the connector could handle a backlight call.
420 */
421 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
422 if (encoder->crtc == crtc) {
423 found = true;
424 break;
425 }
426
427 if (!found) {
428 ret = ASLC_BACKLIGHT_FAILED;
429 goto out;
430 }
431
432 list_for_each_entry(connector, &dev->mode_config.connector_list, head)
433 if (connector->encoder == encoder)
434 intel_connector = to_intel_connector(connector);
435
436 if (!intel_connector) {
437 ret = ASLC_BACKLIGHT_FAILED;
438 goto out;
439 }
440
410 DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp); 441 DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp);
411 intel_panel_set_backlight(dev, bclp, 255); 442 intel_panel_set_backlight(intel_connector, bclp, 255);
412 iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv); 443 iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv);
413 444
414 return 0; 445out:
446 mutex_unlock(&dev->mode_config.mutex);
447
448 return ret;
415} 449}
416 450
417static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi) 451static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index de1518614827..17ddcb00bd26 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)
341/* XXX: query mode clock or hardware clock and program max PWM appropriately 341/* XXX: query mode clock or hardware clock and program max PWM appropriately
342 * when it's 0. 342 * when it's 0.
343 */ 343 */
344static u32 i915_read_blc_pwm_ctl(struct drm_device *dev) 344static u32 i915_read_blc_pwm_ctl(struct drm_device *dev, enum pipe pipe)
345{ 345{
346 struct drm_i915_private *dev_priv = dev->dev_private; 346 struct drm_i915_private *dev_priv = dev->dev_private;
347 u32 val; 347 u32 val;
@@ -380,11 +380,12 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev)
380 return val; 380 return val;
381} 381}
382 382
383static u32 intel_panel_get_max_backlight(struct drm_device *dev) 383static u32 intel_panel_get_max_backlight(struct drm_device *dev,
384 enum pipe pipe)
384{ 385{
385 u32 max; 386 u32 max;
386 387
387 max = i915_read_blc_pwm_ctl(dev); 388 max = i915_read_blc_pwm_ctl(dev, pipe);
388 389
389 if (HAS_PCH_SPLIT(dev)) { 390 if (HAS_PCH_SPLIT(dev)) {
390 max >>= 16; 391 max >>= 16;
@@ -410,7 +411,8 @@ MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness "
410 "to dri-devel@lists.freedesktop.org, if your machine needs it. " 411 "to dri-devel@lists.freedesktop.org, if your machine needs it. "
411 "It will then be included in an upcoming module version."); 412 "It will then be included in an upcoming module version.");
412module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600); 413module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600);
413static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val) 414static u32 intel_panel_compute_brightness(struct drm_device *dev,
415 enum pipe pipe, u32 val)
414{ 416{
415 struct drm_i915_private *dev_priv = dev->dev_private; 417 struct drm_i915_private *dev_priv = dev->dev_private;
416 418
@@ -419,7 +421,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
419 421
420 if (i915_panel_invert_brightness > 0 || 422 if (i915_panel_invert_brightness > 0 ||
421 dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { 423 dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
422 u32 max = intel_panel_get_max_backlight(dev); 424 u32 max = intel_panel_get_max_backlight(dev, pipe);
423 if (max) 425 if (max)
424 return max - val; 426 return max - val;
425 } 427 }
@@ -427,7 +429,8 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
427 return val; 429 return val;
428} 430}
429 431
430static u32 intel_panel_get_backlight(struct drm_device *dev) 432static u32 intel_panel_get_backlight(struct drm_device *dev,
433 enum pipe pipe)
431{ 434{
432 struct drm_i915_private *dev_priv = dev->dev_private; 435 struct drm_i915_private *dev_priv = dev->dev_private;
433 u32 val; 436 u32 val;
@@ -450,7 +453,7 @@ static u32 intel_panel_get_backlight(struct drm_device *dev)
450 } 453 }
451 } 454 }
452 455
453 val = intel_panel_compute_brightness(dev, val); 456 val = intel_panel_compute_brightness(dev, pipe, val);
454 457
455 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); 458 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
456 459
@@ -466,19 +469,19 @@ static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
466} 469}
467 470
468static void intel_panel_actually_set_backlight(struct drm_device *dev, 471static void intel_panel_actually_set_backlight(struct drm_device *dev,
469 u32 level) 472 enum pipe pipe, u32 level)
470{ 473{
471 struct drm_i915_private *dev_priv = dev->dev_private; 474 struct drm_i915_private *dev_priv = dev->dev_private;
472 u32 tmp; 475 u32 tmp;
473 476
474 DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); 477 DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
475 level = intel_panel_compute_brightness(dev, level); 478 level = intel_panel_compute_brightness(dev, pipe, level);
476 479
477 if (HAS_PCH_SPLIT(dev)) 480 if (HAS_PCH_SPLIT(dev))
478 return intel_pch_panel_set_backlight(dev, level); 481 return intel_pch_panel_set_backlight(dev, level);
479 482
480 if (is_backlight_combination_mode(dev)) { 483 if (is_backlight_combination_mode(dev)) {
481 u32 max = intel_panel_get_max_backlight(dev); 484 u32 max = intel_panel_get_max_backlight(dev, pipe);
482 u8 lbpc; 485 u8 lbpc;
483 486
484 /* we're screwed, but keep behaviour backwards compatible */ 487 /* we're screwed, but keep behaviour backwards compatible */
@@ -498,15 +501,21 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev,
498} 501}
499 502
500/* set backlight brightness to level in range [0..max] */ 503/* set backlight brightness to level in range [0..max] */
501void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max) 504void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
505 u32 max)
502{ 506{
507 struct drm_device *dev = connector->base.dev;
503 struct drm_i915_private *dev_priv = dev->dev_private; 508 struct drm_i915_private *dev_priv = dev->dev_private;
509 enum pipe pipe = intel_get_pipe_from_connector(connector);
504 u32 freq; 510 u32 freq;
505 unsigned long flags; 511 unsigned long flags;
506 512
513 if (pipe == INVALID_PIPE)
514 return;
515
507 spin_lock_irqsave(&dev_priv->backlight.lock, flags); 516 spin_lock_irqsave(&dev_priv->backlight.lock, flags);
508 517
509 freq = intel_panel_get_max_backlight(dev); 518 freq = intel_panel_get_max_backlight(dev, pipe);
510 if (!freq) { 519 if (!freq) {
511 /* we are screwed, bail out */ 520 /* we are screwed, bail out */
512 goto out; 521 goto out;
@@ -523,16 +532,21 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max)
523 dev_priv->backlight.device->props.brightness = level; 532 dev_priv->backlight.device->props.brightness = level;
524 533
525 if (dev_priv->backlight.enabled) 534 if (dev_priv->backlight.enabled)
526 intel_panel_actually_set_backlight(dev, level); 535 intel_panel_actually_set_backlight(dev, pipe, level);
527out: 536out:
528 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); 537 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
529} 538}
530 539
531void intel_panel_disable_backlight(struct drm_device *dev) 540void intel_panel_disable_backlight(struct intel_connector *connector)
532{ 541{
542 struct drm_device *dev = connector->base.dev;
533 struct drm_i915_private *dev_priv = dev->dev_private; 543 struct drm_i915_private *dev_priv = dev->dev_private;
544 enum pipe pipe = intel_get_pipe_from_connector(connector);
534 unsigned long flags; 545 unsigned long flags;
535 546
547 if (pipe == INVALID_PIPE)
548 return;
549
536 /* 550 /*
537 * Do not disable backlight on the vgaswitcheroo path. When switching 551 * Do not disable backlight on the vgaswitcheroo path. When switching
538 * away from i915, the other client may depend on i915 to handle the 552 * away from i915, the other client may depend on i915 to handle the
@@ -547,7 +561,7 @@ void intel_panel_disable_backlight(struct drm_device *dev)
547 spin_lock_irqsave(&dev_priv->backlight.lock, flags); 561 spin_lock_irqsave(&dev_priv->backlight.lock, flags);
548 562
549 dev_priv->backlight.enabled = false; 563 dev_priv->backlight.enabled = false;
550 intel_panel_actually_set_backlight(dev, 0); 564 intel_panel_actually_set_backlight(dev, pipe, 0);
551 565
552 if (INTEL_INFO(dev)->gen >= 4) { 566 if (INTEL_INFO(dev)->gen >= 4) {
553 uint32_t reg, tmp; 567 uint32_t reg, tmp;
@@ -566,20 +580,25 @@ void intel_panel_disable_backlight(struct drm_device *dev)
566 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); 580 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
567} 581}
568 582
569void intel_panel_enable_backlight(struct drm_device *dev, 583void intel_panel_enable_backlight(struct intel_connector *connector)
570 enum pipe pipe)
571{ 584{
585 struct drm_device *dev = connector->base.dev;
572 struct drm_i915_private *dev_priv = dev->dev_private; 586 struct drm_i915_private *dev_priv = dev->dev_private;
587 enum pipe pipe = intel_get_pipe_from_connector(connector);
573 enum transcoder cpu_transcoder = 588 enum transcoder cpu_transcoder =
574 intel_pipe_to_cpu_transcoder(dev_priv, pipe); 589 intel_pipe_to_cpu_transcoder(dev_priv, pipe);
575 unsigned long flags; 590 unsigned long flags;
576 591
592 if (pipe == INVALID_PIPE)
593 return;
594
577 DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); 595 DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
578 596
579 spin_lock_irqsave(&dev_priv->backlight.lock, flags); 597 spin_lock_irqsave(&dev_priv->backlight.lock, flags);
580 598
581 if (dev_priv->backlight.level == 0) { 599 if (dev_priv->backlight.level == 0) {
582 dev_priv->backlight.level = intel_panel_get_max_backlight(dev); 600 dev_priv->backlight.level = intel_panel_get_max_backlight(dev,
601 pipe);
583 if (dev_priv->backlight.device) 602 if (dev_priv->backlight.device)
584 dev_priv->backlight.device->props.brightness = 603 dev_priv->backlight.device->props.brightness =
585 dev_priv->backlight.level; 604 dev_priv->backlight.level;
@@ -629,7 +648,8 @@ set_level:
629 * registers are set. 648 * registers are set.
630 */ 649 */
631 dev_priv->backlight.enabled = true; 650 dev_priv->backlight.enabled = true;
632 intel_panel_actually_set_backlight(dev, dev_priv->backlight.level); 651 intel_panel_actually_set_backlight(dev, pipe,
652 dev_priv->backlight.level);
633 653
634 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); 654 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
635} 655}
@@ -652,7 +672,7 @@ static void intel_panel_init_backlight(struct drm_device *dev)
652 672
653 intel_panel_init_backlight_regs(dev); 673 intel_panel_init_backlight_regs(dev);
654 674
655 dev_priv->backlight.level = intel_panel_get_backlight(dev); 675 dev_priv->backlight.level = intel_panel_get_backlight(dev, 0);
656 dev_priv->backlight.enabled = dev_priv->backlight.level != 0; 676 dev_priv->backlight.enabled = dev_priv->backlight.level != 0;
657} 677}
658 678
@@ -681,18 +701,31 @@ intel_panel_detect(struct drm_device *dev)
681#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) 701#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
682static int intel_panel_update_status(struct backlight_device *bd) 702static int intel_panel_update_status(struct backlight_device *bd)
683{ 703{
684 struct drm_device *dev = bl_get_data(bd); 704 struct intel_connector *connector = bl_get_data(bd);
705 struct drm_device *dev = connector->base.dev;
706
707 mutex_lock(&dev->mode_config.mutex);
685 DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n", 708 DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
686 bd->props.brightness, bd->props.max_brightness); 709 bd->props.brightness, bd->props.max_brightness);
687 intel_panel_set_backlight(dev, bd->props.brightness, 710 intel_panel_set_backlight(connector, bd->props.brightness,
688 bd->props.max_brightness); 711 bd->props.max_brightness);
712 mutex_unlock(&dev->mode_config.mutex);
689 return 0; 713 return 0;
690} 714}
691 715
692static int intel_panel_get_brightness(struct backlight_device *bd) 716static int intel_panel_get_brightness(struct backlight_device *bd)
693{ 717{
694 struct drm_device *dev = bl_get_data(bd); 718 struct intel_connector *connector = bl_get_data(bd);
695 return intel_panel_get_backlight(dev); 719 struct drm_device *dev = connector->base.dev;
720 enum pipe pipe;
721
722 mutex_lock(&dev->mode_config.mutex);
723 pipe = intel_get_pipe_from_connector(connector);
724 mutex_unlock(&dev->mode_config.mutex);
725 if (pipe == INVALID_PIPE)
726 return 0;
727
728 return intel_panel_get_backlight(connector->base.dev, pipe);
696} 729}
697 730
698static const struct backlight_ops intel_panel_bl_ops = { 731static const struct backlight_ops intel_panel_bl_ops = {
@@ -717,7 +750,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
717 props.brightness = dev_priv->backlight.level; 750 props.brightness = dev_priv->backlight.level;
718 751
719 spin_lock_irqsave(&dev_priv->backlight.lock, flags); 752 spin_lock_irqsave(&dev_priv->backlight.lock, flags);
720 props.max_brightness = intel_panel_get_max_backlight(dev); 753 props.max_brightness = intel_panel_get_max_backlight(dev, 0);
721 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); 754 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
722 755
723 if (props.max_brightness == 0) { 756 if (props.max_brightness == 0) {
@@ -726,7 +759,8 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
726 } 759 }
727 dev_priv->backlight.device = 760 dev_priv->backlight.device =
728 backlight_device_register("intel_backlight", 761 backlight_device_register("intel_backlight",
729 &connector->kdev, dev, 762 &connector->kdev,
763 to_intel_connector(connector),
730 &intel_panel_bl_ops, &props); 764 &intel_panel_bl_ops, &props);
731 765
732 if (IS_ERR(dev_priv->backlight.device)) { 766 if (IS_ERR(dev_priv->backlight.device)) {