diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 137 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_suspend.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 561 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_i2c.c | 8 |
9 files changed, 704 insertions, 45 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 263636e77e61..81ab4883d898 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -43,6 +43,9 @@ module_param_named(modeset, i915_modeset, int, 0400); | |||
43 | unsigned int i915_fbpercrtc = 0; | 43 | unsigned int i915_fbpercrtc = 0; |
44 | module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); | 44 | module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); |
45 | 45 | ||
46 | unsigned int i915_powersave = 1; | ||
47 | module_param_named(powersave, i915_powersave, int, 0400); | ||
48 | |||
46 | static struct drm_driver driver; | 49 | static struct drm_driver driver; |
47 | 50 | ||
48 | static struct pci_device_id pciidlist[] = { | 51 | static struct pci_device_id pciidlist[] = { |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e286f4e13bd7..76914ae65c31 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -311,7 +311,7 @@ typedef struct drm_i915_private { | |||
311 | u32 saveIMR; | 311 | u32 saveIMR; |
312 | u32 saveCACHE_MODE_0; | 312 | u32 saveCACHE_MODE_0; |
313 | u32 saveD_STATE; | 313 | u32 saveD_STATE; |
314 | u32 saveCG_2D_DIS; | 314 | u32 saveDSPCLK_GATE_D; |
315 | u32 saveMI_ARB_STATE; | 315 | u32 saveMI_ARB_STATE; |
316 | u32 saveSWF0[16]; | 316 | u32 saveSWF0[16]; |
317 | u32 saveSWF1[16]; | 317 | u32 saveSWF1[16]; |
@@ -443,6 +443,14 @@ typedef struct drm_i915_private { | |||
443 | struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; | 443 | struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; |
444 | } mm; | 444 | } mm; |
445 | struct sdvo_device_mapping sdvo_mappings[2]; | 445 | struct sdvo_device_mapping sdvo_mappings[2]; |
446 | |||
447 | /* Reclocking support */ | ||
448 | bool render_reclock_avail; | ||
449 | bool lvds_downclock_avail; | ||
450 | struct work_struct idle_work; | ||
451 | struct timer_list idle_timer; | ||
452 | bool busy; | ||
453 | u16 orig_clock; | ||
446 | } drm_i915_private_t; | 454 | } drm_i915_private_t; |
447 | 455 | ||
448 | /** driver private structure attached to each drm_gem_object */ | 456 | /** driver private structure attached to each drm_gem_object */ |
@@ -575,6 +583,7 @@ enum intel_chip_family { | |||
575 | extern struct drm_ioctl_desc i915_ioctls[]; | 583 | extern struct drm_ioctl_desc i915_ioctls[]; |
576 | extern int i915_max_ioctl; | 584 | extern int i915_max_ioctl; |
577 | extern unsigned int i915_fbpercrtc; | 585 | extern unsigned int i915_fbpercrtc; |
586 | extern unsigned int i915_powersave; | ||
578 | 587 | ||
579 | extern int i915_master_create(struct drm_device *dev, struct drm_master *master); | 588 | extern int i915_master_create(struct drm_device *dev, struct drm_master *master); |
580 | extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); | 589 | extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); |
@@ -903,6 +912,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
903 | /* dsparb controlled by hw only */ | 912 | /* dsparb controlled by hw only */ |
904 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 913 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
905 | 914 | ||
915 | #define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev)) | ||
916 | #define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | ||
917 | |||
906 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 918 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
907 | 919 | ||
908 | #endif | 920 | #endif |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7edb5b9d5792..73b58193afed 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "drm.h" | 29 | #include "drm.h" |
30 | #include "i915_drm.h" | 30 | #include "i915_drm.h" |
31 | #include "i915_drv.h" | 31 | #include "i915_drv.h" |
32 | #include "intel_drv.h" | ||
32 | #include <linux/swap.h> | 33 | #include <linux/swap.h> |
33 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
34 | 35 | ||
@@ -981,6 +982,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
981 | struct drm_i915_private *dev_priv = dev->dev_private; | 982 | struct drm_i915_private *dev_priv = dev->dev_private; |
982 | struct drm_i915_gem_set_domain *args = data; | 983 | struct drm_i915_gem_set_domain *args = data; |
983 | struct drm_gem_object *obj; | 984 | struct drm_gem_object *obj; |
985 | struct drm_i915_gem_object *obj_priv; | ||
984 | uint32_t read_domains = args->read_domains; | 986 | uint32_t read_domains = args->read_domains; |
985 | uint32_t write_domain = args->write_domain; | 987 | uint32_t write_domain = args->write_domain; |
986 | int ret; | 988 | int ret; |
@@ -1004,15 +1006,17 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1004 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 1006 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
1005 | if (obj == NULL) | 1007 | if (obj == NULL) |
1006 | return -EBADF; | 1008 | return -EBADF; |
1009 | obj_priv = obj->driver_private; | ||
1007 | 1010 | ||
1008 | mutex_lock(&dev->struct_mutex); | 1011 | mutex_lock(&dev->struct_mutex); |
1012 | |||
1013 | intel_mark_busy(dev, obj); | ||
1014 | |||
1009 | #if WATCH_BUF | 1015 | #if WATCH_BUF |
1010 | DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n", | 1016 | DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n", |
1011 | obj, obj->size, read_domains, write_domain); | 1017 | obj, obj->size, read_domains, write_domain); |
1012 | #endif | 1018 | #endif |
1013 | if (read_domains & I915_GEM_DOMAIN_GTT) { | 1019 | if (read_domains & I915_GEM_DOMAIN_GTT) { |
1014 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1015 | |||
1016 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); | 1020 | ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); |
1017 | 1021 | ||
1018 | /* Update the LRU on the fence for the CPU access that's | 1022 | /* Update the LRU on the fence for the CPU access that's |
@@ -2776,6 +2780,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | |||
2776 | BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU); | 2780 | BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU); |
2777 | BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU); | 2781 | BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU); |
2778 | 2782 | ||
2783 | intel_mark_busy(dev, obj); | ||
2784 | |||
2779 | #if WATCH_BUF | 2785 | #if WATCH_BUF |
2780 | DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", | 2786 | DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", |
2781 | __func__, obj, | 2787 | __func__, obj, |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 87a737ff3d72..884757ce5b67 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -55,7 +55,7 @@ | |||
55 | /* PCI config space */ | 55 | /* PCI config space */ |
56 | 56 | ||
57 | #define HPLLCC 0xc0 /* 855 only */ | 57 | #define HPLLCC 0xc0 /* 855 only */ |
58 | #define GC_CLOCK_CONTROL_MASK (3 << 0) | 58 | #define GC_CLOCK_CONTROL_MASK (0xf << 0) |
59 | #define GC_CLOCK_133_200 (0 << 0) | 59 | #define GC_CLOCK_133_200 (0 << 0) |
60 | #define GC_CLOCK_100_200 (1 << 0) | 60 | #define GC_CLOCK_100_200 (1 << 0) |
61 | #define GC_CLOCK_100_133 (2 << 0) | 61 | #define GC_CLOCK_100_133 (2 << 0) |
@@ -65,6 +65,25 @@ | |||
65 | #define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) | 65 | #define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) |
66 | #define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) | 66 | #define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) |
67 | #define GC_DISPLAY_CLOCK_MASK (7 << 4) | 67 | #define GC_DISPLAY_CLOCK_MASK (7 << 4) |
68 | #define GM45_GC_RENDER_CLOCK_MASK (0xf << 0) | ||
69 | #define GM45_GC_RENDER_CLOCK_266_MHZ (8 << 0) | ||
70 | #define GM45_GC_RENDER_CLOCK_320_MHZ (9 << 0) | ||
71 | #define GM45_GC_RENDER_CLOCK_400_MHZ (0xb << 0) | ||
72 | #define GM45_GC_RENDER_CLOCK_533_MHZ (0xc << 0) | ||
73 | #define I965_GC_RENDER_CLOCK_MASK (0xf << 0) | ||
74 | #define I965_GC_RENDER_CLOCK_267_MHZ (2 << 0) | ||
75 | #define I965_GC_RENDER_CLOCK_333_MHZ (3 << 0) | ||
76 | #define I965_GC_RENDER_CLOCK_444_MHZ (4 << 0) | ||
77 | #define I965_GC_RENDER_CLOCK_533_MHZ (5 << 0) | ||
78 | #define I945_GC_RENDER_CLOCK_MASK (7 << 0) | ||
79 | #define I945_GC_RENDER_CLOCK_166_MHZ (0 << 0) | ||
80 | #define I945_GC_RENDER_CLOCK_200_MHZ (1 << 0) | ||
81 | #define I945_GC_RENDER_CLOCK_250_MHZ (3 << 0) | ||
82 | #define I945_GC_RENDER_CLOCK_400_MHZ (5 << 0) | ||
83 | #define I915_GC_RENDER_CLOCK_MASK (7 << 0) | ||
84 | #define I915_GC_RENDER_CLOCK_166_MHZ (0 << 0) | ||
85 | #define I915_GC_RENDER_CLOCK_200_MHZ (1 << 0) | ||
86 | #define I915_GC_RENDER_CLOCK_333_MHZ (4 << 0) | ||
68 | #define LBB 0xf4 | 87 | #define LBB 0xf4 |
69 | 88 | ||
70 | /* VGA stuff */ | 89 | /* VGA stuff */ |
@@ -553,9 +572,118 @@ | |||
553 | #define DPLLA_TEST_M_BYPASS (1 << 2) | 572 | #define DPLLA_TEST_M_BYPASS (1 << 2) |
554 | #define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) | 573 | #define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) |
555 | #define D_STATE 0x6104 | 574 | #define D_STATE 0x6104 |
556 | #define CG_2D_DIS 0x6200 | 575 | #define DSTATE_PLL_D3_OFF (1<<3) |
557 | #define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) | 576 | #define DSTATE_GFX_CLOCK_GATING (1<<1) |
558 | #define CG_3D_DIS 0x6204 | 577 | #define DSTATE_DOT_CLOCK_GATING (1<<0) |
578 | #define DSPCLK_GATE_D 0x6200 | ||
579 | # define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */ | ||
580 | # define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */ | ||
581 | # define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */ | ||
582 | # define VRDUNIT_CLOCK_GATE_DISABLE (1 << 27) /* 965 */ | ||
583 | # define AUDUNIT_CLOCK_GATE_DISABLE (1 << 26) /* 965 */ | ||
584 | # define DPUNIT_A_CLOCK_GATE_DISABLE (1 << 25) /* 965 */ | ||
585 | # define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) /* 965 */ | ||
586 | # define TVRUNIT_CLOCK_GATE_DISABLE (1 << 23) /* 915-945 */ | ||
587 | # define TVCUNIT_CLOCK_GATE_DISABLE (1 << 22) /* 915-945 */ | ||
588 | # define TVFUNIT_CLOCK_GATE_DISABLE (1 << 21) /* 915-945 */ | ||
589 | # define TVEUNIT_CLOCK_GATE_DISABLE (1 << 20) /* 915-945 */ | ||
590 | # define DVSUNIT_CLOCK_GATE_DISABLE (1 << 19) /* 915-945 */ | ||
591 | # define DSSUNIT_CLOCK_GATE_DISABLE (1 << 18) /* 915-945 */ | ||
592 | # define DDBUNIT_CLOCK_GATE_DISABLE (1 << 17) /* 915-945 */ | ||
593 | # define DPRUNIT_CLOCK_GATE_DISABLE (1 << 16) /* 915-945 */ | ||
594 | # define DPFUNIT_CLOCK_GATE_DISABLE (1 << 15) /* 915-945 */ | ||
595 | # define DPBMUNIT_CLOCK_GATE_DISABLE (1 << 14) /* 915-945 */ | ||
596 | # define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13) /* 915-945 */ | ||
597 | # define DPLUNIT_CLOCK_GATE_DISABLE (1 << 12) /* 915-945 */ | ||
598 | # define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11) | ||
599 | # define DPBUNIT_CLOCK_GATE_DISABLE (1 << 10) | ||
600 | # define DCUNIT_CLOCK_GATE_DISABLE (1 << 9) | ||
601 | # define DPUNIT_CLOCK_GATE_DISABLE (1 << 8) | ||
602 | # define VRUNIT_CLOCK_GATE_DISABLE (1 << 7) /* 915+: reserved */ | ||
603 | # define OVHUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 830-865 */ | ||
604 | # define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 915-945 */ | ||
605 | # define OVFUNIT_CLOCK_GATE_DISABLE (1 << 5) | ||
606 | # define OVBUNIT_CLOCK_GATE_DISABLE (1 << 4) | ||
607 | /** | ||
608 | * This bit must be set on the 830 to prevent hangs when turning off the | ||
609 | * overlay scaler. | ||
610 | */ | ||
611 | # define OVRUNIT_CLOCK_GATE_DISABLE (1 << 3) | ||
612 | # define OVCUNIT_CLOCK_GATE_DISABLE (1 << 2) | ||
613 | # define OVUUNIT_CLOCK_GATE_DISABLE (1 << 1) | ||
614 | # define ZVUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 830 */ | ||
615 | # define OVLUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 845,865 */ | ||
616 | |||
617 | #define RENCLK_GATE_D1 0x6204 | ||
618 | # define BLITTER_CLOCK_GATE_DISABLE (1 << 13) /* 945GM only */ | ||
619 | # define MPEG_CLOCK_GATE_DISABLE (1 << 12) /* 945GM only */ | ||
620 | # define PC_FE_CLOCK_GATE_DISABLE (1 << 11) | ||
621 | # define PC_BE_CLOCK_GATE_DISABLE (1 << 10) | ||
622 | # define WINDOWER_CLOCK_GATE_DISABLE (1 << 9) | ||
623 | # define INTERPOLATOR_CLOCK_GATE_DISABLE (1 << 8) | ||
624 | # define COLOR_CALCULATOR_CLOCK_GATE_DISABLE (1 << 7) | ||
625 | # define MOTION_COMP_CLOCK_GATE_DISABLE (1 << 6) | ||
626 | # define MAG_CLOCK_GATE_DISABLE (1 << 5) | ||
627 | /** This bit must be unset on 855,865 */ | ||
628 | # define MECI_CLOCK_GATE_DISABLE (1 << 4) | ||
629 | # define DCMP_CLOCK_GATE_DISABLE (1 << 3) | ||
630 | # define MEC_CLOCK_GATE_DISABLE (1 << 2) | ||
631 | # define MECO_CLOCK_GATE_DISABLE (1 << 1) | ||
632 | /** This bit must be set on 855,865. */ | ||
633 | # define SV_CLOCK_GATE_DISABLE (1 << 0) | ||
634 | # define I915_MPEG_CLOCK_GATE_DISABLE (1 << 16) | ||
635 | # define I915_VLD_IP_PR_CLOCK_GATE_DISABLE (1 << 15) | ||
636 | # define I915_MOTION_COMP_CLOCK_GATE_DISABLE (1 << 14) | ||
637 | # define I915_BD_BF_CLOCK_GATE_DISABLE (1 << 13) | ||
638 | # define I915_SF_SE_CLOCK_GATE_DISABLE (1 << 12) | ||
639 | # define I915_WM_CLOCK_GATE_DISABLE (1 << 11) | ||
640 | # define I915_IZ_CLOCK_GATE_DISABLE (1 << 10) | ||
641 | # define I915_PI_CLOCK_GATE_DISABLE (1 << 9) | ||
642 | # define I915_DI_CLOCK_GATE_DISABLE (1 << 8) | ||
643 | # define I915_SH_SV_CLOCK_GATE_DISABLE (1 << 7) | ||
644 | # define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE (1 << 6) | ||
645 | # define I915_SC_CLOCK_GATE_DISABLE (1 << 5) | ||
646 | # define I915_FL_CLOCK_GATE_DISABLE (1 << 4) | ||
647 | # define I915_DM_CLOCK_GATE_DISABLE (1 << 3) | ||
648 | # define I915_PS_CLOCK_GATE_DISABLE (1 << 2) | ||
649 | # define I915_CC_CLOCK_GATE_DISABLE (1 << 1) | ||
650 | # define I915_BY_CLOCK_GATE_DISABLE (1 << 0) | ||
651 | |||
652 | # define I965_RCZ_CLOCK_GATE_DISABLE (1 << 30) | ||
653 | /** This bit must always be set on 965G/965GM */ | ||
654 | # define I965_RCC_CLOCK_GATE_DISABLE (1 << 29) | ||
655 | # define I965_RCPB_CLOCK_GATE_DISABLE (1 << 28) | ||
656 | # define I965_DAP_CLOCK_GATE_DISABLE (1 << 27) | ||
657 | # define I965_ROC_CLOCK_GATE_DISABLE (1 << 26) | ||
658 | # define I965_GW_CLOCK_GATE_DISABLE (1 << 25) | ||
659 | # define I965_TD_CLOCK_GATE_DISABLE (1 << 24) | ||
660 | /** This bit must always be set on 965G */ | ||
661 | # define I965_ISC_CLOCK_GATE_DISABLE (1 << 23) | ||
662 | # define I965_IC_CLOCK_GATE_DISABLE (1 << 22) | ||
663 | # define I965_EU_CLOCK_GATE_DISABLE (1 << 21) | ||
664 | # define I965_IF_CLOCK_GATE_DISABLE (1 << 20) | ||
665 | # define I965_TC_CLOCK_GATE_DISABLE (1 << 19) | ||
666 | # define I965_SO_CLOCK_GATE_DISABLE (1 << 17) | ||
667 | # define I965_FBC_CLOCK_GATE_DISABLE (1 << 16) | ||
668 | # define I965_MARI_CLOCK_GATE_DISABLE (1 << 15) | ||
669 | # define I965_MASF_CLOCK_GATE_DISABLE (1 << 14) | ||
670 | # define I965_MAWB_CLOCK_GATE_DISABLE (1 << 13) | ||
671 | # define I965_EM_CLOCK_GATE_DISABLE (1 << 12) | ||
672 | # define I965_UC_CLOCK_GATE_DISABLE (1 << 11) | ||
673 | # define I965_SI_CLOCK_GATE_DISABLE (1 << 6) | ||
674 | # define I965_MT_CLOCK_GATE_DISABLE (1 << 5) | ||
675 | # define I965_PL_CLOCK_GATE_DISABLE (1 << 4) | ||
676 | # define I965_DG_CLOCK_GATE_DISABLE (1 << 3) | ||
677 | # define I965_QC_CLOCK_GATE_DISABLE (1 << 2) | ||
678 | # define I965_FT_CLOCK_GATE_DISABLE (1 << 1) | ||
679 | # define I965_DM_CLOCK_GATE_DISABLE (1 << 0) | ||
680 | |||
681 | #define RENCLK_GATE_D2 0x6208 | ||
682 | #define VF_UNIT_CLOCK_GATE_DISABLE (1 << 9) | ||
683 | #define GS_UNIT_CLOCK_GATE_DISABLE (1 << 7) | ||
684 | #define CL_UNIT_CLOCK_GATE_DISABLE (1 << 6) | ||
685 | #define RAMCLK_GATE_D 0x6210 /* CRL only */ | ||
686 | #define DEUC 0x6214 /* CRL only */ | ||
559 | 687 | ||
560 | /* | 688 | /* |
561 | * Palette regs | 689 | * Palette regs |
@@ -1588,6 +1716,7 @@ | |||
1588 | #define PIPECONF_PROGRESSIVE (0 << 21) | 1716 | #define PIPECONF_PROGRESSIVE (0 << 21) |
1589 | #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) | 1717 | #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) |
1590 | #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) | 1718 | #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) |
1719 | #define PIPECONF_CXSR_DOWNCLOCK (1<<16) | ||
1591 | #define PIPEASTAT 0x70024 | 1720 | #define PIPEASTAT 0x70024 |
1592 | #define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) | 1721 | #define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) |
1593 | #define PIPE_CRC_ERROR_ENABLE (1UL<<29) | 1722 | #define PIPE_CRC_ERROR_ENABLE (1UL<<29) |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 1d04e1904ac6..20d4d19f5568 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -461,7 +461,7 @@ int i915_save_state(struct drm_device *dev) | |||
461 | 461 | ||
462 | /* Clock gating state */ | 462 | /* Clock gating state */ |
463 | dev_priv->saveD_STATE = I915_READ(D_STATE); | 463 | dev_priv->saveD_STATE = I915_READ(D_STATE); |
464 | dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS); | 464 | dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); |
465 | 465 | ||
466 | /* Cache mode state */ | 466 | /* Cache mode state */ |
467 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); | 467 | dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); |
@@ -588,7 +588,7 @@ int i915_restore_state(struct drm_device *dev) | |||
588 | 588 | ||
589 | /* Clock gating state */ | 589 | /* Clock gating state */ |
590 | I915_WRITE (D_STATE, dev_priv->saveD_STATE); | 590 | I915_WRITE (D_STATE, dev_priv->saveD_STATE); |
591 | I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS); | 591 | I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); |
592 | 592 | ||
593 | /* Cache mode state */ | 593 | /* Cache mode state */ |
594 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); | 594 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index f806fcc54e09..1e28c1652fd0 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -355,8 +355,14 @@ parse_driver_features(struct drm_i915_private *dev_priv, | |||
355 | } | 355 | } |
356 | 356 | ||
357 | driver = find_section(bdb, BDB_DRIVER_FEATURES); | 357 | driver = find_section(bdb, BDB_DRIVER_FEATURES); |
358 | if (driver && driver->lvds_config == BDB_DRIVER_FEATURE_EDP) | 358 | if (!driver) |
359 | return; | ||
360 | |||
361 | if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP) | ||
359 | dev_priv->edp_support = 1; | 362 | dev_priv->edp_support = 1; |
363 | |||
364 | if (driver->dual_frequency) | ||
365 | dev_priv->render_reclock_avail = true; | ||
360 | } | 366 | } |
361 | 367 | ||
362 | /** | 368 | /** |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 748ed50c55ca..3c9445193e3d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -38,6 +38,7 @@ | |||
38 | 38 | ||
39 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); | 39 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); |
40 | static void intel_update_watermarks(struct drm_device *dev); | 40 | static void intel_update_watermarks(struct drm_device *dev); |
41 | static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule); | ||
41 | 42 | ||
42 | typedef struct { | 43 | typedef struct { |
43 | /* given values */ | 44 | /* given values */ |
@@ -67,6 +68,8 @@ struct intel_limit { | |||
67 | intel_p2_t p2; | 68 | intel_p2_t p2; |
68 | bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, | 69 | bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, |
69 | int, int, intel_clock_t *); | 70 | int, int, intel_clock_t *); |
71 | bool (* find_reduced_pll)(const intel_limit_t *, struct drm_crtc *, | ||
72 | int, int, intel_clock_t *); | ||
70 | }; | 73 | }; |
71 | 74 | ||
72 | #define I8XX_DOT_MIN 25000 | 75 | #define I8XX_DOT_MIN 25000 |
@@ -261,6 +264,9 @@ static bool | |||
261 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 264 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
262 | int target, int refclk, intel_clock_t *best_clock); | 265 | int target, int refclk, intel_clock_t *best_clock); |
263 | static bool | 266 | static bool |
267 | intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
268 | int target, int refclk, intel_clock_t *best_clock); | ||
269 | static bool | ||
264 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 270 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
265 | int target, int refclk, intel_clock_t *best_clock); | 271 | int target, int refclk, intel_clock_t *best_clock); |
266 | static bool | 272 | static bool |
@@ -286,6 +292,7 @@ static const intel_limit_t intel_limits_i8xx_dvo = { | |||
286 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, | 292 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, |
287 | .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, | 293 | .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, |
288 | .find_pll = intel_find_best_PLL, | 294 | .find_pll = intel_find_best_PLL, |
295 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
289 | }; | 296 | }; |
290 | 297 | ||
291 | static const intel_limit_t intel_limits_i8xx_lvds = { | 298 | static const intel_limit_t intel_limits_i8xx_lvds = { |
@@ -300,6 +307,7 @@ static const intel_limit_t intel_limits_i8xx_lvds = { | |||
300 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, | 307 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, |
301 | .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, | 308 | .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, |
302 | .find_pll = intel_find_best_PLL, | 309 | .find_pll = intel_find_best_PLL, |
310 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
303 | }; | 311 | }; |
304 | 312 | ||
305 | static const intel_limit_t intel_limits_i9xx_sdvo = { | 313 | static const intel_limit_t intel_limits_i9xx_sdvo = { |
@@ -314,6 +322,7 @@ static const intel_limit_t intel_limits_i9xx_sdvo = { | |||
314 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 322 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
315 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 323 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
316 | .find_pll = intel_find_best_PLL, | 324 | .find_pll = intel_find_best_PLL, |
325 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
317 | }; | 326 | }; |
318 | 327 | ||
319 | static const intel_limit_t intel_limits_i9xx_lvds = { | 328 | static const intel_limit_t intel_limits_i9xx_lvds = { |
@@ -331,6 +340,7 @@ static const intel_limit_t intel_limits_i9xx_lvds = { | |||
331 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 340 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
332 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, | 341 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, |
333 | .find_pll = intel_find_best_PLL, | 342 | .find_pll = intel_find_best_PLL, |
343 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
334 | }; | 344 | }; |
335 | 345 | ||
336 | /* below parameter and function is for G4X Chipset Family*/ | 346 | /* below parameter and function is for G4X Chipset Family*/ |
@@ -348,6 +358,7 @@ static const intel_limit_t intel_limits_g4x_sdvo = { | |||
348 | .p2_fast = G4X_P2_SDVO_FAST | 358 | .p2_fast = G4X_P2_SDVO_FAST |
349 | }, | 359 | }, |
350 | .find_pll = intel_g4x_find_best_PLL, | 360 | .find_pll = intel_g4x_find_best_PLL, |
361 | .find_reduced_pll = intel_g4x_find_best_PLL, | ||
351 | }; | 362 | }; |
352 | 363 | ||
353 | static const intel_limit_t intel_limits_g4x_hdmi = { | 364 | static const intel_limit_t intel_limits_g4x_hdmi = { |
@@ -364,6 +375,7 @@ static const intel_limit_t intel_limits_g4x_hdmi = { | |||
364 | .p2_fast = G4X_P2_HDMI_DAC_FAST | 375 | .p2_fast = G4X_P2_HDMI_DAC_FAST |
365 | }, | 376 | }, |
366 | .find_pll = intel_g4x_find_best_PLL, | 377 | .find_pll = intel_g4x_find_best_PLL, |
378 | .find_reduced_pll = intel_g4x_find_best_PLL, | ||
367 | }; | 379 | }; |
368 | 380 | ||
369 | static const intel_limit_t intel_limits_g4x_single_channel_lvds = { | 381 | static const intel_limit_t intel_limits_g4x_single_channel_lvds = { |
@@ -388,6 +400,7 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = { | |||
388 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST | 400 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST |
389 | }, | 401 | }, |
390 | .find_pll = intel_g4x_find_best_PLL, | 402 | .find_pll = intel_g4x_find_best_PLL, |
403 | .find_reduced_pll = intel_g4x_find_best_PLL, | ||
391 | }; | 404 | }; |
392 | 405 | ||
393 | static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { | 406 | static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { |
@@ -412,6 +425,7 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { | |||
412 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST | 425 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST |
413 | }, | 426 | }, |
414 | .find_pll = intel_g4x_find_best_PLL, | 427 | .find_pll = intel_g4x_find_best_PLL, |
428 | .find_reduced_pll = intel_g4x_find_best_PLL, | ||
415 | }; | 429 | }; |
416 | 430 | ||
417 | static const intel_limit_t intel_limits_g4x_display_port = { | 431 | static const intel_limit_t intel_limits_g4x_display_port = { |
@@ -449,6 +463,7 @@ static const intel_limit_t intel_limits_igd_sdvo = { | |||
449 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 463 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
450 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 464 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
451 | .find_pll = intel_find_best_PLL, | 465 | .find_pll = intel_find_best_PLL, |
466 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
452 | }; | 467 | }; |
453 | 468 | ||
454 | static const intel_limit_t intel_limits_igd_lvds = { | 469 | static const intel_limit_t intel_limits_igd_lvds = { |
@@ -464,6 +479,7 @@ static const intel_limit_t intel_limits_igd_lvds = { | |||
464 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 479 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
465 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, | 480 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, |
466 | .find_pll = intel_find_best_PLL, | 481 | .find_pll = intel_find_best_PLL, |
482 | .find_reduced_pll = intel_find_best_reduced_PLL, | ||
467 | }; | 483 | }; |
468 | 484 | ||
469 | static const intel_limit_t intel_limits_igdng_sdvo = { | 485 | static const intel_limit_t intel_limits_igdng_sdvo = { |
@@ -688,15 +704,16 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
688 | 704 | ||
689 | memset (best_clock, 0, sizeof (*best_clock)); | 705 | memset (best_clock, 0, sizeof (*best_clock)); |
690 | 706 | ||
691 | for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) { | 707 | for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { |
692 | for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) { | 708 | for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; |
693 | /* m1 is always 0 in IGD */ | 709 | clock.m1++) { |
694 | if (clock.m2 >= clock.m1 && !IS_IGD(dev)) | 710 | for (clock.m2 = limit->m2.min; |
695 | break; | 711 | clock.m2 <= limit->m2.max; clock.m2++) { |
696 | for (clock.n = limit->n.min; clock.n <= limit->n.max; | 712 | /* m1 is always 0 in IGD */ |
697 | clock.n++) { | 713 | if (clock.m2 >= clock.m1 && !IS_IGD(dev)) |
698 | for (clock.p1 = limit->p1.min; | 714 | break; |
699 | clock.p1 <= limit->p1.max; clock.p1++) { | 715 | for (clock.n = limit->n.min; |
716 | clock.n <= limit->n.max; clock.n++) { | ||
700 | int this_err; | 717 | int this_err; |
701 | 718 | ||
702 | intel_clock(dev, refclk, &clock); | 719 | intel_clock(dev, refclk, &clock); |
@@ -717,6 +734,46 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
717 | return (err != target); | 734 | return (err != target); |
718 | } | 735 | } |
719 | 736 | ||
737 | |||
738 | static bool | ||
739 | intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
740 | int target, int refclk, intel_clock_t *best_clock) | ||
741 | |||
742 | { | ||
743 | struct drm_device *dev = crtc->dev; | ||
744 | intel_clock_t clock; | ||
745 | int err = target; | ||
746 | bool found = false; | ||
747 | |||
748 | memcpy(&clock, best_clock, sizeof(intel_clock_t)); | ||
749 | |||
750 | for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) { | ||
751 | for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) { | ||
752 | /* m1 is always 0 in IGD */ | ||
753 | if (clock.m2 >= clock.m1 && !IS_IGD(dev)) | ||
754 | break; | ||
755 | for (clock.n = limit->n.min; clock.n <= limit->n.max; | ||
756 | clock.n++) { | ||
757 | int this_err; | ||
758 | |||
759 | intel_clock(dev, refclk, &clock); | ||
760 | |||
761 | if (!intel_PLL_is_valid(crtc, &clock)) | ||
762 | continue; | ||
763 | |||
764 | this_err = abs(clock.dot - target); | ||
765 | if (this_err < err) { | ||
766 | *best_clock = clock; | ||
767 | err = this_err; | ||
768 | found = true; | ||
769 | } | ||
770 | } | ||
771 | } | ||
772 | } | ||
773 | |||
774 | return found; | ||
775 | } | ||
776 | |||
720 | static bool | 777 | static bool |
721 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 778 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
722 | int target, int refclk, intel_clock_t *best_clock) | 779 | int target, int refclk, intel_clock_t *best_clock) |
@@ -747,7 +804,7 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
747 | max_n = limit->n.max; | 804 | max_n = limit->n.max; |
748 | /* based on hardware requriment prefer smaller n to precision */ | 805 | /* based on hardware requriment prefer smaller n to precision */ |
749 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { | 806 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { |
750 | /* based on hardware requirment prefere larger m1,m2, p1 */ | 807 | /* based on hardware requirment prefere larger m1,m2 */ |
751 | for (clock.m1 = limit->m1.max; | 808 | for (clock.m1 = limit->m1.max; |
752 | clock.m1 >= limit->m1.min; clock.m1--) { | 809 | clock.m1 >= limit->m1.min; clock.m1--) { |
753 | for (clock.m2 = limit->m2.max; | 810 | for (clock.m2 = limit->m2.max; |
@@ -832,15 +889,14 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
832 | 889 | ||
833 | memset(best_clock, 0, sizeof(*best_clock)); | 890 | memset(best_clock, 0, sizeof(*best_clock)); |
834 | max_n = limit->n.max; | 891 | max_n = limit->n.max; |
835 | /* based on hardware requriment prefer smaller n to precision */ | 892 | for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { |
836 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { | 893 | /* based on hardware requriment prefer smaller n to precision */ |
837 | /* based on hardware requirment prefere larger m1,m2, p1 */ | 894 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { |
838 | for (clock.m1 = limit->m1.max; | 895 | /* based on hardware requirment prefere larger m1,m2 */ |
839 | clock.m1 >= limit->m1.min; clock.m1--) { | 896 | for (clock.m1 = limit->m1.max; |
840 | for (clock.m2 = limit->m2.max; | 897 | clock.m1 >= limit->m1.min; clock.m1--) { |
841 | clock.m2 >= limit->m2.min; clock.m2--) { | 898 | for (clock.m2 = limit->m2.max; |
842 | for (clock.p1 = limit->p1.max; | 899 | clock.m2 >= limit->m2.min; clock.m2--) { |
843 | clock.p1 >= limit->p1.min; clock.p1--) { | ||
844 | int this_err; | 900 | int this_err; |
845 | 901 | ||
846 | intel_clock(dev, refclk, &clock); | 902 | intel_clock(dev, refclk, &clock); |
@@ -1030,8 +1086,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1030 | 1086 | ||
1031 | if (old_fb) { | 1087 | if (old_fb) { |
1032 | intel_fb = to_intel_framebuffer(old_fb); | 1088 | intel_fb = to_intel_framebuffer(old_fb); |
1089 | obj_priv = intel_fb->obj->driver_private; | ||
1033 | i915_gem_object_unpin(intel_fb->obj); | 1090 | i915_gem_object_unpin(intel_fb->obj); |
1034 | } | 1091 | } |
1092 | intel_increase_pllclock(crtc, true); | ||
1093 | |||
1035 | mutex_unlock(&dev->struct_mutex); | 1094 | mutex_unlock(&dev->struct_mutex); |
1036 | 1095 | ||
1037 | if (!dev->primary->master) | 1096 | if (!dev->primary->master) |
@@ -2054,6 +2113,18 @@ static int intel_get_fifo_size(struct drm_device *dev, int plane) | |||
2054 | return size; | 2113 | return size; |
2055 | } | 2114 | } |
2056 | 2115 | ||
2116 | static void g4x_update_wm(struct drm_device *dev) | ||
2117 | { | ||
2118 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2119 | u32 fw_blc_self = I915_READ(FW_BLC_SELF); | ||
2120 | |||
2121 | if (i915_powersave) | ||
2122 | fw_blc_self |= FW_BLC_SELF_EN; | ||
2123 | else | ||
2124 | fw_blc_self &= ~FW_BLC_SELF_EN; | ||
2125 | I915_WRITE(FW_BLC_SELF, fw_blc_self); | ||
2126 | } | ||
2127 | |||
2057 | static void i965_update_wm(struct drm_device *dev) | 2128 | static void i965_update_wm(struct drm_device *dev) |
2058 | { | 2129 | { |
2059 | struct drm_i915_private *dev_priv = dev->dev_private; | 2130 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -2105,7 +2176,8 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
2105 | cwm = 2; | 2176 | cwm = 2; |
2106 | 2177 | ||
2107 | /* Calc sr entries for one plane configs */ | 2178 | /* Calc sr entries for one plane configs */ |
2108 | if (sr_hdisplay && (!planea_clock || !planeb_clock)) { | 2179 | if (HAS_FW_BLC(dev) && sr_hdisplay && |
2180 | (!planea_clock || !planeb_clock)) { | ||
2109 | /* self-refresh has much higher latency */ | 2181 | /* self-refresh has much higher latency */ |
2110 | const static int sr_latency_ns = 6000; | 2182 | const static int sr_latency_ns = 6000; |
2111 | 2183 | ||
@@ -2120,8 +2192,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
2120 | srwm = total_size - sr_entries; | 2192 | srwm = total_size - sr_entries; |
2121 | if (srwm < 0) | 2193 | if (srwm < 0) |
2122 | srwm = 1; | 2194 | srwm = 1; |
2123 | if (IS_I9XX(dev)) | 2195 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f)); |
2124 | I915_WRITE(FW_BLC_SELF, (srwm & 0x3f)); | ||
2125 | } | 2196 | } |
2126 | 2197 | ||
2127 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | 2198 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", |
@@ -2195,9 +2266,6 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
2195 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | 2266 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; |
2196 | int enabled = 0, pixel_size = 0; | 2267 | int enabled = 0, pixel_size = 0; |
2197 | 2268 | ||
2198 | if (DSPARB_HWCONTROL(dev)) | ||
2199 | return; | ||
2200 | |||
2201 | /* Get the clock config from both planes */ | 2269 | /* Get the clock config from both planes */ |
2202 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 2270 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
2203 | intel_crtc = to_intel_crtc(crtc); | 2271 | intel_crtc = to_intel_crtc(crtc); |
@@ -2230,7 +2298,9 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
2230 | else if (IS_IGD(dev)) | 2298 | else if (IS_IGD(dev)) |
2231 | igd_disable_cxsr(dev); | 2299 | igd_disable_cxsr(dev); |
2232 | 2300 | ||
2233 | if (IS_I965G(dev)) | 2301 | if (IS_G4X(dev)) |
2302 | g4x_update_wm(dev); | ||
2303 | else if (IS_I965G(dev)) | ||
2234 | i965_update_wm(dev); | 2304 | i965_update_wm(dev); |
2235 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) | 2305 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) |
2236 | i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, | 2306 | i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, |
@@ -2264,9 +2334,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2264 | int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; | 2334 | int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; |
2265 | int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; | 2335 | int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; |
2266 | int refclk, num_outputs = 0; | 2336 | int refclk, num_outputs = 0; |
2267 | intel_clock_t clock; | 2337 | intel_clock_t clock, reduced_clock; |
2268 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; | 2338 | u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; |
2269 | bool ok, is_sdvo = false, is_dvo = false; | 2339 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; |
2270 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 2340 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
2271 | bool is_edp = false; | 2341 | bool is_edp = false; |
2272 | struct drm_mode_config *mode_config = &dev->mode_config; | 2342 | struct drm_mode_config *mode_config = &dev->mode_config; |
@@ -2349,6 +2419,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2349 | return -EINVAL; | 2419 | return -EINVAL; |
2350 | } | 2420 | } |
2351 | 2421 | ||
2422 | if (limit->find_reduced_pll && dev_priv->lvds_downclock_avail) { | ||
2423 | memcpy(&reduced_clock, &clock, sizeof(intel_clock_t)); | ||
2424 | has_reduced_clock = limit->find_reduced_pll(limit, crtc, | ||
2425 | (adjusted_mode->clock*3/4), | ||
2426 | refclk, | ||
2427 | &reduced_clock); | ||
2428 | } | ||
2429 | |||
2352 | /* SDVO TV has fixed PLL values depend on its clock range, | 2430 | /* SDVO TV has fixed PLL values depend on its clock range, |
2353 | this mirrors vbios setting. */ | 2431 | this mirrors vbios setting. */ |
2354 | if (is_sdvo && is_tv) { | 2432 | if (is_sdvo && is_tv) { |
@@ -2394,10 +2472,17 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2394 | link_bw, &m_n); | 2472 | link_bw, &m_n); |
2395 | } | 2473 | } |
2396 | 2474 | ||
2397 | if (IS_IGD(dev)) | 2475 | if (IS_IGD(dev)) { |
2398 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; | 2476 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; |
2399 | else | 2477 | if (has_reduced_clock) |
2478 | fp2 = (1 << reduced_clock.n) << 16 | | ||
2479 | reduced_clock.m1 << 8 | reduced_clock.m2; | ||
2480 | } else { | ||
2400 | fp = clock.n << 16 | clock.m1 << 8 | clock.m2; | 2481 | fp = clock.n << 16 | clock.m1 << 8 | clock.m2; |
2482 | if (has_reduced_clock) | ||
2483 | fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | | ||
2484 | reduced_clock.m2; | ||
2485 | } | ||
2401 | 2486 | ||
2402 | if (!IS_IGDNG(dev)) | 2487 | if (!IS_IGDNG(dev)) |
2403 | dpll = DPLL_VGA_MODE_DIS; | 2488 | dpll = DPLL_VGA_MODE_DIS; |
@@ -2426,6 +2511,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2426 | /* also FPA1 */ | 2511 | /* also FPA1 */ |
2427 | if (IS_IGDNG(dev)) | 2512 | if (IS_IGDNG(dev)) |
2428 | dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; | 2513 | dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; |
2514 | if (IS_G4X(dev) && has_reduced_clock) | ||
2515 | dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; | ||
2429 | } | 2516 | } |
2430 | switch (clock.p2) { | 2517 | switch (clock.p2) { |
2431 | case 5: | 2518 | case 5: |
@@ -2573,6 +2660,22 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2573 | udelay(150); | 2660 | udelay(150); |
2574 | } | 2661 | } |
2575 | 2662 | ||
2663 | if (is_lvds && has_reduced_clock && i915_powersave) { | ||
2664 | I915_WRITE(fp_reg + 4, fp2); | ||
2665 | intel_crtc->lowfreq_avail = true; | ||
2666 | if (HAS_PIPE_CXSR(dev)) { | ||
2667 | DRM_DEBUG("enabling CxSR downclocking\n"); | ||
2668 | pipeconf |= PIPECONF_CXSR_DOWNCLOCK; | ||
2669 | } | ||
2670 | } else { | ||
2671 | I915_WRITE(fp_reg + 4, fp); | ||
2672 | intel_crtc->lowfreq_avail = false; | ||
2673 | if (HAS_PIPE_CXSR(dev)) { | ||
2674 | DRM_DEBUG("disabling CxSR downclocking\n"); | ||
2675 | pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; | ||
2676 | } | ||
2677 | } | ||
2678 | |||
2576 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | | 2679 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | |
2577 | ((adjusted_mode->crtc_htotal - 1) << 16)); | 2680 | ((adjusted_mode->crtc_htotal - 1) << 16)); |
2578 | I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | | 2681 | I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | |
@@ -2769,10 +2872,16 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
2769 | struct drm_device *dev = crtc->dev; | 2872 | struct drm_device *dev = crtc->dev; |
2770 | struct drm_i915_private *dev_priv = dev->dev_private; | 2873 | struct drm_i915_private *dev_priv = dev->dev_private; |
2771 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 2874 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2875 | struct intel_framebuffer *intel_fb; | ||
2772 | int pipe = intel_crtc->pipe; | 2876 | int pipe = intel_crtc->pipe; |
2773 | uint32_t temp = 0; | 2877 | uint32_t temp = 0; |
2774 | uint32_t adder; | 2878 | uint32_t adder; |
2775 | 2879 | ||
2880 | if (crtc->fb) { | ||
2881 | intel_fb = to_intel_framebuffer(crtc->fb); | ||
2882 | intel_mark_busy(dev, intel_fb->obj); | ||
2883 | } | ||
2884 | |||
2776 | if (x < 0) { | 2885 | if (x < 0) { |
2777 | temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; | 2886 | temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; |
2778 | x = -x; | 2887 | x = -x; |
@@ -3070,6 +3179,312 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | |||
3070 | return mode; | 3179 | return mode; |
3071 | } | 3180 | } |
3072 | 3181 | ||
3182 | #define GPU_IDLE_TIMEOUT 500 /* ms */ | ||
3183 | |||
3184 | /* When this timer fires, we've been idle for awhile */ | ||
3185 | static void intel_gpu_idle_timer(unsigned long arg) | ||
3186 | { | ||
3187 | struct drm_device *dev = (struct drm_device *)arg; | ||
3188 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3189 | |||
3190 | DRM_DEBUG("idle timer fired, downclocking\n"); | ||
3191 | |||
3192 | dev_priv->busy = false; | ||
3193 | |||
3194 | schedule_work(&dev_priv->idle_work); | ||
3195 | } | ||
3196 | |||
3197 | void intel_increase_renderclock(struct drm_device *dev, bool schedule) | ||
3198 | { | ||
3199 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3200 | |||
3201 | if (IS_IGDNG(dev)) | ||
3202 | return; | ||
3203 | |||
3204 | if (!dev_priv->render_reclock_avail) { | ||
3205 | DRM_ERROR("not reclocking render clock\n"); | ||
3206 | return; | ||
3207 | } | ||
3208 | |||
3209 | /* Restore render clock frequency to original value */ | ||
3210 | if (IS_G4X(dev) || IS_I9XX(dev)) | ||
3211 | pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock); | ||
3212 | else if (IS_I85X(dev)) | ||
3213 | pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock); | ||
3214 | DRM_DEBUG("increasing render clock frequency\n"); | ||
3215 | |||
3216 | /* Schedule downclock */ | ||
3217 | if (schedule) | ||
3218 | mod_timer(&dev_priv->idle_timer, jiffies + | ||
3219 | msecs_to_jiffies(GPU_IDLE_TIMEOUT)); | ||
3220 | } | ||
3221 | |||
3222 | void intel_decrease_renderclock(struct drm_device *dev) | ||
3223 | { | ||
3224 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3225 | |||
3226 | if (IS_IGDNG(dev)) | ||
3227 | return; | ||
3228 | |||
3229 | if (!dev_priv->render_reclock_avail) { | ||
3230 | DRM_ERROR("not reclocking render clock\n"); | ||
3231 | return; | ||
3232 | } | ||
3233 | |||
3234 | if (IS_G4X(dev)) { | ||
3235 | u16 gcfgc; | ||
3236 | |||
3237 | /* Adjust render clock... */ | ||
3238 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3239 | |||
3240 | /* Down to minimum... */ | ||
3241 | gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK; | ||
3242 | gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ; | ||
3243 | |||
3244 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3245 | } else if (IS_I965G(dev)) { | ||
3246 | u16 gcfgc; | ||
3247 | |||
3248 | /* Adjust render clock... */ | ||
3249 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3250 | |||
3251 | /* Down to minimum... */ | ||
3252 | gcfgc &= ~I965_GC_RENDER_CLOCK_MASK; | ||
3253 | gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ; | ||
3254 | |||
3255 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3256 | } else if (IS_I945G(dev) || IS_I945GM(dev)) { | ||
3257 | u16 gcfgc; | ||
3258 | |||
3259 | /* Adjust render clock... */ | ||
3260 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3261 | |||
3262 | /* Down to minimum... */ | ||
3263 | gcfgc &= ~I945_GC_RENDER_CLOCK_MASK; | ||
3264 | gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ; | ||
3265 | |||
3266 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3267 | } else if (IS_I915G(dev)) { | ||
3268 | u16 gcfgc; | ||
3269 | |||
3270 | /* Adjust render clock... */ | ||
3271 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3272 | |||
3273 | /* Down to minimum... */ | ||
3274 | gcfgc &= ~I915_GC_RENDER_CLOCK_MASK; | ||
3275 | gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ; | ||
3276 | |||
3277 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3278 | } else if (IS_I85X(dev)) { | ||
3279 | u16 hpllcc; | ||
3280 | |||
3281 | /* Adjust render clock... */ | ||
3282 | pci_read_config_word(dev->pdev, HPLLCC, &hpllcc); | ||
3283 | |||
3284 | /* Up to maximum... */ | ||
3285 | hpllcc &= ~GC_CLOCK_CONTROL_MASK; | ||
3286 | hpllcc |= GC_CLOCK_133_200; | ||
3287 | |||
3288 | pci_write_config_word(dev->pdev, HPLLCC, hpllcc); | ||
3289 | } | ||
3290 | DRM_DEBUG("decreasing render clock frequency\n"); | ||
3291 | } | ||
3292 | |||
3293 | /* Note that no increase function is needed for this - increase_renderclock() | ||
3294 | * will also rewrite these bits | ||
3295 | */ | ||
3296 | void intel_decrease_displayclock(struct drm_device *dev) | ||
3297 | { | ||
3298 | if (IS_IGDNG(dev)) | ||
3299 | return; | ||
3300 | |||
3301 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) || | ||
3302 | IS_I915GM(dev)) { | ||
3303 | u16 gcfgc; | ||
3304 | |||
3305 | /* Adjust render clock... */ | ||
3306 | pci_read_config_word(dev->pdev, GCFGC, &gcfgc); | ||
3307 | |||
3308 | /* Down to minimum... */ | ||
3309 | gcfgc &= ~0xf0; | ||
3310 | gcfgc |= 0x80; | ||
3311 | |||
3312 | pci_write_config_word(dev->pdev, GCFGC, gcfgc); | ||
3313 | } | ||
3314 | } | ||
3315 | |||
3316 | #define CRTC_IDLE_TIMEOUT 1000 /* ms */ | ||
3317 | |||
3318 | static void intel_crtc_idle_timer(unsigned long arg) | ||
3319 | { | ||
3320 | struct intel_crtc *intel_crtc = (struct intel_crtc *)arg; | ||
3321 | struct drm_crtc *crtc = &intel_crtc->base; | ||
3322 | drm_i915_private_t *dev_priv = crtc->dev->dev_private; | ||
3323 | |||
3324 | DRM_DEBUG("idle timer fired, downclocking\n"); | ||
3325 | |||
3326 | intel_crtc->busy = false; | ||
3327 | |||
3328 | schedule_work(&dev_priv->idle_work); | ||
3329 | } | ||
3330 | |||
3331 | static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule) | ||
3332 | { | ||
3333 | struct drm_device *dev = crtc->dev; | ||
3334 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3335 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
3336 | int pipe = intel_crtc->pipe; | ||
3337 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | ||
3338 | int dpll = I915_READ(dpll_reg); | ||
3339 | |||
3340 | if (IS_IGDNG(dev)) | ||
3341 | return; | ||
3342 | |||
3343 | if (!dev_priv->lvds_downclock_avail) | ||
3344 | return; | ||
3345 | |||
3346 | if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) { | ||
3347 | DRM_DEBUG("upclocking LVDS\n"); | ||
3348 | |||
3349 | /* Unlock panel regs */ | ||
3350 | I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16)); | ||
3351 | |||
3352 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; | ||
3353 | I915_WRITE(dpll_reg, dpll); | ||
3354 | dpll = I915_READ(dpll_reg); | ||
3355 | intel_wait_for_vblank(dev); | ||
3356 | dpll = I915_READ(dpll_reg); | ||
3357 | if (dpll & DISPLAY_RATE_SELECT_FPA1) | ||
3358 | DRM_DEBUG("failed to upclock LVDS!\n"); | ||
3359 | |||
3360 | /* ...and lock them again */ | ||
3361 | I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3); | ||
3362 | } | ||
3363 | |||
3364 | /* Schedule downclock */ | ||
3365 | if (schedule) | ||
3366 | mod_timer(&intel_crtc->idle_timer, jiffies + | ||
3367 | msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); | ||
3368 | } | ||
3369 | |||
3370 | static void intel_decrease_pllclock(struct drm_crtc *crtc) | ||
3371 | { | ||
3372 | struct drm_device *dev = crtc->dev; | ||
3373 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3374 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
3375 | int pipe = intel_crtc->pipe; | ||
3376 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | ||
3377 | int dpll = I915_READ(dpll_reg); | ||
3378 | |||
3379 | if (IS_IGDNG(dev)) | ||
3380 | return; | ||
3381 | |||
3382 | if (!dev_priv->lvds_downclock_avail) | ||
3383 | return; | ||
3384 | |||
3385 | /* | ||
3386 | * Since this is called by a timer, we should never get here in | ||
3387 | * the manual case. | ||
3388 | */ | ||
3389 | if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { | ||
3390 | DRM_DEBUG("downclocking LVDS\n"); | ||
3391 | |||
3392 | /* Unlock panel regs */ | ||
3393 | I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16)); | ||
3394 | |||
3395 | dpll |= DISPLAY_RATE_SELECT_FPA1; | ||
3396 | I915_WRITE(dpll_reg, dpll); | ||
3397 | dpll = I915_READ(dpll_reg); | ||
3398 | intel_wait_for_vblank(dev); | ||
3399 | dpll = I915_READ(dpll_reg); | ||
3400 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) | ||
3401 | DRM_DEBUG("failed to downclock LVDS!\n"); | ||
3402 | |||
3403 | /* ...and lock them again */ | ||
3404 | I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3); | ||
3405 | } | ||
3406 | |||
3407 | } | ||
3408 | |||
3409 | /** | ||
3410 | * intel_idle_update - adjust clocks for idleness | ||
3411 | * @work: work struct | ||
3412 | * | ||
3413 | * Either the GPU or display (or both) went idle. Check the busy status | ||
3414 | * here and adjust the CRTC and GPU clocks as necessary. | ||
3415 | */ | ||
3416 | static void intel_idle_update(struct work_struct *work) | ||
3417 | { | ||
3418 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, | ||
3419 | idle_work); | ||
3420 | struct drm_device *dev = dev_priv->dev; | ||
3421 | struct drm_crtc *crtc; | ||
3422 | struct intel_crtc *intel_crtc; | ||
3423 | |||
3424 | if (!i915_powersave) | ||
3425 | return; | ||
3426 | |||
3427 | mutex_lock(&dev->struct_mutex); | ||
3428 | |||
3429 | /* GPU isn't processing, downclock it. */ | ||
3430 | if (!dev_priv->busy) { | ||
3431 | intel_decrease_renderclock(dev); | ||
3432 | intel_decrease_displayclock(dev); | ||
3433 | } | ||
3434 | |||
3435 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
3436 | /* Skip inactive CRTCs */ | ||
3437 | if (!crtc->fb) | ||
3438 | continue; | ||
3439 | |||
3440 | intel_crtc = to_intel_crtc(crtc); | ||
3441 | if (!intel_crtc->busy) | ||
3442 | intel_decrease_pllclock(crtc); | ||
3443 | } | ||
3444 | |||
3445 | mutex_unlock(&dev->struct_mutex); | ||
3446 | } | ||
3447 | |||
3448 | /** | ||
3449 | * intel_mark_busy - mark the GPU and possibly the display busy | ||
3450 | * @dev: drm device | ||
3451 | * @obj: object we're operating on | ||
3452 | * | ||
3453 | * Callers can use this function to indicate that the GPU is busy processing | ||
3454 | * commands. If @obj matches one of the CRTC objects (i.e. it's a scanout | ||
3455 | * buffer), we'll also mark the display as busy, so we know to increase its | ||
3456 | * clock frequency. | ||
3457 | */ | ||
3458 | void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj) | ||
3459 | { | ||
3460 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3461 | struct drm_crtc *crtc = NULL; | ||
3462 | struct intel_framebuffer *intel_fb; | ||
3463 | struct intel_crtc *intel_crtc; | ||
3464 | |||
3465 | dev_priv->busy = true; | ||
3466 | intel_increase_renderclock(dev, true); | ||
3467 | |||
3468 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
3469 | if (!crtc->fb) | ||
3470 | continue; | ||
3471 | |||
3472 | intel_crtc = to_intel_crtc(crtc); | ||
3473 | intel_fb = to_intel_framebuffer(crtc->fb); | ||
3474 | if (intel_fb->obj == obj) { | ||
3475 | if (!intel_crtc->busy) { | ||
3476 | /* Non-busy -> busy, upclock */ | ||
3477 | intel_increase_pllclock(crtc, true); | ||
3478 | intel_crtc->busy = true; | ||
3479 | } else { | ||
3480 | /* Busy -> busy, put off timer */ | ||
3481 | mod_timer(&intel_crtc->idle_timer, jiffies + | ||
3482 | msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); | ||
3483 | } | ||
3484 | } | ||
3485 | } | ||
3486 | } | ||
3487 | |||
3073 | static void intel_crtc_destroy(struct drm_crtc *crtc) | 3488 | static void intel_crtc_destroy(struct drm_crtc *crtc) |
3074 | { | 3489 | { |
3075 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3490 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
@@ -3125,6 +3540,10 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
3125 | intel_crtc->mode_set.crtc = &intel_crtc->base; | 3540 | intel_crtc->mode_set.crtc = &intel_crtc->base; |
3126 | intel_crtc->mode_set.connectors = (struct drm_connector **)(intel_crtc + 1); | 3541 | intel_crtc->mode_set.connectors = (struct drm_connector **)(intel_crtc + 1); |
3127 | intel_crtc->mode_set.num_connectors = 0; | 3542 | intel_crtc->mode_set.num_connectors = 0; |
3543 | intel_crtc->busy = false; | ||
3544 | |||
3545 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, | ||
3546 | (unsigned long)intel_crtc); | ||
3128 | 3547 | ||
3129 | if (i915_fbpercrtc) { | 3548 | if (i915_fbpercrtc) { |
3130 | 3549 | ||
@@ -3362,8 +3781,56 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { | |||
3362 | .fb_changed = intelfb_probe, | 3781 | .fb_changed = intelfb_probe, |
3363 | }; | 3782 | }; |
3364 | 3783 | ||
3784 | void intel_init_clock_gating(struct drm_device *dev) | ||
3785 | { | ||
3786 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3787 | |||
3788 | /* | ||
3789 | * Disable clock gating reported to work incorrectly according to the | ||
3790 | * specs, but enable as much else as we can. | ||
3791 | */ | ||
3792 | if (IS_G4X(dev)) { | ||
3793 | uint32_t dspclk_gate; | ||
3794 | I915_WRITE(RENCLK_GATE_D1, 0); | ||
3795 | I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | | ||
3796 | GS_UNIT_CLOCK_GATE_DISABLE | | ||
3797 | CL_UNIT_CLOCK_GATE_DISABLE); | ||
3798 | I915_WRITE(RAMCLK_GATE_D, 0); | ||
3799 | dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | | ||
3800 | OVRUNIT_CLOCK_GATE_DISABLE | | ||
3801 | OVCUNIT_CLOCK_GATE_DISABLE; | ||
3802 | if (IS_GM45(dev)) | ||
3803 | dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; | ||
3804 | I915_WRITE(DSPCLK_GATE_D, dspclk_gate); | ||
3805 | } else if (IS_I965GM(dev)) { | ||
3806 | I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); | ||
3807 | I915_WRITE(RENCLK_GATE_D2, 0); | ||
3808 | I915_WRITE(DSPCLK_GATE_D, 0); | ||
3809 | I915_WRITE(RAMCLK_GATE_D, 0); | ||
3810 | I915_WRITE16(DEUC, 0); | ||
3811 | } else if (IS_I965G(dev)) { | ||
3812 | I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | | ||
3813 | I965_RCC_CLOCK_GATE_DISABLE | | ||
3814 | I965_RCPB_CLOCK_GATE_DISABLE | | ||
3815 | I965_ISC_CLOCK_GATE_DISABLE | | ||
3816 | I965_FBC_CLOCK_GATE_DISABLE); | ||
3817 | I915_WRITE(RENCLK_GATE_D2, 0); | ||
3818 | } else if (IS_I9XX(dev)) { | ||
3819 | u32 dstate = I915_READ(D_STATE); | ||
3820 | |||
3821 | dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | | ||
3822 | DSTATE_DOT_CLOCK_GATING; | ||
3823 | I915_WRITE(D_STATE, dstate); | ||
3824 | } else if (IS_I855(dev) || IS_I865G(dev)) { | ||
3825 | I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); | ||
3826 | } else if (IS_I830(dev)) { | ||
3827 | I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); | ||
3828 | } | ||
3829 | } | ||
3830 | |||
3365 | void intel_modeset_init(struct drm_device *dev) | 3831 | void intel_modeset_init(struct drm_device *dev) |
3366 | { | 3832 | { |
3833 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3367 | int num_pipe; | 3834 | int num_pipe; |
3368 | int i; | 3835 | int i; |
3369 | 3836 | ||
@@ -3398,15 +3865,47 @@ void intel_modeset_init(struct drm_device *dev) | |||
3398 | DRM_DEBUG("%d display pipe%s available.\n", | 3865 | DRM_DEBUG("%d display pipe%s available.\n", |
3399 | num_pipe, num_pipe > 1 ? "s" : ""); | 3866 | num_pipe, num_pipe > 1 ? "s" : ""); |
3400 | 3867 | ||
3868 | if (IS_I85X(dev)) | ||
3869 | pci_read_config_word(dev->pdev, HPLLCC, &dev_priv->orig_clock); | ||
3870 | else if (IS_I9XX(dev) || IS_G4X(dev)) | ||
3871 | pci_read_config_word(dev->pdev, GCFGC, &dev_priv->orig_clock); | ||
3872 | |||
3401 | for (i = 0; i < num_pipe; i++) { | 3873 | for (i = 0; i < num_pipe; i++) { |
3402 | intel_crtc_init(dev, i); | 3874 | intel_crtc_init(dev, i); |
3403 | } | 3875 | } |
3404 | 3876 | ||
3405 | intel_setup_outputs(dev); | 3877 | intel_setup_outputs(dev); |
3878 | |||
3879 | intel_init_clock_gating(dev); | ||
3880 | |||
3881 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); | ||
3882 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, | ||
3883 | (unsigned long)dev); | ||
3406 | } | 3884 | } |
3407 | 3885 | ||
3408 | void intel_modeset_cleanup(struct drm_device *dev) | 3886 | void intel_modeset_cleanup(struct drm_device *dev) |
3409 | { | 3887 | { |
3888 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3889 | struct drm_crtc *crtc; | ||
3890 | struct intel_crtc *intel_crtc; | ||
3891 | |||
3892 | mutex_lock(&dev->struct_mutex); | ||
3893 | |||
3894 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
3895 | /* Skip inactive CRTCs */ | ||
3896 | if (!crtc->fb) | ||
3897 | continue; | ||
3898 | |||
3899 | intel_crtc = to_intel_crtc(crtc); | ||
3900 | intel_increase_pllclock(crtc, false); | ||
3901 | del_timer_sync(&intel_crtc->idle_timer); | ||
3902 | } | ||
3903 | |||
3904 | intel_increase_renderclock(dev, false); | ||
3905 | del_timer_sync(&dev_priv->idle_timer); | ||
3906 | |||
3907 | mutex_unlock(&dev->struct_mutex); | ||
3908 | |||
3410 | drm_mode_config_cleanup(dev); | 3909 | drm_mode_config_cleanup(dev); |
3411 | } | 3910 | } |
3412 | 3911 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 25aa6facc12d..495dc955d045 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -119,6 +119,9 @@ struct intel_crtc { | |||
119 | struct intel_framebuffer *fbdev_fb; | 119 | struct intel_framebuffer *fbdev_fb; |
120 | /* a mode_set for fbdev users on this crtc */ | 120 | /* a mode_set for fbdev users on this crtc */ |
121 | struct drm_mode_set mode_set; | 121 | struct drm_mode_set mode_set; |
122 | bool busy; /* is scanout buffer being updated frequently? */ | ||
123 | struct timer_list idle_timer; | ||
124 | bool lowfreq_avail; | ||
122 | }; | 125 | }; |
123 | 126 | ||
124 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) | 127 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) |
@@ -137,6 +140,7 @@ extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); | |||
137 | extern bool intel_sdvo_init(struct drm_device *dev, int output_device); | 140 | extern bool intel_sdvo_init(struct drm_device *dev, int output_device); |
138 | extern void intel_dvo_init(struct drm_device *dev); | 141 | extern void intel_dvo_init(struct drm_device *dev); |
139 | extern void intel_tv_init(struct drm_device *dev); | 142 | extern void intel_tv_init(struct drm_device *dev); |
143 | extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj); | ||
140 | extern void intel_lvds_init(struct drm_device *dev); | 144 | extern void intel_lvds_init(struct drm_device *dev); |
141 | extern void intel_dp_init(struct drm_device *dev, int dp_reg); | 145 | extern void intel_dp_init(struct drm_device *dev, int dp_reg); |
142 | void | 146 | void |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 62b8bead7652..c7eab724c418 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -42,11 +42,11 @@ void intel_i2c_quirk_set(struct drm_device *dev, bool enable) | |||
42 | if (!IS_IGD(dev)) | 42 | if (!IS_IGD(dev)) |
43 | return; | 43 | return; |
44 | if (enable) | 44 | if (enable) |
45 | I915_WRITE(CG_2D_DIS, | 45 | I915_WRITE(DSPCLK_GATE_D, |
46 | I915_READ(CG_2D_DIS) | DPCUNIT_CLOCK_GATE_DISABLE); | 46 | I915_READ(DSPCLK_GATE_D) | DPCUNIT_CLOCK_GATE_DISABLE); |
47 | else | 47 | else |
48 | I915_WRITE(CG_2D_DIS, | 48 | I915_WRITE(DSPCLK_GATE_D, |
49 | I915_READ(CG_2D_DIS) & (~DPCUNIT_CLOCK_GATE_DISABLE)); | 49 | I915_READ(DSPCLK_GATE_D) & (~DPCUNIT_CLOCK_GATE_DISABLE)); |
50 | } | 50 | } |
51 | 51 | ||
52 | /* | 52 | /* |