diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_drv.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 74 |
1 files changed, 47 insertions, 27 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 651e65e051c0..6c4b25ce8bb0 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -28,6 +28,7 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/device.h> | 30 | #include <linux/device.h> |
31 | #include <linux/acpi.h> | ||
31 | #include <drm/drmP.h> | 32 | #include <drm/drmP.h> |
32 | #include <drm/i915_drm.h> | 33 | #include <drm/i915_drm.h> |
33 | #include "i915_drv.h" | 34 | #include "i915_drv.h" |
@@ -46,8 +47,6 @@ static struct drm_driver driver; | |||
46 | PIPE_C_OFFSET, PIPE_EDP_OFFSET }, \ | 47 | PIPE_C_OFFSET, PIPE_EDP_OFFSET }, \ |
47 | .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ | 48 | .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ |
48 | TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET }, \ | 49 | TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET }, \ |
49 | .dpll_offsets = { DPLL_A_OFFSET, DPLL_B_OFFSET }, \ | ||
50 | .dpll_md_offsets = { DPLL_A_MD_OFFSET, DPLL_B_MD_OFFSET }, \ | ||
51 | .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET } | 50 | .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET } |
52 | 51 | ||
53 | #define GEN_CHV_PIPEOFFSETS \ | 52 | #define GEN_CHV_PIPEOFFSETS \ |
@@ -55,10 +54,6 @@ static struct drm_driver driver; | |||
55 | CHV_PIPE_C_OFFSET }, \ | 54 | CHV_PIPE_C_OFFSET }, \ |
56 | .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ | 55 | .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ |
57 | CHV_TRANSCODER_C_OFFSET, }, \ | 56 | CHV_TRANSCODER_C_OFFSET, }, \ |
58 | .dpll_offsets = { DPLL_A_OFFSET, DPLL_B_OFFSET, \ | ||
59 | CHV_DPLL_C_OFFSET }, \ | ||
60 | .dpll_md_offsets = { DPLL_A_MD_OFFSET, DPLL_B_MD_OFFSET, \ | ||
61 | CHV_DPLL_C_MD_OFFSET }, \ | ||
62 | .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET, \ | 57 | .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET, \ |
63 | CHV_PALETTE_C_OFFSET } | 58 | CHV_PALETTE_C_OFFSET } |
64 | 59 | ||
@@ -308,6 +303,7 @@ static const struct intel_device_info intel_broadwell_d_info = { | |||
308 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, | 303 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, |
309 | .has_llc = 1, | 304 | .has_llc = 1, |
310 | .has_ddi = 1, | 305 | .has_ddi = 1, |
306 | .has_fpga_dbg = 1, | ||
311 | .has_fbc = 1, | 307 | .has_fbc = 1, |
312 | GEN_DEFAULT_PIPEOFFSETS, | 308 | GEN_DEFAULT_PIPEOFFSETS, |
313 | IVB_CURSOR_OFFSETS, | 309 | IVB_CURSOR_OFFSETS, |
@@ -319,6 +315,7 @@ static const struct intel_device_info intel_broadwell_m_info = { | |||
319 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, | 315 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, |
320 | .has_llc = 1, | 316 | .has_llc = 1, |
321 | .has_ddi = 1, | 317 | .has_ddi = 1, |
318 | .has_fpga_dbg = 1, | ||
322 | .has_fbc = 1, | 319 | .has_fbc = 1, |
323 | GEN_DEFAULT_PIPEOFFSETS, | 320 | GEN_DEFAULT_PIPEOFFSETS, |
324 | IVB_CURSOR_OFFSETS, | 321 | IVB_CURSOR_OFFSETS, |
@@ -330,6 +327,7 @@ static const struct intel_device_info intel_broadwell_gt3d_info = { | |||
330 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, | 327 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, |
331 | .has_llc = 1, | 328 | .has_llc = 1, |
332 | .has_ddi = 1, | 329 | .has_ddi = 1, |
330 | .has_fpga_dbg = 1, | ||
333 | .has_fbc = 1, | 331 | .has_fbc = 1, |
334 | GEN_DEFAULT_PIPEOFFSETS, | 332 | GEN_DEFAULT_PIPEOFFSETS, |
335 | IVB_CURSOR_OFFSETS, | 333 | IVB_CURSOR_OFFSETS, |
@@ -341,6 +339,7 @@ static const struct intel_device_info intel_broadwell_gt3m_info = { | |||
341 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, | 339 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, |
342 | .has_llc = 1, | 340 | .has_llc = 1, |
343 | .has_ddi = 1, | 341 | .has_ddi = 1, |
342 | .has_fpga_dbg = 1, | ||
344 | .has_fbc = 1, | 343 | .has_fbc = 1, |
345 | GEN_DEFAULT_PIPEOFFSETS, | 344 | GEN_DEFAULT_PIPEOFFSETS, |
346 | IVB_CURSOR_OFFSETS, | 345 | IVB_CURSOR_OFFSETS, |
@@ -482,10 +481,6 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) | |||
482 | if (i915.semaphores >= 0) | 481 | if (i915.semaphores >= 0) |
483 | return i915.semaphores; | 482 | return i915.semaphores; |
484 | 483 | ||
485 | /* Until we get further testing... */ | ||
486 | if (IS_GEN8(dev)) | ||
487 | return false; | ||
488 | |||
489 | #ifdef CONFIG_INTEL_IOMMU | 484 | #ifdef CONFIG_INTEL_IOMMU |
490 | /* Enable semaphores on SNB when IO remapping is off */ | 485 | /* Enable semaphores on SNB when IO remapping is off */ |
491 | if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) | 486 | if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) |
@@ -499,8 +494,7 @@ static int i915_drm_freeze(struct drm_device *dev) | |||
499 | { | 494 | { |
500 | struct drm_i915_private *dev_priv = dev->dev_private; | 495 | struct drm_i915_private *dev_priv = dev->dev_private; |
501 | struct drm_crtc *crtc; | 496 | struct drm_crtc *crtc; |
502 | 497 | pci_power_t opregion_target_state; | |
503 | intel_runtime_pm_get(dev_priv); | ||
504 | 498 | ||
505 | /* ignore lid events during suspend */ | 499 | /* ignore lid events during suspend */ |
506 | mutex_lock(&dev_priv->modeset_restore_lock); | 500 | mutex_lock(&dev_priv->modeset_restore_lock); |
@@ -526,21 +520,23 @@ static int i915_drm_freeze(struct drm_device *dev) | |||
526 | return error; | 520 | return error; |
527 | } | 521 | } |
528 | 522 | ||
529 | drm_irq_uninstall(dev); | ||
530 | dev_priv->enable_hotplug_processing = false; | ||
531 | |||
532 | intel_disable_gt_powersave(dev); | ||
533 | |||
534 | /* | 523 | /* |
535 | * Disable CRTCs directly since we want to preserve sw state | 524 | * Disable CRTCs directly since we want to preserve sw state |
536 | * for _thaw. | 525 | * for _thaw. Also, power gate the CRTC power wells. |
537 | */ | 526 | */ |
538 | drm_modeset_lock_all(dev); | 527 | drm_modeset_lock_all(dev); |
539 | for_each_crtc(dev, crtc) { | 528 | for_each_crtc(dev, crtc) |
540 | dev_priv->display.crtc_disable(crtc); | 529 | intel_crtc_control(crtc, false); |
541 | } | ||
542 | drm_modeset_unlock_all(dev); | 530 | drm_modeset_unlock_all(dev); |
543 | 531 | ||
532 | intel_dp_mst_suspend(dev); | ||
533 | |||
534 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); | ||
535 | |||
536 | intel_runtime_pm_disable_interrupts(dev); | ||
537 | |||
538 | intel_suspend_gt_powersave(dev); | ||
539 | |||
544 | intel_modeset_suspend_hw(dev); | 540 | intel_modeset_suspend_hw(dev); |
545 | } | 541 | } |
546 | 542 | ||
@@ -548,8 +544,15 @@ static int i915_drm_freeze(struct drm_device *dev) | |||
548 | 544 | ||
549 | i915_save_state(dev); | 545 | i915_save_state(dev); |
550 | 546 | ||
547 | opregion_target_state = PCI_D3cold; | ||
548 | #if IS_ENABLED(CONFIG_ACPI_SLEEP) | ||
549 | if (acpi_target_system_state() < ACPI_STATE_S3) | ||
550 | opregion_target_state = PCI_D1; | ||
551 | #endif | ||
552 | intel_opregion_notify_adapter(dev, opregion_target_state); | ||
553 | |||
554 | intel_uncore_forcewake_reset(dev, false); | ||
551 | intel_opregion_fini(dev); | 555 | intel_opregion_fini(dev); |
552 | intel_uncore_fini(dev); | ||
553 | 556 | ||
554 | console_lock(); | 557 | console_lock(); |
555 | intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED); | 558 | intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED); |
@@ -557,6 +560,8 @@ static int i915_drm_freeze(struct drm_device *dev) | |||
557 | 560 | ||
558 | dev_priv->suspend_count++; | 561 | dev_priv->suspend_count++; |
559 | 562 | ||
563 | intel_display_set_init_power(dev_priv, false); | ||
564 | |||
560 | return 0; | 565 | return 0; |
561 | } | 566 | } |
562 | 567 | ||
@@ -606,7 +611,10 @@ static int i915_drm_thaw_early(struct drm_device *dev) | |||
606 | { | 611 | { |
607 | struct drm_i915_private *dev_priv = dev->dev_private; | 612 | struct drm_i915_private *dev_priv = dev->dev_private; |
608 | 613 | ||
609 | intel_uncore_early_sanitize(dev); | 614 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
615 | hsw_disable_pc8(dev_priv); | ||
616 | |||
617 | intel_uncore_early_sanitize(dev, true); | ||
610 | intel_uncore_sanitize(dev); | 618 | intel_uncore_sanitize(dev); |
611 | intel_power_domains_init_hw(dev_priv); | 619 | intel_power_domains_init_hw(dev_priv); |
612 | 620 | ||
@@ -639,11 +647,19 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) | |||
639 | } | 647 | } |
640 | mutex_unlock(&dev->struct_mutex); | 648 | mutex_unlock(&dev->struct_mutex); |
641 | 649 | ||
642 | /* We need working interrupts for modeset enabling ... */ | 650 | intel_runtime_pm_restore_interrupts(dev); |
643 | drm_irq_install(dev, dev->pdev->irq); | ||
644 | 651 | ||
645 | intel_modeset_init_hw(dev); | 652 | intel_modeset_init_hw(dev); |
646 | 653 | ||
654 | { | ||
655 | unsigned long irqflags; | ||
656 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
657 | if (dev_priv->display.hpd_irq_setup) | ||
658 | dev_priv->display.hpd_irq_setup(dev); | ||
659 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
660 | } | ||
661 | |||
662 | intel_dp_mst_resume(dev); | ||
647 | drm_modeset_lock_all(dev); | 663 | drm_modeset_lock_all(dev); |
648 | intel_modeset_setup_hw_state(dev, true); | 664 | intel_modeset_setup_hw_state(dev, true); |
649 | drm_modeset_unlock_all(dev); | 665 | drm_modeset_unlock_all(dev); |
@@ -655,7 +671,6 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) | |||
655 | * notifications. | 671 | * notifications. |
656 | * */ | 672 | * */ |
657 | intel_hpd_init(dev); | 673 | intel_hpd_init(dev); |
658 | dev_priv->enable_hotplug_processing = true; | ||
659 | /* Config may have changed between suspend and resume */ | 674 | /* Config may have changed between suspend and resume */ |
660 | drm_helper_hpd_irq_event(dev); | 675 | drm_helper_hpd_irq_event(dev); |
661 | } | 676 | } |
@@ -678,7 +693,8 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) | |||
678 | dev_priv->modeset_restore = MODESET_DONE; | 693 | dev_priv->modeset_restore = MODESET_DONE; |
679 | mutex_unlock(&dev_priv->modeset_restore_lock); | 694 | mutex_unlock(&dev_priv->modeset_restore_lock); |
680 | 695 | ||
681 | intel_runtime_pm_put(dev_priv); | 696 | intel_opregion_notify_adapter(dev, PCI_D0); |
697 | |||
682 | return 0; | 698 | return 0; |
683 | } | 699 | } |
684 | 700 | ||
@@ -887,6 +903,7 @@ static int i915_pm_suspend_late(struct device *dev) | |||
887 | { | 903 | { |
888 | struct pci_dev *pdev = to_pci_dev(dev); | 904 | struct pci_dev *pdev = to_pci_dev(dev); |
889 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | 905 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
906 | struct drm_i915_private *dev_priv = drm_dev->dev_private; | ||
890 | 907 | ||
891 | /* | 908 | /* |
892 | * We have a suspedn ordering issue with the snd-hda driver also | 909 | * We have a suspedn ordering issue with the snd-hda driver also |
@@ -900,6 +917,9 @@ static int i915_pm_suspend_late(struct device *dev) | |||
900 | if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) | 917 | if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
901 | return 0; | 918 | return 0; |
902 | 919 | ||
920 | if (IS_HASWELL(drm_dev) || IS_BROADWELL(drm_dev)) | ||
921 | hsw_enable_pc8(dev_priv); | ||
922 | |||
903 | pci_disable_device(pdev); | 923 | pci_disable_device(pdev); |
904 | pci_set_power_state(pdev, PCI_D3hot); | 924 | pci_set_power_state(pdev, PCI_D3hot); |
905 | 925 | ||