aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_panel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_panel.c')
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c153
1 files changed, 115 insertions, 38 deletions
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 09b2994c9b37..f161ac02c4f6 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;
@@ -358,6 +358,21 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev)
358 val = dev_priv->regfile.saveBLC_PWM_CTL2; 358 val = dev_priv->regfile.saveBLC_PWM_CTL2;
359 I915_WRITE(BLC_PWM_PCH_CTL2, val); 359 I915_WRITE(BLC_PWM_PCH_CTL2, val);
360 } 360 }
361 } else if (IS_VALLEYVIEW(dev)) {
362 val = I915_READ(VLV_BLC_PWM_CTL(pipe));
363 if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
364 dev_priv->regfile.saveBLC_PWM_CTL = val;
365 dev_priv->regfile.saveBLC_PWM_CTL2 =
366 I915_READ(VLV_BLC_PWM_CTL2(pipe));
367 } else if (val == 0) {
368 val = dev_priv->regfile.saveBLC_PWM_CTL;
369 I915_WRITE(VLV_BLC_PWM_CTL(pipe), val);
370 I915_WRITE(VLV_BLC_PWM_CTL2(pipe),
371 dev_priv->regfile.saveBLC_PWM_CTL2);
372 }
373
374 if (!val)
375 val = 0x0f42ffff;
361 } else { 376 } else {
362 val = I915_READ(BLC_PWM_CTL); 377 val = I915_READ(BLC_PWM_CTL);
363 if (dev_priv->regfile.saveBLC_PWM_CTL == 0) { 378 if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
@@ -372,19 +387,17 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev)
372 I915_WRITE(BLC_PWM_CTL2, 387 I915_WRITE(BLC_PWM_CTL2,
373 dev_priv->regfile.saveBLC_PWM_CTL2); 388 dev_priv->regfile.saveBLC_PWM_CTL2);
374 } 389 }
375
376 if (IS_VALLEYVIEW(dev) && !val)
377 val = 0x0f42ffff;
378 } 390 }
379 391
380 return val; 392 return val;
381} 393}
382 394
383static u32 intel_panel_get_max_backlight(struct drm_device *dev) 395static u32 intel_panel_get_max_backlight(struct drm_device *dev,
396 enum pipe pipe)
384{ 397{
385 u32 max; 398 u32 max;
386 399
387 max = i915_read_blc_pwm_ctl(dev); 400 max = i915_read_blc_pwm_ctl(dev, pipe);
388 401
389 if (HAS_PCH_SPLIT(dev)) { 402 if (HAS_PCH_SPLIT(dev)) {
390 max >>= 16; 403 max >>= 16;
@@ -410,7 +423,8 @@ MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness "
410 "to dri-devel@lists.freedesktop.org, if your machine needs it. " 423 "to dri-devel@lists.freedesktop.org, if your machine needs it. "
411 "It will then be included in an upcoming module version."); 424 "It will then be included in an upcoming module version.");
412module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600); 425module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600);
413static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val) 426static u32 intel_panel_compute_brightness(struct drm_device *dev,
427 enum pipe pipe, u32 val)
414{ 428{
415 struct drm_i915_private *dev_priv = dev->dev_private; 429 struct drm_i915_private *dev_priv = dev->dev_private;
416 430
@@ -419,7 +433,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
419 433
420 if (i915_panel_invert_brightness > 0 || 434 if (i915_panel_invert_brightness > 0 ||
421 dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { 435 dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
422 u32 max = intel_panel_get_max_backlight(dev); 436 u32 max = intel_panel_get_max_backlight(dev, pipe);
423 if (max) 437 if (max)
424 return max - val; 438 return max - val;
425 } 439 }
@@ -427,18 +441,25 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
427 return val; 441 return val;
428} 442}
429 443
430static u32 intel_panel_get_backlight(struct drm_device *dev) 444static u32 intel_panel_get_backlight(struct drm_device *dev,
445 enum pipe pipe)
431{ 446{
432 struct drm_i915_private *dev_priv = dev->dev_private; 447 struct drm_i915_private *dev_priv = dev->dev_private;
433 u32 val; 448 u32 val;
434 unsigned long flags; 449 unsigned long flags;
450 int reg;
435 451
436 spin_lock_irqsave(&dev_priv->backlight.lock, flags); 452 spin_lock_irqsave(&dev_priv->backlight.lock, flags);
437 453
438 if (HAS_PCH_SPLIT(dev)) { 454 if (HAS_PCH_SPLIT(dev)) {
439 val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; 455 val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
440 } else { 456 } else {
441 val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; 457 if (IS_VALLEYVIEW(dev))
458 reg = VLV_BLC_PWM_CTL(pipe);
459 else
460 reg = BLC_PWM_CTL;
461
462 val = I915_READ(reg) & BACKLIGHT_DUTY_CYCLE_MASK;
442 if (INTEL_INFO(dev)->gen < 4) 463 if (INTEL_INFO(dev)->gen < 4)
443 val >>= 1; 464 val >>= 1;
444 465
@@ -450,7 +471,7 @@ static u32 intel_panel_get_backlight(struct drm_device *dev)
450 } 471 }
451 } 472 }
452 473
453 val = intel_panel_compute_brightness(dev, val); 474 val = intel_panel_compute_brightness(dev, pipe, val);
454 475
455 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); 476 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
456 477
@@ -466,19 +487,20 @@ static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
466} 487}
467 488
468static void intel_panel_actually_set_backlight(struct drm_device *dev, 489static void intel_panel_actually_set_backlight(struct drm_device *dev,
469 u32 level) 490 enum pipe pipe, u32 level)
470{ 491{
471 struct drm_i915_private *dev_priv = dev->dev_private; 492 struct drm_i915_private *dev_priv = dev->dev_private;
472 u32 tmp; 493 u32 tmp;
494 int reg;
473 495
474 DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); 496 DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
475 level = intel_panel_compute_brightness(dev, level); 497 level = intel_panel_compute_brightness(dev, pipe, level);
476 498
477 if (HAS_PCH_SPLIT(dev)) 499 if (HAS_PCH_SPLIT(dev))
478 return intel_pch_panel_set_backlight(dev, level); 500 return intel_pch_panel_set_backlight(dev, level);
479 501
480 if (is_backlight_combination_mode(dev)) { 502 if (is_backlight_combination_mode(dev)) {
481 u32 max = intel_panel_get_max_backlight(dev); 503 u32 max = intel_panel_get_max_backlight(dev, pipe);
482 u8 lbpc; 504 u8 lbpc;
483 505
484 /* we're screwed, but keep behaviour backwards compatible */ 506 /* we're screwed, but keep behaviour backwards compatible */
@@ -490,23 +512,34 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev,
490 pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc); 512 pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
491 } 513 }
492 514
493 tmp = I915_READ(BLC_PWM_CTL); 515 if (IS_VALLEYVIEW(dev))
516 reg = VLV_BLC_PWM_CTL(pipe);
517 else
518 reg = BLC_PWM_CTL;
519
520 tmp = I915_READ(reg);
494 if (INTEL_INFO(dev)->gen < 4) 521 if (INTEL_INFO(dev)->gen < 4)
495 level <<= 1; 522 level <<= 1;
496 tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK; 523 tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK;
497 I915_WRITE(BLC_PWM_CTL, tmp | level); 524 I915_WRITE(reg, tmp | level);
498} 525}
499 526
500/* set backlight brightness to level in range [0..max] */ 527/* set backlight brightness to level in range [0..max] */
501void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max) 528void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
529 u32 max)
502{ 530{
531 struct drm_device *dev = connector->base.dev;
503 struct drm_i915_private *dev_priv = dev->dev_private; 532 struct drm_i915_private *dev_priv = dev->dev_private;
533 enum pipe pipe = intel_get_pipe_from_connector(connector);
504 u32 freq; 534 u32 freq;
505 unsigned long flags; 535 unsigned long flags;
506 536
537 if (pipe == INVALID_PIPE)
538 return;
539
507 spin_lock_irqsave(&dev_priv->backlight.lock, flags); 540 spin_lock_irqsave(&dev_priv->backlight.lock, flags);
508 541
509 freq = intel_panel_get_max_backlight(dev); 542 freq = intel_panel_get_max_backlight(dev, pipe);
510 if (!freq) { 543 if (!freq) {
511 /* we are screwed, bail out */ 544 /* we are screwed, bail out */
512 goto out; 545 goto out;
@@ -523,16 +556,21 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max)
523 dev_priv->backlight.device->props.brightness = level; 556 dev_priv->backlight.device->props.brightness = level;
524 557
525 if (dev_priv->backlight.enabled) 558 if (dev_priv->backlight.enabled)
526 intel_panel_actually_set_backlight(dev, level); 559 intel_panel_actually_set_backlight(dev, pipe, level);
527out: 560out:
528 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); 561 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
529} 562}
530 563
531void intel_panel_disable_backlight(struct drm_device *dev) 564void intel_panel_disable_backlight(struct intel_connector *connector)
532{ 565{
566 struct drm_device *dev = connector->base.dev;
533 struct drm_i915_private *dev_priv = dev->dev_private; 567 struct drm_i915_private *dev_priv = dev->dev_private;
568 enum pipe pipe = intel_get_pipe_from_connector(connector);
534 unsigned long flags; 569 unsigned long flags;
535 570
571 if (pipe == INVALID_PIPE)
572 return;
573
536 /* 574 /*
537 * Do not disable backlight on the vgaswitcheroo path. When switching 575 * Do not disable backlight on the vgaswitcheroo path. When switching
538 * away from i915, the other client may depend on i915 to handle the 576 * away from i915, the other client may depend on i915 to handle the
@@ -547,12 +585,17 @@ void intel_panel_disable_backlight(struct drm_device *dev)
547 spin_lock_irqsave(&dev_priv->backlight.lock, flags); 585 spin_lock_irqsave(&dev_priv->backlight.lock, flags);
548 586
549 dev_priv->backlight.enabled = false; 587 dev_priv->backlight.enabled = false;
550 intel_panel_actually_set_backlight(dev, 0); 588 intel_panel_actually_set_backlight(dev, pipe, 0);
551 589
552 if (INTEL_INFO(dev)->gen >= 4) { 590 if (INTEL_INFO(dev)->gen >= 4) {
553 uint32_t reg, tmp; 591 uint32_t reg, tmp;
554 592
555 reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2; 593 if (HAS_PCH_SPLIT(dev))
594 reg = BLC_PWM_CPU_CTL2;
595 else if (IS_VALLEYVIEW(dev))
596 reg = VLV_BLC_PWM_CTL2(pipe);
597 else
598 reg = BLC_PWM_CTL2;
556 599
557 I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE); 600 I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE);
558 601
@@ -566,20 +609,25 @@ void intel_panel_disable_backlight(struct drm_device *dev)
566 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); 609 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
567} 610}
568 611
569void intel_panel_enable_backlight(struct drm_device *dev, 612void intel_panel_enable_backlight(struct intel_connector *connector)
570 enum pipe pipe)
571{ 613{
614 struct drm_device *dev = connector->base.dev;
572 struct drm_i915_private *dev_priv = dev->dev_private; 615 struct drm_i915_private *dev_priv = dev->dev_private;
616 enum pipe pipe = intel_get_pipe_from_connector(connector);
573 enum transcoder cpu_transcoder = 617 enum transcoder cpu_transcoder =
574 intel_pipe_to_cpu_transcoder(dev_priv, pipe); 618 intel_pipe_to_cpu_transcoder(dev_priv, pipe);
575 unsigned long flags; 619 unsigned long flags;
576 620
621 if (pipe == INVALID_PIPE)
622 return;
623
577 DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); 624 DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
578 625
579 spin_lock_irqsave(&dev_priv->backlight.lock, flags); 626 spin_lock_irqsave(&dev_priv->backlight.lock, flags);
580 627
581 if (dev_priv->backlight.level == 0) { 628 if (dev_priv->backlight.level == 0) {
582 dev_priv->backlight.level = intel_panel_get_max_backlight(dev); 629 dev_priv->backlight.level = intel_panel_get_max_backlight(dev,
630 pipe);
583 if (dev_priv->backlight.device) 631 if (dev_priv->backlight.device)
584 dev_priv->backlight.device->props.brightness = 632 dev_priv->backlight.device->props.brightness =
585 dev_priv->backlight.level; 633 dev_priv->backlight.level;
@@ -588,8 +636,12 @@ void intel_panel_enable_backlight(struct drm_device *dev,
588 if (INTEL_INFO(dev)->gen >= 4) { 636 if (INTEL_INFO(dev)->gen >= 4) {
589 uint32_t reg, tmp; 637 uint32_t reg, tmp;
590 638
591 reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2; 639 if (HAS_PCH_SPLIT(dev))
592 640 reg = BLC_PWM_CPU_CTL2;
641 else if (IS_VALLEYVIEW(dev))
642 reg = VLV_BLC_PWM_CTL2(pipe);
643 else
644 reg = BLC_PWM_CTL2;
593 645
594 tmp = I915_READ(reg); 646 tmp = I915_READ(reg);
595 647
@@ -629,7 +681,8 @@ set_level:
629 * registers are set. 681 * registers are set.
630 */ 682 */
631 dev_priv->backlight.enabled = true; 683 dev_priv->backlight.enabled = true;
632 intel_panel_actually_set_backlight(dev, dev_priv->backlight.level); 684 intel_panel_actually_set_backlight(dev, pipe,
685 dev_priv->backlight.level);
633 686
634 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); 687 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
635} 688}
@@ -640,9 +693,19 @@ static void intel_panel_init_backlight_regs(struct drm_device *dev)
640 struct drm_i915_private *dev_priv = dev->dev_private; 693 struct drm_i915_private *dev_priv = dev->dev_private;
641 694
642 if (IS_VALLEYVIEW(dev)) { 695 if (IS_VALLEYVIEW(dev)) {
643 u32 cur_val = I915_READ(BLC_PWM_CTL) & 696 enum pipe pipe;
644 BACKLIGHT_DUTY_CYCLE_MASK; 697
645 I915_WRITE(BLC_PWM_CTL, (0xf42 << 16) | cur_val); 698 for_each_pipe(pipe) {
699 u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe));
700
701 /* Skip if the modulation freq is already set */
702 if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK)
703 continue;
704
705 cur_val &= BACKLIGHT_DUTY_CYCLE_MASK;
706 I915_WRITE(VLV_BLC_PWM_CTL(pipe), (0xf42 << 16) |
707 cur_val);
708 }
646 } 709 }
647} 710}
648 711
@@ -652,7 +715,7 @@ static void intel_panel_init_backlight(struct drm_device *dev)
652 715
653 intel_panel_init_backlight_regs(dev); 716 intel_panel_init_backlight_regs(dev);
654 717
655 dev_priv->backlight.level = intel_panel_get_backlight(dev); 718 dev_priv->backlight.level = intel_panel_get_backlight(dev, 0);
656 dev_priv->backlight.enabled = dev_priv->backlight.level != 0; 719 dev_priv->backlight.enabled = dev_priv->backlight.level != 0;
657} 720}
658 721
@@ -681,18 +744,31 @@ intel_panel_detect(struct drm_device *dev)
681#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) 744#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
682static int intel_panel_update_status(struct backlight_device *bd) 745static int intel_panel_update_status(struct backlight_device *bd)
683{ 746{
684 struct drm_device *dev = bl_get_data(bd); 747 struct intel_connector *connector = bl_get_data(bd);
748 struct drm_device *dev = connector->base.dev;
749
750 mutex_lock(&dev->mode_config.mutex);
685 DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n", 751 DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
686 bd->props.brightness, bd->props.max_brightness); 752 bd->props.brightness, bd->props.max_brightness);
687 intel_panel_set_backlight(dev, bd->props.brightness, 753 intel_panel_set_backlight(connector, bd->props.brightness,
688 bd->props.max_brightness); 754 bd->props.max_brightness);
755 mutex_unlock(&dev->mode_config.mutex);
689 return 0; 756 return 0;
690} 757}
691 758
692static int intel_panel_get_brightness(struct backlight_device *bd) 759static int intel_panel_get_brightness(struct backlight_device *bd)
693{ 760{
694 struct drm_device *dev = bl_get_data(bd); 761 struct intel_connector *connector = bl_get_data(bd);
695 return intel_panel_get_backlight(dev); 762 struct drm_device *dev = connector->base.dev;
763 enum pipe pipe;
764
765 mutex_lock(&dev->mode_config.mutex);
766 pipe = intel_get_pipe_from_connector(connector);
767 mutex_unlock(&dev->mode_config.mutex);
768 if (pipe == INVALID_PIPE)
769 return 0;
770
771 return intel_panel_get_backlight(connector->base.dev, pipe);
696} 772}
697 773
698static const struct backlight_ops intel_panel_bl_ops = { 774static const struct backlight_ops intel_panel_bl_ops = {
@@ -717,7 +793,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
717 props.brightness = dev_priv->backlight.level; 793 props.brightness = dev_priv->backlight.level;
718 794
719 spin_lock_irqsave(&dev_priv->backlight.lock, flags); 795 spin_lock_irqsave(&dev_priv->backlight.lock, flags);
720 props.max_brightness = intel_panel_get_max_backlight(dev); 796 props.max_brightness = intel_panel_get_max_backlight(dev, 0);
721 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); 797 spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
722 798
723 if (props.max_brightness == 0) { 799 if (props.max_brightness == 0) {
@@ -726,7 +802,8 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
726 } 802 }
727 dev_priv->backlight.device = 803 dev_priv->backlight.device =
728 backlight_device_register("intel_backlight", 804 backlight_device_register("intel_backlight",
729 connector->kdev, dev, 805 connector->kdev,
806 to_intel_connector(connector),
730 &intel_panel_bl_ops, &props); 807 &intel_panel_bl_ops, &props);
731 808
732 if (IS_ERR(dev_priv->backlight.device)) { 809 if (IS_ERR(dev_priv->backlight.device)) {