diff options
Diffstat (limited to 'drivers')
62 files changed, 4355 insertions, 4414 deletions
diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile index 627f542827c7..8eb56e273e75 100644 --- a/drivers/char/agp/Makefile +++ b/drivers/char/agp/Makefile | |||
@@ -13,6 +13,7 @@ obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o | |||
13 | obj-$(CONFIG_AGP_PARISC) += parisc-agp.o | 13 | obj-$(CONFIG_AGP_PARISC) += parisc-agp.o |
14 | obj-$(CONFIG_AGP_I460) += i460-agp.o | 14 | obj-$(CONFIG_AGP_I460) += i460-agp.o |
15 | obj-$(CONFIG_AGP_INTEL) += intel-agp.o | 15 | obj-$(CONFIG_AGP_INTEL) += intel-agp.o |
16 | obj-$(CONFIG_AGP_INTEL) += intel-gtt.o | ||
16 | obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o | 17 | obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o |
17 | obj-$(CONFIG_AGP_SGI_TIOCA) += sgi-agp.o | 18 | obj-$(CONFIG_AGP_SGI_TIOCA) += sgi-agp.o |
18 | obj-$(CONFIG_AGP_SIS) += sis-agp.o | 19 | obj-$(CONFIG_AGP_SIS) += sis-agp.o |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index cd18493c9527..5cd2221ab472 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -12,9 +12,6 @@ | |||
12 | #include <asm/smp.h> | 12 | #include <asm/smp.h> |
13 | #include "agp.h" | 13 | #include "agp.h" |
14 | #include "intel-agp.h" | 14 | #include "intel-agp.h" |
15 | #include <linux/intel-gtt.h> | ||
16 | |||
17 | #include "intel-gtt.c" | ||
18 | 15 | ||
19 | int intel_agp_enabled; | 16 | int intel_agp_enabled; |
20 | EXPORT_SYMBOL(intel_agp_enabled); | 17 | EXPORT_SYMBOL(intel_agp_enabled); |
@@ -703,179 +700,37 @@ static const struct agp_bridge_driver intel_7505_driver = { | |||
703 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 700 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
704 | }; | 701 | }; |
705 | 702 | ||
706 | static int find_gmch(u16 device) | ||
707 | { | ||
708 | struct pci_dev *gmch_device; | ||
709 | |||
710 | gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL); | ||
711 | if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) { | ||
712 | gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
713 | device, gmch_device); | ||
714 | } | ||
715 | |||
716 | if (!gmch_device) | ||
717 | return 0; | ||
718 | |||
719 | intel_private.pcidev = gmch_device; | ||
720 | return 1; | ||
721 | } | ||
722 | |||
723 | /* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of | 703 | /* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of |
724 | * driver and gmch_driver must be non-null, and find_gmch will determine | 704 | * driver and gmch_driver must be non-null, and find_gmch will determine |
725 | * which one should be used if a gmch_chip_id is present. | 705 | * which one should be used if a gmch_chip_id is present. |
726 | */ | 706 | */ |
727 | static const struct intel_driver_description { | 707 | static const struct intel_agp_driver_description { |
728 | unsigned int chip_id; | 708 | unsigned int chip_id; |
729 | unsigned int gmch_chip_id; | ||
730 | char *name; | 709 | char *name; |
731 | const struct agp_bridge_driver *driver; | 710 | const struct agp_bridge_driver *driver; |
732 | const struct agp_bridge_driver *gmch_driver; | ||
733 | } intel_agp_chipsets[] = { | 711 | } intel_agp_chipsets[] = { |
734 | { PCI_DEVICE_ID_INTEL_82443LX_0, 0, "440LX", &intel_generic_driver, NULL }, | 712 | { PCI_DEVICE_ID_INTEL_82443LX_0, "440LX", &intel_generic_driver }, |
735 | { PCI_DEVICE_ID_INTEL_82443BX_0, 0, "440BX", &intel_generic_driver, NULL }, | 713 | { PCI_DEVICE_ID_INTEL_82443BX_0, "440BX", &intel_generic_driver }, |
736 | { PCI_DEVICE_ID_INTEL_82443GX_0, 0, "440GX", &intel_generic_driver, NULL }, | 714 | { PCI_DEVICE_ID_INTEL_82443GX_0, "440GX", &intel_generic_driver }, |
737 | { PCI_DEVICE_ID_INTEL_82810_MC1, PCI_DEVICE_ID_INTEL_82810_IG1, "i810", | 715 | { PCI_DEVICE_ID_INTEL_82815_MC, "i815", &intel_815_driver }, |
738 | NULL, &intel_810_driver }, | 716 | { PCI_DEVICE_ID_INTEL_82820_HB, "i820", &intel_820_driver }, |
739 | { PCI_DEVICE_ID_INTEL_82810_MC3, PCI_DEVICE_ID_INTEL_82810_IG3, "i810", | 717 | { PCI_DEVICE_ID_INTEL_82820_UP_HB, "i820", &intel_820_driver }, |
740 | NULL, &intel_810_driver }, | 718 | { PCI_DEVICE_ID_INTEL_82830_HB, "830M", &intel_830mp_driver }, |
741 | { PCI_DEVICE_ID_INTEL_82810E_MC, PCI_DEVICE_ID_INTEL_82810E_IG, "i810", | 719 | { PCI_DEVICE_ID_INTEL_82840_HB, "i840", &intel_840_driver }, |
742 | NULL, &intel_810_driver }, | 720 | { PCI_DEVICE_ID_INTEL_82845_HB, "845G", &intel_845_driver }, |
743 | { PCI_DEVICE_ID_INTEL_82815_MC, PCI_DEVICE_ID_INTEL_82815_CGC, "i815", | 721 | { PCI_DEVICE_ID_INTEL_82845G_HB, "830M", &intel_845_driver }, |
744 | &intel_815_driver, &intel_810_driver }, | 722 | { PCI_DEVICE_ID_INTEL_82850_HB, "i850", &intel_850_driver }, |
745 | { PCI_DEVICE_ID_INTEL_82820_HB, 0, "i820", &intel_820_driver, NULL }, | 723 | { PCI_DEVICE_ID_INTEL_82854_HB, "854", &intel_845_driver }, |
746 | { PCI_DEVICE_ID_INTEL_82820_UP_HB, 0, "i820", &intel_820_driver, NULL }, | 724 | { PCI_DEVICE_ID_INTEL_82855PM_HB, "855PM", &intel_845_driver }, |
747 | { PCI_DEVICE_ID_INTEL_82830_HB, PCI_DEVICE_ID_INTEL_82830_CGC, "830M", | 725 | { PCI_DEVICE_ID_INTEL_82855GM_HB, "855GM", &intel_845_driver }, |
748 | &intel_830mp_driver, &intel_830_driver }, | 726 | { PCI_DEVICE_ID_INTEL_82860_HB, "i860", &intel_860_driver }, |
749 | { PCI_DEVICE_ID_INTEL_82840_HB, 0, "i840", &intel_840_driver, NULL }, | 727 | { PCI_DEVICE_ID_INTEL_82865_HB, "865", &intel_845_driver }, |
750 | { PCI_DEVICE_ID_INTEL_82845_HB, 0, "845G", &intel_845_driver, NULL }, | 728 | { PCI_DEVICE_ID_INTEL_82875_HB, "i875", &intel_845_driver }, |
751 | { PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, "830M", | 729 | { PCI_DEVICE_ID_INTEL_7505_0, "E7505", &intel_7505_driver }, |
752 | &intel_845_driver, &intel_830_driver }, | 730 | { PCI_DEVICE_ID_INTEL_7205_0, "E7205", &intel_7505_driver }, |
753 | { PCI_DEVICE_ID_INTEL_82850_HB, 0, "i850", &intel_850_driver, NULL }, | 731 | { 0, NULL, NULL } |
754 | { PCI_DEVICE_ID_INTEL_82854_HB, PCI_DEVICE_ID_INTEL_82854_IG, "854", | ||
755 | &intel_845_driver, &intel_830_driver }, | ||
756 | { PCI_DEVICE_ID_INTEL_82855PM_HB, 0, "855PM", &intel_845_driver, NULL }, | ||
757 | { PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, "855GM", | ||
758 | &intel_845_driver, &intel_830_driver }, | ||
759 | { PCI_DEVICE_ID_INTEL_82860_HB, 0, "i860", &intel_860_driver, NULL }, | ||
760 | { PCI_DEVICE_ID_INTEL_82865_HB, PCI_DEVICE_ID_INTEL_82865_IG, "865", | ||
761 | &intel_845_driver, &intel_830_driver }, | ||
762 | { PCI_DEVICE_ID_INTEL_82875_HB, 0, "i875", &intel_845_driver, NULL }, | ||
763 | { PCI_DEVICE_ID_INTEL_E7221_HB, PCI_DEVICE_ID_INTEL_E7221_IG, "E7221 (i915)", | ||
764 | NULL, &intel_915_driver }, | ||
765 | { PCI_DEVICE_ID_INTEL_82915G_HB, PCI_DEVICE_ID_INTEL_82915G_IG, "915G", | ||
766 | NULL, &intel_915_driver }, | ||
767 | { PCI_DEVICE_ID_INTEL_82915GM_HB, PCI_DEVICE_ID_INTEL_82915GM_IG, "915GM", | ||
768 | NULL, &intel_915_driver }, | ||
769 | { PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, "945G", | ||
770 | NULL, &intel_915_driver }, | ||
771 | { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, "945GM", | ||
772 | NULL, &intel_915_driver }, | ||
773 | { PCI_DEVICE_ID_INTEL_82945GME_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, "945GME", | ||
774 | NULL, &intel_915_driver }, | ||
775 | { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, "946GZ", | ||
776 | NULL, &intel_i965_driver }, | ||
777 | { PCI_DEVICE_ID_INTEL_82G35_HB, PCI_DEVICE_ID_INTEL_82G35_IG, "G35", | ||
778 | NULL, &intel_i965_driver }, | ||
779 | { PCI_DEVICE_ID_INTEL_82965Q_HB, PCI_DEVICE_ID_INTEL_82965Q_IG, "965Q", | ||
780 | NULL, &intel_i965_driver }, | ||
781 | { PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, "965G", | ||
782 | NULL, &intel_i965_driver }, | ||
783 | { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, "965GM", | ||
784 | NULL, &intel_i965_driver }, | ||
785 | { PCI_DEVICE_ID_INTEL_82965GME_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, "965GME/GLE", | ||
786 | NULL, &intel_i965_driver }, | ||
787 | { PCI_DEVICE_ID_INTEL_7505_0, 0, "E7505", &intel_7505_driver, NULL }, | ||
788 | { PCI_DEVICE_ID_INTEL_7205_0, 0, "E7205", &intel_7505_driver, NULL }, | ||
789 | { PCI_DEVICE_ID_INTEL_G33_HB, PCI_DEVICE_ID_INTEL_G33_IG, "G33", | ||
790 | NULL, &intel_g33_driver }, | ||
791 | { PCI_DEVICE_ID_INTEL_Q35_HB, PCI_DEVICE_ID_INTEL_Q35_IG, "Q35", | ||
792 | NULL, &intel_g33_driver }, | ||
793 | { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, "Q33", | ||
794 | NULL, &intel_g33_driver }, | ||
795 | { PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, "GMA3150", | ||
796 | NULL, &intel_g33_driver }, | ||
797 | { PCI_DEVICE_ID_INTEL_PINEVIEW_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_IG, "GMA3150", | ||
798 | NULL, &intel_g33_driver }, | ||
799 | { PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, | ||
800 | "GM45", NULL, &intel_i965_driver }, | ||
801 | { PCI_DEVICE_ID_INTEL_EAGLELAKE_HB, PCI_DEVICE_ID_INTEL_EAGLELAKE_IG, | ||
802 | "Eaglelake", NULL, &intel_i965_driver }, | ||
803 | { PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, | ||
804 | "Q45/Q43", NULL, &intel_i965_driver }, | ||
805 | { PCI_DEVICE_ID_INTEL_G45_HB, PCI_DEVICE_ID_INTEL_G45_IG, | ||
806 | "G45/G43", NULL, &intel_i965_driver }, | ||
807 | { PCI_DEVICE_ID_INTEL_B43_HB, PCI_DEVICE_ID_INTEL_B43_IG, | ||
808 | "B43", NULL, &intel_i965_driver }, | ||
809 | { PCI_DEVICE_ID_INTEL_B43_1_HB, PCI_DEVICE_ID_INTEL_B43_1_IG, | ||
810 | "B43", NULL, &intel_i965_driver }, | ||
811 | { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, | ||
812 | "G41", NULL, &intel_i965_driver }, | ||
813 | { PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, | ||
814 | "HD Graphics", NULL, &intel_i965_driver }, | ||
815 | { PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, | ||
816 | "HD Graphics", NULL, &intel_i965_driver }, | ||
817 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, | ||
818 | "HD Graphics", NULL, &intel_i965_driver }, | ||
819 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, | ||
820 | "HD Graphics", NULL, &intel_i965_driver }, | ||
821 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG, | ||
822 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
823 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG, | ||
824 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
825 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG, | ||
826 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
827 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG, | ||
828 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
829 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG, | ||
830 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
831 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG, | ||
832 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
833 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG, | ||
834 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
835 | { 0, 0, NULL, NULL, NULL } | ||
836 | }; | 732 | }; |
837 | 733 | ||
838 | static int __devinit intel_gmch_probe(struct pci_dev *pdev, | ||
839 | struct agp_bridge_data *bridge) | ||
840 | { | ||
841 | int i, mask; | ||
842 | |||
843 | bridge->driver = NULL; | ||
844 | |||
845 | for (i = 0; intel_agp_chipsets[i].name != NULL; i++) { | ||
846 | if ((intel_agp_chipsets[i].gmch_chip_id != 0) && | ||
847 | find_gmch(intel_agp_chipsets[i].gmch_chip_id)) { | ||
848 | bridge->driver = | ||
849 | intel_agp_chipsets[i].gmch_driver; | ||
850 | break; | ||
851 | } | ||
852 | } | ||
853 | |||
854 | if (!bridge->driver) | ||
855 | return 0; | ||
856 | |||
857 | bridge->dev_private_data = &intel_private; | ||
858 | bridge->dev = pdev; | ||
859 | |||
860 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); | ||
861 | |||
862 | if (bridge->driver->mask_memory == intel_gen6_mask_memory) | ||
863 | mask = 40; | ||
864 | else if (bridge->driver->mask_memory == intel_i965_mask_memory) | ||
865 | mask = 36; | ||
866 | else | ||
867 | mask = 32; | ||
868 | |||
869 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask))) | ||
870 | dev_err(&intel_private.pcidev->dev, | ||
871 | "set gfx device dma mask %d-bit failed!\n", mask); | ||
872 | else | ||
873 | pci_set_consistent_dma_mask(intel_private.pcidev, | ||
874 | DMA_BIT_MASK(mask)); | ||
875 | |||
876 | return 1; | ||
877 | } | ||
878 | |||
879 | static int __devinit agp_intel_probe(struct pci_dev *pdev, | 734 | static int __devinit agp_intel_probe(struct pci_dev *pdev, |
880 | const struct pci_device_id *ent) | 735 | const struct pci_device_id *ent) |
881 | { | 736 | { |
@@ -905,7 +760,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
905 | } | 760 | } |
906 | } | 761 | } |
907 | 762 | ||
908 | if (intel_agp_chipsets[i].name == NULL) { | 763 | if (!bridge->driver) { |
909 | if (cap_ptr) | 764 | if (cap_ptr) |
910 | dev_warn(&pdev->dev, "unsupported Intel chipset [%04x/%04x]\n", | 765 | dev_warn(&pdev->dev, "unsupported Intel chipset [%04x/%04x]\n", |
911 | pdev->vendor, pdev->device); | 766 | pdev->vendor, pdev->device); |
@@ -913,14 +768,6 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
913 | return -ENODEV; | 768 | return -ENODEV; |
914 | } | 769 | } |
915 | 770 | ||
916 | if (!bridge->driver) { | ||
917 | if (cap_ptr) | ||
918 | dev_warn(&pdev->dev, "can't find bridge device (chip_id: %04x)\n", | ||
919 | intel_agp_chipsets[i].gmch_chip_id); | ||
920 | agp_put_bridge(bridge); | ||
921 | return -ENODEV; | ||
922 | } | ||
923 | |||
924 | bridge->dev = pdev; | 771 | bridge->dev = pdev; |
925 | bridge->dev_private_data = NULL; | 772 | bridge->dev_private_data = NULL; |
926 | 773 | ||
@@ -972,8 +819,7 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev) | |||
972 | 819 | ||
973 | agp_remove_bridge(bridge); | 820 | agp_remove_bridge(bridge); |
974 | 821 | ||
975 | if (intel_private.pcidev) | 822 | intel_gmch_remove(pdev); |
976 | pci_dev_put(intel_private.pcidev); | ||
977 | 823 | ||
978 | agp_put_bridge(bridge); | 824 | agp_put_bridge(bridge); |
979 | } | 825 | } |
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index d09b1ab7e8ab..90539df02504 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h | |||
@@ -215,44 +215,7 @@ | |||
215 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB 0x0108 /* Server */ | 215 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB 0x0108 /* Server */ |
216 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG 0x010A | 216 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG 0x010A |
217 | 217 | ||
218 | /* cover 915 and 945 variants */ | 218 | int intel_gmch_probe(struct pci_dev *pdev, |
219 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ | 219 | struct agp_bridge_data *bridge); |
220 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || \ | 220 | void intel_gmch_remove(struct pci_dev *pdev); |
221 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || \ | ||
222 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || \ | ||
223 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || \ | ||
224 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB) | ||
225 | |||
226 | #define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \ | ||
227 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82G35_HB || \ | ||
228 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ | ||
229 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ | ||
230 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ | ||
231 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB) | ||
232 | |||
233 | #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ | ||
234 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ | ||
235 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB || \ | ||
236 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \ | ||
237 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB) | ||
238 | |||
239 | #define IS_PINEVIEW (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \ | ||
240 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB) | ||
241 | |||
242 | #define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \ | ||
243 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB || \ | ||
244 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB) | ||
245 | |||
246 | #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \ | ||
247 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ | ||
248 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \ | ||
249 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \ | ||
250 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \ | ||
251 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \ | ||
252 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB || \ | ||
253 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \ | ||
254 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \ | ||
255 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \ | ||
256 | IS_SNB) | ||
257 | |||
258 | #endif | 221 | #endif |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 75e0a3497888..248ac5f8708e 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -15,6 +15,18 @@ | |||
15 | * /fairy-tale-mode off | 15 | * /fairy-tale-mode off |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/pagemap.h> | ||
23 | #include <linux/agp_backend.h> | ||
24 | #include <asm/smp.h> | ||
25 | #include "agp.h" | ||
26 | #include "intel-agp.h" | ||
27 | #include <linux/intel-gtt.h> | ||
28 | #include <drm/intel-gtt.h> | ||
29 | |||
18 | /* | 30 | /* |
19 | * If we have Intel graphics, we're not going to have anything other than | 31 | * If we have Intel graphics, we're not going to have anything other than |
20 | * an Intel IOMMU. So make the correct use of the PCI DMA API contingent | 32 | * an Intel IOMMU. So make the correct use of the PCI DMA API contingent |
@@ -69,18 +81,26 @@ static struct gatt_mask intel_gen6_masks[] = | |||
69 | .type = INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT }, | 81 | .type = INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT }, |
70 | }; | 82 | }; |
71 | 83 | ||
84 | struct intel_gtt_driver { | ||
85 | unsigned int gen : 8; | ||
86 | unsigned int is_g33 : 1; | ||
87 | unsigned int is_pineview : 1; | ||
88 | unsigned int is_ironlake : 1; | ||
89 | /* Chipset specific GTT setup */ | ||
90 | int (*setup)(void); | ||
91 | }; | ||
92 | |||
72 | static struct _intel_private { | 93 | static struct _intel_private { |
94 | struct intel_gtt base; | ||
95 | const struct intel_gtt_driver *driver; | ||
73 | struct pci_dev *pcidev; /* device one */ | 96 | struct pci_dev *pcidev; /* device one */ |
97 | struct pci_dev *bridge_dev; | ||
74 | u8 __iomem *registers; | 98 | u8 __iomem *registers; |
99 | phys_addr_t gtt_bus_addr; | ||
100 | phys_addr_t gma_bus_addr; | ||
101 | phys_addr_t pte_bus_addr; | ||
75 | u32 __iomem *gtt; /* I915G */ | 102 | u32 __iomem *gtt; /* I915G */ |
76 | int num_dcache_entries; | 103 | int num_dcache_entries; |
77 | /* gtt_entries is the number of gtt entries that are already mapped | ||
78 | * to stolen memory. Stolen memory is larger than the memory mapped | ||
79 | * through gtt_entries, as it includes some reserved space for the BIOS | ||
80 | * popup and for the GTT. | ||
81 | */ | ||
82 | int gtt_entries; /* i830+ */ | ||
83 | int gtt_total_size; | ||
84 | union { | 104 | union { |
85 | void __iomem *i9xx_flush_page; | 105 | void __iomem *i9xx_flush_page; |
86 | void *i8xx_flush_page; | 106 | void *i8xx_flush_page; |
@@ -90,6 +110,11 @@ static struct _intel_private { | |||
90 | int resource_valid; | 110 | int resource_valid; |
91 | } intel_private; | 111 | } intel_private; |
92 | 112 | ||
113 | #define INTEL_GTT_GEN intel_private.driver->gen | ||
114 | #define IS_G33 intel_private.driver->is_g33 | ||
115 | #define IS_PINEVIEW intel_private.driver->is_pineview | ||
116 | #define IS_IRONLAKE intel_private.driver->is_ironlake | ||
117 | |||
93 | #ifdef USE_PCI_DMA_API | 118 | #ifdef USE_PCI_DMA_API |
94 | static int intel_agp_map_page(struct page *page, dma_addr_t *ret) | 119 | static int intel_agp_map_page(struct page *page, dma_addr_t *ret) |
95 | { | 120 | { |
@@ -215,11 +240,12 @@ static int intel_i810_fetch_size(void) | |||
215 | u32 smram_miscc; | 240 | u32 smram_miscc; |
216 | struct aper_size_info_fixed *values; | 241 | struct aper_size_info_fixed *values; |
217 | 242 | ||
218 | pci_read_config_dword(agp_bridge->dev, I810_SMRAM_MISCC, &smram_miscc); | 243 | pci_read_config_dword(intel_private.bridge_dev, |
244 | I810_SMRAM_MISCC, &smram_miscc); | ||
219 | values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); | 245 | values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); |
220 | 246 | ||
221 | if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) { | 247 | if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) { |
222 | dev_warn(&agp_bridge->dev->dev, "i810 is disabled\n"); | 248 | dev_warn(&intel_private.bridge_dev->dev, "i810 is disabled\n"); |
223 | return 0; | 249 | return 0; |
224 | } | 250 | } |
225 | if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) { | 251 | if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) { |
@@ -284,7 +310,7 @@ static void intel_i810_cleanup(void) | |||
284 | iounmap(intel_private.registers); | 310 | iounmap(intel_private.registers); |
285 | } | 311 | } |
286 | 312 | ||
287 | static void intel_i810_agp_enable(struct agp_bridge_data *bridge, u32 mode) | 313 | static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode) |
288 | { | 314 | { |
289 | return; | 315 | return; |
290 | } | 316 | } |
@@ -514,8 +540,7 @@ static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge, | |||
514 | return addr | bridge->driver->masks[type].mask; | 540 | return addr | bridge->driver->masks[type].mask; |
515 | } | 541 | } |
516 | 542 | ||
517 | static struct aper_size_info_fixed intel_i830_sizes[] = | 543 | static const struct aper_size_info_fixed const intel_fake_agp_sizes[] = { |
518 | { | ||
519 | {128, 32768, 5}, | 544 | {128, 32768, 5}, |
520 | /* The 64M mode still requires a 128k gatt */ | 545 | /* The 64M mode still requires a 128k gatt */ |
521 | {64, 16384, 5}, | 546 | {64, 16384, 5}, |
@@ -523,102 +548,49 @@ static struct aper_size_info_fixed intel_i830_sizes[] = | |||
523 | {512, 131072, 7}, | 548 | {512, 131072, 7}, |
524 | }; | 549 | }; |
525 | 550 | ||
526 | static void intel_i830_init_gtt_entries(void) | 551 | static unsigned int intel_gtt_stolen_entries(void) |
527 | { | 552 | { |
528 | u16 gmch_ctrl; | 553 | u16 gmch_ctrl; |
529 | int gtt_entries = 0; | ||
530 | u8 rdct; | 554 | u8 rdct; |
531 | int local = 0; | 555 | int local = 0; |
532 | static const int ddt[4] = { 0, 16, 32, 64 }; | 556 | static const int ddt[4] = { 0, 16, 32, 64 }; |
533 | int size; /* reserved space (in kb) at the top of stolen memory */ | 557 | unsigned int overhead_entries, stolen_entries; |
558 | unsigned int stolen_size = 0; | ||
534 | 559 | ||
535 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | 560 | pci_read_config_word(intel_private.bridge_dev, |
561 | I830_GMCH_CTRL, &gmch_ctrl); | ||
536 | 562 | ||
537 | if (IS_I965) { | 563 | if (INTEL_GTT_GEN > 4 || IS_PINEVIEW) |
538 | u32 pgetbl_ctl; | 564 | overhead_entries = 0; |
539 | pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL); | 565 | else |
566 | overhead_entries = intel_private.base.gtt_mappable_entries | ||
567 | / 1024; | ||
540 | 568 | ||
541 | /* The 965 has a field telling us the size of the GTT, | 569 | overhead_entries += 1; /* BIOS popup */ |
542 | * which may be larger than what is necessary to map the | ||
543 | * aperture. | ||
544 | */ | ||
545 | switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) { | ||
546 | case I965_PGETBL_SIZE_128KB: | ||
547 | size = 128; | ||
548 | break; | ||
549 | case I965_PGETBL_SIZE_256KB: | ||
550 | size = 256; | ||
551 | break; | ||
552 | case I965_PGETBL_SIZE_512KB: | ||
553 | size = 512; | ||
554 | break; | ||
555 | case I965_PGETBL_SIZE_1MB: | ||
556 | size = 1024; | ||
557 | break; | ||
558 | case I965_PGETBL_SIZE_2MB: | ||
559 | size = 2048; | ||
560 | break; | ||
561 | case I965_PGETBL_SIZE_1_5MB: | ||
562 | size = 1024 + 512; | ||
563 | break; | ||
564 | default: | ||
565 | dev_info(&intel_private.pcidev->dev, | ||
566 | "unknown page table size, assuming 512KB\n"); | ||
567 | size = 512; | ||
568 | } | ||
569 | size += 4; /* add in BIOS popup space */ | ||
570 | } else if (IS_G33 && !IS_PINEVIEW) { | ||
571 | /* G33's GTT size defined in gmch_ctrl */ | ||
572 | switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { | ||
573 | case G33_PGETBL_SIZE_1M: | ||
574 | size = 1024; | ||
575 | break; | ||
576 | case G33_PGETBL_SIZE_2M: | ||
577 | size = 2048; | ||
578 | break; | ||
579 | default: | ||
580 | dev_info(&agp_bridge->dev->dev, | ||
581 | "unknown page table size 0x%x, assuming 512KB\n", | ||
582 | (gmch_ctrl & G33_PGETBL_SIZE_MASK)); | ||
583 | size = 512; | ||
584 | } | ||
585 | size += 4; | ||
586 | } else if (IS_G4X || IS_PINEVIEW) { | ||
587 | /* On 4 series hardware, GTT stolen is separate from graphics | ||
588 | * stolen, ignore it in stolen gtt entries counting. However, | ||
589 | * 4KB of the stolen memory doesn't get mapped to the GTT. | ||
590 | */ | ||
591 | size = 4; | ||
592 | } else { | ||
593 | /* On previous hardware, the GTT size was just what was | ||
594 | * required to map the aperture. | ||
595 | */ | ||
596 | size = agp_bridge->driver->fetch_size() + 4; | ||
597 | } | ||
598 | 570 | ||
599 | if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB || | 571 | if (intel_private.bridge_dev->device == PCI_DEVICE_ID_INTEL_82830_HB || |
600 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) { | 572 | intel_private.bridge_dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) { |
601 | switch (gmch_ctrl & I830_GMCH_GMS_MASK) { | 573 | switch (gmch_ctrl & I830_GMCH_GMS_MASK) { |
602 | case I830_GMCH_GMS_STOLEN_512: | 574 | case I830_GMCH_GMS_STOLEN_512: |
603 | gtt_entries = KB(512) - KB(size); | 575 | stolen_size = KB(512); |
604 | break; | 576 | break; |
605 | case I830_GMCH_GMS_STOLEN_1024: | 577 | case I830_GMCH_GMS_STOLEN_1024: |
606 | gtt_entries = MB(1) - KB(size); | 578 | stolen_size = MB(1); |
607 | break; | 579 | break; |
608 | case I830_GMCH_GMS_STOLEN_8192: | 580 | case I830_GMCH_GMS_STOLEN_8192: |
609 | gtt_entries = MB(8) - KB(size); | 581 | stolen_size = MB(8); |
610 | break; | 582 | break; |
611 | case I830_GMCH_GMS_LOCAL: | 583 | case I830_GMCH_GMS_LOCAL: |
612 | rdct = readb(intel_private.registers+I830_RDRAM_CHANNEL_TYPE); | 584 | rdct = readb(intel_private.registers+I830_RDRAM_CHANNEL_TYPE); |
613 | gtt_entries = (I830_RDRAM_ND(rdct) + 1) * | 585 | stolen_size = (I830_RDRAM_ND(rdct) + 1) * |
614 | MB(ddt[I830_RDRAM_DDT(rdct)]); | 586 | MB(ddt[I830_RDRAM_DDT(rdct)]); |
615 | local = 1; | 587 | local = 1; |
616 | break; | 588 | break; |
617 | default: | 589 | default: |
618 | gtt_entries = 0; | 590 | stolen_size = 0; |
619 | break; | 591 | break; |
620 | } | 592 | } |
621 | } else if (IS_SNB) { | 593 | } else if (INTEL_GTT_GEN == 6) { |
622 | /* | 594 | /* |
623 | * SandyBridge has new memory control reg at 0x50.w | 595 | * SandyBridge has new memory control reg at 0x50.w |
624 | */ | 596 | */ |
@@ -626,142 +598,254 @@ static void intel_i830_init_gtt_entries(void) | |||
626 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); | 598 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); |
627 | switch (snb_gmch_ctl & SNB_GMCH_GMS_STOLEN_MASK) { | 599 | switch (snb_gmch_ctl & SNB_GMCH_GMS_STOLEN_MASK) { |
628 | case SNB_GMCH_GMS_STOLEN_32M: | 600 | case SNB_GMCH_GMS_STOLEN_32M: |
629 | gtt_entries = MB(32) - KB(size); | 601 | stolen_size = MB(32); |
630 | break; | 602 | break; |
631 | case SNB_GMCH_GMS_STOLEN_64M: | 603 | case SNB_GMCH_GMS_STOLEN_64M: |
632 | gtt_entries = MB(64) - KB(size); | 604 | stolen_size = MB(64); |
633 | break; | 605 | break; |
634 | case SNB_GMCH_GMS_STOLEN_96M: | 606 | case SNB_GMCH_GMS_STOLEN_96M: |
635 | gtt_entries = MB(96) - KB(size); | 607 | stolen_size = MB(96); |
636 | break; | 608 | break; |
637 | case SNB_GMCH_GMS_STOLEN_128M: | 609 | case SNB_GMCH_GMS_STOLEN_128M: |
638 | gtt_entries = MB(128) - KB(size); | 610 | stolen_size = MB(128); |
639 | break; | 611 | break; |
640 | case SNB_GMCH_GMS_STOLEN_160M: | 612 | case SNB_GMCH_GMS_STOLEN_160M: |
641 | gtt_entries = MB(160) - KB(size); | 613 | stolen_size = MB(160); |
642 | break; | 614 | break; |
643 | case SNB_GMCH_GMS_STOLEN_192M: | 615 | case SNB_GMCH_GMS_STOLEN_192M: |
644 | gtt_entries = MB(192) - KB(size); | 616 | stolen_size = MB(192); |
645 | break; | 617 | break; |
646 | case SNB_GMCH_GMS_STOLEN_224M: | 618 | case SNB_GMCH_GMS_STOLEN_224M: |
647 | gtt_entries = MB(224) - KB(size); | 619 | stolen_size = MB(224); |
648 | break; | 620 | break; |
649 | case SNB_GMCH_GMS_STOLEN_256M: | 621 | case SNB_GMCH_GMS_STOLEN_256M: |
650 | gtt_entries = MB(256) - KB(size); | 622 | stolen_size = MB(256); |
651 | break; | 623 | break; |
652 | case SNB_GMCH_GMS_STOLEN_288M: | 624 | case SNB_GMCH_GMS_STOLEN_288M: |
653 | gtt_entries = MB(288) - KB(size); | 625 | stolen_size = MB(288); |
654 | break; | 626 | break; |
655 | case SNB_GMCH_GMS_STOLEN_320M: | 627 | case SNB_GMCH_GMS_STOLEN_320M: |
656 | gtt_entries = MB(320) - KB(size); | 628 | stolen_size = MB(320); |
657 | break; | 629 | break; |
658 | case SNB_GMCH_GMS_STOLEN_352M: | 630 | case SNB_GMCH_GMS_STOLEN_352M: |
659 | gtt_entries = MB(352) - KB(size); | 631 | stolen_size = MB(352); |
660 | break; | 632 | break; |
661 | case SNB_GMCH_GMS_STOLEN_384M: | 633 | case SNB_GMCH_GMS_STOLEN_384M: |
662 | gtt_entries = MB(384) - KB(size); | 634 | stolen_size = MB(384); |
663 | break; | 635 | break; |
664 | case SNB_GMCH_GMS_STOLEN_416M: | 636 | case SNB_GMCH_GMS_STOLEN_416M: |
665 | gtt_entries = MB(416) - KB(size); | 637 | stolen_size = MB(416); |
666 | break; | 638 | break; |
667 | case SNB_GMCH_GMS_STOLEN_448M: | 639 | case SNB_GMCH_GMS_STOLEN_448M: |
668 | gtt_entries = MB(448) - KB(size); | 640 | stolen_size = MB(448); |
669 | break; | 641 | break; |
670 | case SNB_GMCH_GMS_STOLEN_480M: | 642 | case SNB_GMCH_GMS_STOLEN_480M: |
671 | gtt_entries = MB(480) - KB(size); | 643 | stolen_size = MB(480); |
672 | break; | 644 | break; |
673 | case SNB_GMCH_GMS_STOLEN_512M: | 645 | case SNB_GMCH_GMS_STOLEN_512M: |
674 | gtt_entries = MB(512) - KB(size); | 646 | stolen_size = MB(512); |
675 | break; | 647 | break; |
676 | } | 648 | } |
677 | } else { | 649 | } else { |
678 | switch (gmch_ctrl & I855_GMCH_GMS_MASK) { | 650 | switch (gmch_ctrl & I855_GMCH_GMS_MASK) { |
679 | case I855_GMCH_GMS_STOLEN_1M: | 651 | case I855_GMCH_GMS_STOLEN_1M: |
680 | gtt_entries = MB(1) - KB(size); | 652 | stolen_size = MB(1); |
681 | break; | 653 | break; |
682 | case I855_GMCH_GMS_STOLEN_4M: | 654 | case I855_GMCH_GMS_STOLEN_4M: |
683 | gtt_entries = MB(4) - KB(size); | 655 | stolen_size = MB(4); |
684 | break; | 656 | break; |
685 | case I855_GMCH_GMS_STOLEN_8M: | 657 | case I855_GMCH_GMS_STOLEN_8M: |
686 | gtt_entries = MB(8) - KB(size); | 658 | stolen_size = MB(8); |
687 | break; | 659 | break; |
688 | case I855_GMCH_GMS_STOLEN_16M: | 660 | case I855_GMCH_GMS_STOLEN_16M: |
689 | gtt_entries = MB(16) - KB(size); | 661 | stolen_size = MB(16); |
690 | break; | 662 | break; |
691 | case I855_GMCH_GMS_STOLEN_32M: | 663 | case I855_GMCH_GMS_STOLEN_32M: |
692 | gtt_entries = MB(32) - KB(size); | 664 | stolen_size = MB(32); |
693 | break; | 665 | break; |
694 | case I915_GMCH_GMS_STOLEN_48M: | 666 | case I915_GMCH_GMS_STOLEN_48M: |
695 | /* Check it's really I915G */ | 667 | stolen_size = MB(48); |
696 | if (IS_I915 || IS_I965 || IS_G33 || IS_G4X) | ||
697 | gtt_entries = MB(48) - KB(size); | ||
698 | else | ||
699 | gtt_entries = 0; | ||
700 | break; | 668 | break; |
701 | case I915_GMCH_GMS_STOLEN_64M: | 669 | case I915_GMCH_GMS_STOLEN_64M: |
702 | /* Check it's really I915G */ | 670 | stolen_size = MB(64); |
703 | if (IS_I915 || IS_I965 || IS_G33 || IS_G4X) | ||
704 | gtt_entries = MB(64) - KB(size); | ||
705 | else | ||
706 | gtt_entries = 0; | ||
707 | break; | 671 | break; |
708 | case G33_GMCH_GMS_STOLEN_128M: | 672 | case G33_GMCH_GMS_STOLEN_128M: |
709 | if (IS_G33 || IS_I965 || IS_G4X) | 673 | stolen_size = MB(128); |
710 | gtt_entries = MB(128) - KB(size); | ||
711 | else | ||
712 | gtt_entries = 0; | ||
713 | break; | 674 | break; |
714 | case G33_GMCH_GMS_STOLEN_256M: | 675 | case G33_GMCH_GMS_STOLEN_256M: |
715 | if (IS_G33 || IS_I965 || IS_G4X) | 676 | stolen_size = MB(256); |
716 | gtt_entries = MB(256) - KB(size); | ||
717 | else | ||
718 | gtt_entries = 0; | ||
719 | break; | 677 | break; |
720 | case INTEL_GMCH_GMS_STOLEN_96M: | 678 | case INTEL_GMCH_GMS_STOLEN_96M: |
721 | if (IS_I965 || IS_G4X) | 679 | stolen_size = MB(96); |
722 | gtt_entries = MB(96) - KB(size); | ||
723 | else | ||
724 | gtt_entries = 0; | ||
725 | break; | 680 | break; |
726 | case INTEL_GMCH_GMS_STOLEN_160M: | 681 | case INTEL_GMCH_GMS_STOLEN_160M: |
727 | if (IS_I965 || IS_G4X) | 682 | stolen_size = MB(160); |
728 | gtt_entries = MB(160) - KB(size); | ||
729 | else | ||
730 | gtt_entries = 0; | ||
731 | break; | 683 | break; |
732 | case INTEL_GMCH_GMS_STOLEN_224M: | 684 | case INTEL_GMCH_GMS_STOLEN_224M: |
733 | if (IS_I965 || IS_G4X) | 685 | stolen_size = MB(224); |
734 | gtt_entries = MB(224) - KB(size); | ||
735 | else | ||
736 | gtt_entries = 0; | ||
737 | break; | 686 | break; |
738 | case INTEL_GMCH_GMS_STOLEN_352M: | 687 | case INTEL_GMCH_GMS_STOLEN_352M: |
739 | if (IS_I965 || IS_G4X) | 688 | stolen_size = MB(352); |
740 | gtt_entries = MB(352) - KB(size); | ||
741 | else | ||
742 | gtt_entries = 0; | ||
743 | break; | 689 | break; |
744 | default: | 690 | default: |
745 | gtt_entries = 0; | 691 | stolen_size = 0; |
746 | break; | 692 | break; |
747 | } | 693 | } |
748 | } | 694 | } |
749 | if (!local && gtt_entries > intel_max_stolen) { | 695 | |
750 | dev_info(&agp_bridge->dev->dev, | 696 | if (!local && stolen_size > intel_max_stolen) { |
697 | dev_info(&intel_private.bridge_dev->dev, | ||
751 | "detected %dK stolen memory, trimming to %dK\n", | 698 | "detected %dK stolen memory, trimming to %dK\n", |
752 | gtt_entries / KB(1), intel_max_stolen / KB(1)); | 699 | stolen_size / KB(1), intel_max_stolen / KB(1)); |
753 | gtt_entries = intel_max_stolen / KB(4); | 700 | stolen_size = intel_max_stolen; |
754 | } else if (gtt_entries > 0) { | 701 | } else if (stolen_size > 0) { |
755 | dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n", | 702 | dev_info(&intel_private.bridge_dev->dev, "detected %dK %s memory\n", |
756 | gtt_entries / KB(1), local ? "local" : "stolen"); | 703 | stolen_size / KB(1), local ? "local" : "stolen"); |
757 | gtt_entries /= KB(4); | ||
758 | } else { | 704 | } else { |
759 | dev_info(&agp_bridge->dev->dev, | 705 | dev_info(&intel_private.bridge_dev->dev, |
760 | "no pre-allocated video memory detected\n"); | 706 | "no pre-allocated video memory detected\n"); |
761 | gtt_entries = 0; | 707 | stolen_size = 0; |
708 | } | ||
709 | |||
710 | stolen_entries = stolen_size/KB(4) - overhead_entries; | ||
711 | |||
712 | return stolen_entries; | ||
713 | } | ||
714 | |||
715 | static unsigned int intel_gtt_total_entries(void) | ||
716 | { | ||
717 | int size; | ||
718 | |||
719 | if (IS_G33 || INTEL_GTT_GEN == 4 || INTEL_GTT_GEN == 5) { | ||
720 | u32 pgetbl_ctl; | ||
721 | pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL); | ||
722 | |||
723 | switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) { | ||
724 | case I965_PGETBL_SIZE_128KB: | ||
725 | size = KB(128); | ||
726 | break; | ||
727 | case I965_PGETBL_SIZE_256KB: | ||
728 | size = KB(256); | ||
729 | break; | ||
730 | case I965_PGETBL_SIZE_512KB: | ||
731 | size = KB(512); | ||
732 | break; | ||
733 | case I965_PGETBL_SIZE_1MB: | ||
734 | size = KB(1024); | ||
735 | break; | ||
736 | case I965_PGETBL_SIZE_2MB: | ||
737 | size = KB(2048); | ||
738 | break; | ||
739 | case I965_PGETBL_SIZE_1_5MB: | ||
740 | size = KB(1024 + 512); | ||
741 | break; | ||
742 | default: | ||
743 | dev_info(&intel_private.pcidev->dev, | ||
744 | "unknown page table size, assuming 512KB\n"); | ||
745 | size = KB(512); | ||
746 | } | ||
747 | |||
748 | return size/4; | ||
749 | } else if (INTEL_GTT_GEN == 6) { | ||
750 | u16 snb_gmch_ctl; | ||
751 | |||
752 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); | ||
753 | switch (snb_gmch_ctl & SNB_GTT_SIZE_MASK) { | ||
754 | default: | ||
755 | case SNB_GTT_SIZE_0M: | ||
756 | printk(KERN_ERR "Bad GTT size mask: 0x%04x.\n", snb_gmch_ctl); | ||
757 | size = MB(0); | ||
758 | break; | ||
759 | case SNB_GTT_SIZE_1M: | ||
760 | size = MB(1); | ||
761 | break; | ||
762 | case SNB_GTT_SIZE_2M: | ||
763 | size = MB(2); | ||
764 | break; | ||
765 | } | ||
766 | return size/4; | ||
767 | } else { | ||
768 | /* On previous hardware, the GTT size was just what was | ||
769 | * required to map the aperture. | ||
770 | */ | ||
771 | return intel_private.base.gtt_mappable_entries; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | static unsigned int intel_gtt_mappable_entries(void) | ||
776 | { | ||
777 | unsigned int aperture_size; | ||
778 | |||
779 | if (INTEL_GTT_GEN == 2) { | ||
780 | u16 gmch_ctrl; | ||
781 | |||
782 | pci_read_config_word(intel_private.bridge_dev, | ||
783 | I830_GMCH_CTRL, &gmch_ctrl); | ||
784 | |||
785 | if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_64M) | ||
786 | aperture_size = MB(64); | ||
787 | else | ||
788 | aperture_size = MB(128); | ||
789 | } else { | ||
790 | /* 9xx supports large sizes, just look at the length */ | ||
791 | aperture_size = pci_resource_len(intel_private.pcidev, 2); | ||
762 | } | 792 | } |
763 | 793 | ||
764 | intel_private.gtt_entries = gtt_entries; | 794 | return aperture_size >> PAGE_SHIFT; |
795 | } | ||
796 | |||
797 | static int intel_gtt_init(void) | ||
798 | { | ||
799 | u32 gtt_map_size; | ||
800 | int ret; | ||
801 | |||
802 | ret = intel_private.driver->setup(); | ||
803 | if (ret != 0) | ||
804 | return ret; | ||
805 | |||
806 | intel_private.base.gtt_mappable_entries = intel_gtt_mappable_entries(); | ||
807 | intel_private.base.gtt_total_entries = intel_gtt_total_entries(); | ||
808 | |||
809 | gtt_map_size = intel_private.base.gtt_total_entries * 4; | ||
810 | |||
811 | intel_private.gtt = ioremap(intel_private.gtt_bus_addr, | ||
812 | gtt_map_size); | ||
813 | if (!intel_private.gtt) { | ||
814 | iounmap(intel_private.registers); | ||
815 | return -ENOMEM; | ||
816 | } | ||
817 | |||
818 | global_cache_flush(); /* FIXME: ? */ | ||
819 | |||
820 | /* we have to call this as early as possible after the MMIO base address is known */ | ||
821 | intel_private.base.gtt_stolen_entries = intel_gtt_stolen_entries(); | ||
822 | if (intel_private.base.gtt_stolen_entries == 0) { | ||
823 | iounmap(intel_private.registers); | ||
824 | iounmap(intel_private.gtt); | ||
825 | return -ENOMEM; | ||
826 | } | ||
827 | |||
828 | return 0; | ||
829 | } | ||
830 | |||
831 | static int intel_fake_agp_fetch_size(void) | ||
832 | { | ||
833 | int num_sizes = ARRAY_SIZE(intel_fake_agp_sizes); | ||
834 | unsigned int aper_size; | ||
835 | int i; | ||
836 | |||
837 | aper_size = (intel_private.base.gtt_mappable_entries << PAGE_SHIFT) | ||
838 | / MB(1); | ||
839 | |||
840 | for (i = 0; i < num_sizes; i++) { | ||
841 | if (aper_size == intel_fake_agp_sizes[i].size) { | ||
842 | agp_bridge->current_size = | ||
843 | (void *) (intel_fake_agp_sizes + i); | ||
844 | return aper_size; | ||
845 | } | ||
846 | } | ||
847 | |||
848 | return 0; | ||
765 | } | 849 | } |
766 | 850 | ||
767 | static void intel_i830_fini_flush(void) | 851 | static void intel_i830_fini_flush(void) |
@@ -811,120 +895,84 @@ static void intel_i830_chipset_flush(struct agp_bridge_data *bridge) | |||
811 | printk(KERN_ERR "Timed out waiting for cache flush.\n"); | 895 | printk(KERN_ERR "Timed out waiting for cache flush.\n"); |
812 | } | 896 | } |
813 | 897 | ||
814 | /* The intel i830 automatically initializes the agp aperture during POST. | 898 | static void intel_enable_gtt(void) |
815 | * Use the memory already set aside for in the GTT. | ||
816 | */ | ||
817 | static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge) | ||
818 | { | 899 | { |
819 | int page_order; | 900 | u32 gma_addr; |
820 | struct aper_size_info_fixed *size; | 901 | u16 gmch_ctrl; |
821 | int num_entries; | ||
822 | u32 temp; | ||
823 | 902 | ||
824 | size = agp_bridge->current_size; | 903 | if (INTEL_GTT_GEN == 2) |
825 | page_order = size->page_order; | 904 | pci_read_config_dword(intel_private.pcidev, I810_GMADDR, |
826 | num_entries = size->num_entries; | 905 | &gma_addr); |
827 | agp_bridge->gatt_table_real = NULL; | 906 | else |
907 | pci_read_config_dword(intel_private.pcidev, I915_GMADDR, | ||
908 | &gma_addr); | ||
828 | 909 | ||
829 | pci_read_config_dword(intel_private.pcidev, I810_MMADDR, &temp); | 910 | intel_private.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK); |
830 | temp &= 0xfff80000; | ||
831 | 911 | ||
832 | intel_private.registers = ioremap(temp, 128 * 4096); | 912 | pci_read_config_word(intel_private.bridge_dev, I830_GMCH_CTRL, &gmch_ctrl); |
833 | if (!intel_private.registers) | 913 | gmch_ctrl |= I830_GMCH_ENABLED; |
834 | return -ENOMEM; | 914 | pci_write_config_word(intel_private.bridge_dev, I830_GMCH_CTRL, gmch_ctrl); |
835 | 915 | ||
836 | temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; | 916 | writel(intel_private.pte_bus_addr|I810_PGETBL_ENABLED, |
837 | global_cache_flush(); /* FIXME: ?? */ | 917 | intel_private.registers+I810_PGETBL_CTL); |
918 | readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ | ||
919 | } | ||
838 | 920 | ||
839 | /* we have to call this as early as possible after the MMIO base address is known */ | 921 | static int i830_setup(void) |
840 | intel_i830_init_gtt_entries(); | 922 | { |
841 | if (intel_private.gtt_entries == 0) { | 923 | u32 reg_addr; |
842 | iounmap(intel_private.registers); | 924 | |
925 | pci_read_config_dword(intel_private.pcidev, I810_MMADDR, ®_addr); | ||
926 | reg_addr &= 0xfff80000; | ||
927 | |||
928 | intel_private.registers = ioremap(reg_addr, KB(64)); | ||
929 | if (!intel_private.registers) | ||
843 | return -ENOMEM; | 930 | return -ENOMEM; |
844 | } | ||
845 | 931 | ||
846 | agp_bridge->gatt_table = NULL; | 932 | intel_private.gtt_bus_addr = reg_addr + I810_PTE_BASE; |
933 | intel_private.pte_bus_addr = | ||
934 | readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; | ||
847 | 935 | ||
848 | agp_bridge->gatt_bus_addr = temp; | 936 | intel_i830_setup_flush(); |
849 | 937 | ||
850 | return 0; | 938 | return 0; |
851 | } | 939 | } |
852 | 940 | ||
853 | /* Return the gatt table to a sane state. Use the top of stolen | 941 | static int intel_fake_agp_create_gatt_table(struct agp_bridge_data *bridge) |
854 | * memory for the GTT. | ||
855 | */ | ||
856 | static int intel_i830_free_gatt_table(struct agp_bridge_data *bridge) | ||
857 | { | 942 | { |
943 | agp_bridge->gatt_table_real = NULL; | ||
944 | agp_bridge->gatt_table = NULL; | ||
945 | agp_bridge->gatt_bus_addr = 0; | ||
946 | |||
858 | return 0; | 947 | return 0; |
859 | } | 948 | } |
860 | 949 | ||
861 | static int intel_i830_fetch_size(void) | 950 | static int intel_fake_agp_free_gatt_table(struct agp_bridge_data *bridge) |
862 | { | 951 | { |
863 | u16 gmch_ctrl; | ||
864 | struct aper_size_info_fixed *values; | ||
865 | |||
866 | values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); | ||
867 | |||
868 | if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB && | ||
869 | agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) { | ||
870 | /* 855GM/852GM/865G has 128MB aperture size */ | ||
871 | agp_bridge->current_size = (void *) values; | ||
872 | agp_bridge->aperture_size_idx = 0; | ||
873 | return values[0].size; | ||
874 | } | ||
875 | |||
876 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | ||
877 | |||
878 | if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { | ||
879 | agp_bridge->current_size = (void *) values; | ||
880 | agp_bridge->aperture_size_idx = 0; | ||
881 | return values[0].size; | ||
882 | } else { | ||
883 | agp_bridge->current_size = (void *) (values + 1); | ||
884 | agp_bridge->aperture_size_idx = 1; | ||
885 | return values[1].size; | ||
886 | } | ||
887 | |||
888 | return 0; | 952 | return 0; |
889 | } | 953 | } |
890 | 954 | ||
891 | static int intel_i830_configure(void) | 955 | static int intel_i830_configure(void) |
892 | { | 956 | { |
893 | struct aper_size_info_fixed *current_size; | ||
894 | u32 temp; | ||
895 | u16 gmch_ctrl; | ||
896 | int i; | 957 | int i; |
897 | 958 | ||
898 | current_size = A_SIZE_FIX(agp_bridge->current_size); | 959 | intel_enable_gtt(); |
899 | 960 | ||
900 | pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp); | 961 | agp_bridge->gart_bus_addr = intel_private.gma_bus_addr; |
901 | agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); | ||
902 | |||
903 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | ||
904 | gmch_ctrl |= I830_GMCH_ENABLED; | ||
905 | pci_write_config_word(agp_bridge->dev, I830_GMCH_CTRL, gmch_ctrl); | ||
906 | |||
907 | writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL); | ||
908 | readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ | ||
909 | 962 | ||
910 | if (agp_bridge->driver->needs_scratch_page) { | 963 | if (agp_bridge->driver->needs_scratch_page) { |
911 | for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) { | 964 | for (i = intel_private.base.gtt_stolen_entries; |
912 | writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); | 965 | i < intel_private.base.gtt_total_entries; i++) { |
966 | writel(agp_bridge->scratch_page, intel_private.gtt+i); | ||
913 | } | 967 | } |
914 | readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI Posting. */ | 968 | readl(intel_private.gtt+i-1); /* PCI Posting. */ |
915 | } | 969 | } |
916 | 970 | ||
917 | global_cache_flush(); | 971 | global_cache_flush(); |
918 | 972 | ||
919 | intel_i830_setup_flush(); | ||
920 | return 0; | 973 | return 0; |
921 | } | 974 | } |
922 | 975 | ||
923 | static void intel_i830_cleanup(void) | ||
924 | { | ||
925 | iounmap(intel_private.registers); | ||
926 | } | ||
927 | |||
928 | static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, | 976 | static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, |
929 | int type) | 977 | int type) |
930 | { | 978 | { |
@@ -939,10 +987,10 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
939 | temp = agp_bridge->current_size; | 987 | temp = agp_bridge->current_size; |
940 | num_entries = A_SIZE_FIX(temp)->num_entries; | 988 | num_entries = A_SIZE_FIX(temp)->num_entries; |
941 | 989 | ||
942 | if (pg_start < intel_private.gtt_entries) { | 990 | if (pg_start < intel_private.base.gtt_stolen_entries) { |
943 | dev_printk(KERN_DEBUG, &intel_private.pcidev->dev, | 991 | dev_printk(KERN_DEBUG, &intel_private.pcidev->dev, |
944 | "pg_start == 0x%.8lx, intel_private.gtt_entries == 0x%.8x\n", | 992 | "pg_start == 0x%.8lx, gtt_stolen_entries == 0x%.8x\n", |
945 | pg_start, intel_private.gtt_entries); | 993 | pg_start, intel_private.base.gtt_stolen_entries); |
946 | 994 | ||
947 | dev_info(&intel_private.pcidev->dev, | 995 | dev_info(&intel_private.pcidev->dev, |
948 | "trying to insert into local/stolen memory\n"); | 996 | "trying to insert into local/stolen memory\n"); |
@@ -971,9 +1019,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
971 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 1019 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
972 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 1020 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
973 | page_to_phys(mem->pages[i]), mask_type), | 1021 | page_to_phys(mem->pages[i]), mask_type), |
974 | intel_private.registers+I810_PTE_BASE+(j*4)); | 1022 | intel_private.gtt+j); |
975 | } | 1023 | } |
976 | readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); | 1024 | readl(intel_private.gtt+j-1); |
977 | 1025 | ||
978 | out: | 1026 | out: |
979 | ret = 0; | 1027 | ret = 0; |
@@ -990,21 +1038,22 @@ static int intel_i830_remove_entries(struct agp_memory *mem, off_t pg_start, | |||
990 | if (mem->page_count == 0) | 1038 | if (mem->page_count == 0) |
991 | return 0; | 1039 | return 0; |
992 | 1040 | ||
993 | if (pg_start < intel_private.gtt_entries) { | 1041 | if (pg_start < intel_private.base.gtt_stolen_entries) { |
994 | dev_info(&intel_private.pcidev->dev, | 1042 | dev_info(&intel_private.pcidev->dev, |
995 | "trying to disable local/stolen memory\n"); | 1043 | "trying to disable local/stolen memory\n"); |
996 | return -EINVAL; | 1044 | return -EINVAL; |
997 | } | 1045 | } |
998 | 1046 | ||
999 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { | 1047 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { |
1000 | writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); | 1048 | writel(agp_bridge->scratch_page, intel_private.gtt+i); |
1001 | } | 1049 | } |
1002 | readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); | 1050 | readl(intel_private.gtt+i-1); |
1003 | 1051 | ||
1004 | return 0; | 1052 | return 0; |
1005 | } | 1053 | } |
1006 | 1054 | ||
1007 | static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count, int type) | 1055 | static struct agp_memory *intel_fake_agp_alloc_by_type(size_t pg_count, |
1056 | int type) | ||
1008 | { | 1057 | { |
1009 | if (type == AGP_PHYS_MEMORY) | 1058 | if (type == AGP_PHYS_MEMORY) |
1010 | return alloc_agpphysmem_i8xx(pg_count, type); | 1059 | return alloc_agpphysmem_i8xx(pg_count, type); |
@@ -1015,9 +1064,9 @@ static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count, int type) | |||
1015 | static int intel_alloc_chipset_flush_resource(void) | 1064 | static int intel_alloc_chipset_flush_resource(void) |
1016 | { | 1065 | { |
1017 | int ret; | 1066 | int ret; |
1018 | ret = pci_bus_alloc_resource(agp_bridge->dev->bus, &intel_private.ifp_resource, PAGE_SIZE, | 1067 | ret = pci_bus_alloc_resource(intel_private.bridge_dev->bus, &intel_private.ifp_resource, PAGE_SIZE, |
1019 | PAGE_SIZE, PCIBIOS_MIN_MEM, 0, | 1068 | PAGE_SIZE, PCIBIOS_MIN_MEM, 0, |
1020 | pcibios_align_resource, agp_bridge->dev); | 1069 | pcibios_align_resource, intel_private.bridge_dev); |
1021 | 1070 | ||
1022 | return ret; | 1071 | return ret; |
1023 | } | 1072 | } |
@@ -1027,11 +1076,11 @@ static void intel_i915_setup_chipset_flush(void) | |||
1027 | int ret; | 1076 | int ret; |
1028 | u32 temp; | 1077 | u32 temp; |
1029 | 1078 | ||
1030 | pci_read_config_dword(agp_bridge->dev, I915_IFPADDR, &temp); | 1079 | pci_read_config_dword(intel_private.bridge_dev, I915_IFPADDR, &temp); |
1031 | if (!(temp & 0x1)) { | 1080 | if (!(temp & 0x1)) { |
1032 | intel_alloc_chipset_flush_resource(); | 1081 | intel_alloc_chipset_flush_resource(); |
1033 | intel_private.resource_valid = 1; | 1082 | intel_private.resource_valid = 1; |
1034 | pci_write_config_dword(agp_bridge->dev, I915_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); | 1083 | pci_write_config_dword(intel_private.bridge_dev, I915_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); |
1035 | } else { | 1084 | } else { |
1036 | temp &= ~1; | 1085 | temp &= ~1; |
1037 | 1086 | ||
@@ -1050,17 +1099,17 @@ static void intel_i965_g33_setup_chipset_flush(void) | |||
1050 | u32 temp_hi, temp_lo; | 1099 | u32 temp_hi, temp_lo; |
1051 | int ret; | 1100 | int ret; |
1052 | 1101 | ||
1053 | pci_read_config_dword(agp_bridge->dev, I965_IFPADDR + 4, &temp_hi); | 1102 | pci_read_config_dword(intel_private.bridge_dev, I965_IFPADDR + 4, &temp_hi); |
1054 | pci_read_config_dword(agp_bridge->dev, I965_IFPADDR, &temp_lo); | 1103 | pci_read_config_dword(intel_private.bridge_dev, I965_IFPADDR, &temp_lo); |
1055 | 1104 | ||
1056 | if (!(temp_lo & 0x1)) { | 1105 | if (!(temp_lo & 0x1)) { |
1057 | 1106 | ||
1058 | intel_alloc_chipset_flush_resource(); | 1107 | intel_alloc_chipset_flush_resource(); |
1059 | 1108 | ||
1060 | intel_private.resource_valid = 1; | 1109 | intel_private.resource_valid = 1; |
1061 | pci_write_config_dword(agp_bridge->dev, I965_IFPADDR + 4, | 1110 | pci_write_config_dword(intel_private.bridge_dev, I965_IFPADDR + 4, |
1062 | upper_32_bits(intel_private.ifp_resource.start)); | 1111 | upper_32_bits(intel_private.ifp_resource.start)); |
1063 | pci_write_config_dword(agp_bridge->dev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); | 1112 | pci_write_config_dword(intel_private.bridge_dev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); |
1064 | } else { | 1113 | } else { |
1065 | u64 l64; | 1114 | u64 l64; |
1066 | 1115 | ||
@@ -1083,7 +1132,7 @@ static void intel_i9xx_setup_flush(void) | |||
1083 | if (intel_private.ifp_resource.start) | 1132 | if (intel_private.ifp_resource.start) |
1084 | return; | 1133 | return; |
1085 | 1134 | ||
1086 | if (IS_SNB) | 1135 | if (INTEL_GTT_GEN == 6) |
1087 | return; | 1136 | return; |
1088 | 1137 | ||
1089 | /* setup a resource for this object */ | 1138 | /* setup a resource for this object */ |
@@ -1091,7 +1140,7 @@ static void intel_i9xx_setup_flush(void) | |||
1091 | intel_private.ifp_resource.flags = IORESOURCE_MEM; | 1140 | intel_private.ifp_resource.flags = IORESOURCE_MEM; |
1092 | 1141 | ||
1093 | /* Setup chipset flush for 915 */ | 1142 | /* Setup chipset flush for 915 */ |
1094 | if (IS_I965 || IS_G33 || IS_G4X) { | 1143 | if (IS_G33 || INTEL_GTT_GEN >= 4) { |
1095 | intel_i965_g33_setup_chipset_flush(); | 1144 | intel_i965_g33_setup_chipset_flush(); |
1096 | } else { | 1145 | } else { |
1097 | intel_i915_setup_chipset_flush(); | 1146 | intel_i915_setup_chipset_flush(); |
@@ -1106,26 +1155,15 @@ static void intel_i9xx_setup_flush(void) | |||
1106 | 1155 | ||
1107 | static int intel_i9xx_configure(void) | 1156 | static int intel_i9xx_configure(void) |
1108 | { | 1157 | { |
1109 | struct aper_size_info_fixed *current_size; | ||
1110 | u32 temp; | ||
1111 | u16 gmch_ctrl; | ||
1112 | int i; | 1158 | int i; |
1113 | 1159 | ||
1114 | current_size = A_SIZE_FIX(agp_bridge->current_size); | 1160 | intel_enable_gtt(); |
1115 | 1161 | ||
1116 | pci_read_config_dword(intel_private.pcidev, I915_GMADDR, &temp); | 1162 | agp_bridge->gart_bus_addr = intel_private.gma_bus_addr; |
1117 | |||
1118 | agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); | ||
1119 | |||
1120 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | ||
1121 | gmch_ctrl |= I830_GMCH_ENABLED; | ||
1122 | pci_write_config_word(agp_bridge->dev, I830_GMCH_CTRL, gmch_ctrl); | ||
1123 | |||
1124 | writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL); | ||
1125 | readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ | ||
1126 | 1163 | ||
1127 | if (agp_bridge->driver->needs_scratch_page) { | 1164 | if (agp_bridge->driver->needs_scratch_page) { |
1128 | for (i = intel_private.gtt_entries; i < intel_private.gtt_total_size; i++) { | 1165 | for (i = intel_private.base.gtt_stolen_entries; i < |
1166 | intel_private.base.gtt_total_entries; i++) { | ||
1129 | writel(agp_bridge->scratch_page, intel_private.gtt+i); | 1167 | writel(agp_bridge->scratch_page, intel_private.gtt+i); |
1130 | } | 1168 | } |
1131 | readl(intel_private.gtt+i-1); /* PCI Posting. */ | 1169 | readl(intel_private.gtt+i-1); /* PCI Posting. */ |
@@ -1133,12 +1171,10 @@ static int intel_i9xx_configure(void) | |||
1133 | 1171 | ||
1134 | global_cache_flush(); | 1172 | global_cache_flush(); |
1135 | 1173 | ||
1136 | intel_i9xx_setup_flush(); | ||
1137 | |||
1138 | return 0; | 1174 | return 0; |
1139 | } | 1175 | } |
1140 | 1176 | ||
1141 | static void intel_i915_cleanup(void) | 1177 | static void intel_gtt_cleanup(void) |
1142 | { | 1178 | { |
1143 | if (intel_private.i9xx_flush_page) | 1179 | if (intel_private.i9xx_flush_page) |
1144 | iounmap(intel_private.i9xx_flush_page); | 1180 | iounmap(intel_private.i9xx_flush_page); |
@@ -1170,10 +1206,10 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
1170 | temp = agp_bridge->current_size; | 1206 | temp = agp_bridge->current_size; |
1171 | num_entries = A_SIZE_FIX(temp)->num_entries; | 1207 | num_entries = A_SIZE_FIX(temp)->num_entries; |
1172 | 1208 | ||
1173 | if (pg_start < intel_private.gtt_entries) { | 1209 | if (pg_start < intel_private.base.gtt_stolen_entries) { |
1174 | dev_printk(KERN_DEBUG, &intel_private.pcidev->dev, | 1210 | dev_printk(KERN_DEBUG, &intel_private.pcidev->dev, |
1175 | "pg_start == 0x%.8lx, intel_private.gtt_entries == 0x%.8x\n", | 1211 | "pg_start == 0x%.8lx, gtt_stolen_entries == 0x%.8x\n", |
1176 | pg_start, intel_private.gtt_entries); | 1212 | pg_start, intel_private.base.gtt_stolen_entries); |
1177 | 1213 | ||
1178 | dev_info(&intel_private.pcidev->dev, | 1214 | dev_info(&intel_private.pcidev->dev, |
1179 | "trying to insert into local/stolen memory\n"); | 1215 | "trying to insert into local/stolen memory\n"); |
@@ -1192,7 +1228,8 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
1192 | 1228 | ||
1193 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); | 1229 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); |
1194 | 1230 | ||
1195 | if (!IS_SNB && mask_type != 0 && mask_type != AGP_PHYS_MEMORY && | 1231 | if (INTEL_GTT_GEN != 6 && mask_type != 0 && |
1232 | mask_type != AGP_PHYS_MEMORY && | ||
1196 | mask_type != INTEL_AGP_CACHED_MEMORY) | 1233 | mask_type != INTEL_AGP_CACHED_MEMORY) |
1197 | goto out_err; | 1234 | goto out_err; |
1198 | 1235 | ||
@@ -1216,7 +1253,7 @@ static int intel_i915_remove_entries(struct agp_memory *mem, off_t pg_start, | |||
1216 | if (mem->page_count == 0) | 1253 | if (mem->page_count == 0) |
1217 | return 0; | 1254 | return 0; |
1218 | 1255 | ||
1219 | if (pg_start < intel_private.gtt_entries) { | 1256 | if (pg_start < intel_private.base.gtt_stolen_entries) { |
1220 | dev_info(&intel_private.pcidev->dev, | 1257 | dev_info(&intel_private.pcidev->dev, |
1221 | "trying to disable local/stolen memory\n"); | 1258 | "trying to disable local/stolen memory\n"); |
1222 | return -EINVAL; | 1259 | return -EINVAL; |
@@ -1230,112 +1267,44 @@ static int intel_i915_remove_entries(struct agp_memory *mem, off_t pg_start, | |||
1230 | return 0; | 1267 | return 0; |
1231 | } | 1268 | } |
1232 | 1269 | ||
1233 | /* Return the aperture size by just checking the resource length. The effect | 1270 | static int i9xx_setup(void) |
1234 | * described in the spec of the MSAC registers is just changing of the | ||
1235 | * resource size. | ||
1236 | */ | ||
1237 | static int intel_i9xx_fetch_size(void) | ||
1238 | { | 1271 | { |
1239 | int num_sizes = ARRAY_SIZE(intel_i830_sizes); | 1272 | u32 reg_addr; |
1240 | int aper_size; /* size in megabytes */ | ||
1241 | int i; | ||
1242 | 1273 | ||
1243 | aper_size = pci_resource_len(intel_private.pcidev, 2) / MB(1); | 1274 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, ®_addr); |
1244 | 1275 | ||
1245 | for (i = 0; i < num_sizes; i++) { | 1276 | reg_addr &= 0xfff80000; |
1246 | if (aper_size == intel_i830_sizes[i].size) { | ||
1247 | agp_bridge->current_size = intel_i830_sizes + i; | ||
1248 | return aper_size; | ||
1249 | } | ||
1250 | } | ||
1251 | 1277 | ||
1252 | return 0; | 1278 | intel_private.registers = ioremap(reg_addr, 128 * 4096); |
1253 | } | 1279 | if (!intel_private.registers) |
1280 | return -ENOMEM; | ||
1254 | 1281 | ||
1255 | static int intel_i915_get_gtt_size(void) | 1282 | if (INTEL_GTT_GEN == 3) { |
1256 | { | 1283 | u32 gtt_addr; |
1257 | int size; | ||
1258 | 1284 | ||
1259 | if (IS_G33) { | 1285 | pci_read_config_dword(intel_private.pcidev, |
1260 | u16 gmch_ctrl; | 1286 | I915_PTEADDR, >t_addr); |
1287 | intel_private.gtt_bus_addr = gtt_addr; | ||
1288 | } else { | ||
1289 | u32 gtt_offset; | ||
1261 | 1290 | ||
1262 | /* G33's GTT size defined in gmch_ctrl */ | 1291 | switch (INTEL_GTT_GEN) { |
1263 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | 1292 | case 5: |
1264 | switch (gmch_ctrl & I830_GMCH_GMS_MASK) { | 1293 | case 6: |
1265 | case I830_GMCH_GMS_STOLEN_512: | 1294 | gtt_offset = MB(2); |
1266 | size = 512; | ||
1267 | break; | ||
1268 | case I830_GMCH_GMS_STOLEN_1024: | ||
1269 | size = 1024; | ||
1270 | break; | ||
1271 | case I830_GMCH_GMS_STOLEN_8192: | ||
1272 | size = 8*1024; | ||
1273 | break; | 1295 | break; |
1296 | case 4: | ||
1274 | default: | 1297 | default: |
1275 | dev_info(&agp_bridge->dev->dev, | 1298 | gtt_offset = KB(512); |
1276 | "unknown page table size 0x%x, assuming 512KB\n", | 1299 | break; |
1277 | (gmch_ctrl & I830_GMCH_GMS_MASK)); | ||
1278 | size = 512; | ||
1279 | } | 1300 | } |
1280 | } else { | 1301 | intel_private.gtt_bus_addr = reg_addr + gtt_offset; |
1281 | /* On previous hardware, the GTT size was just what was | ||
1282 | * required to map the aperture. | ||
1283 | */ | ||
1284 | size = agp_bridge->driver->fetch_size(); | ||
1285 | } | ||
1286 | |||
1287 | return KB(size); | ||
1288 | } | ||
1289 | |||
1290 | /* The intel i915 automatically initializes the agp aperture during POST. | ||
1291 | * Use the memory already set aside for in the GTT. | ||
1292 | */ | ||
1293 | static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | ||
1294 | { | ||
1295 | int page_order; | ||
1296 | struct aper_size_info_fixed *size; | ||
1297 | int num_entries; | ||
1298 | u32 temp, temp2; | ||
1299 | int gtt_map_size; | ||
1300 | |||
1301 | size = agp_bridge->current_size; | ||
1302 | page_order = size->page_order; | ||
1303 | num_entries = size->num_entries; | ||
1304 | agp_bridge->gatt_table_real = NULL; | ||
1305 | |||
1306 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); | ||
1307 | pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2); | ||
1308 | |||
1309 | gtt_map_size = intel_i915_get_gtt_size(); | ||
1310 | |||
1311 | intel_private.gtt = ioremap(temp2, gtt_map_size); | ||
1312 | if (!intel_private.gtt) | ||
1313 | return -ENOMEM; | ||
1314 | |||
1315 | intel_private.gtt_total_size = gtt_map_size / 4; | ||
1316 | |||
1317 | temp &= 0xfff80000; | ||
1318 | |||
1319 | intel_private.registers = ioremap(temp, 128 * 4096); | ||
1320 | if (!intel_private.registers) { | ||
1321 | iounmap(intel_private.gtt); | ||
1322 | return -ENOMEM; | ||
1323 | } | 1302 | } |
1324 | 1303 | ||
1325 | temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; | 1304 | intel_private.pte_bus_addr = |
1326 | global_cache_flush(); /* FIXME: ? */ | 1305 | readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; |
1327 | |||
1328 | /* we have to call this as early as possible after the MMIO base address is known */ | ||
1329 | intel_i830_init_gtt_entries(); | ||
1330 | if (intel_private.gtt_entries == 0) { | ||
1331 | iounmap(intel_private.gtt); | ||
1332 | iounmap(intel_private.registers); | ||
1333 | return -ENOMEM; | ||
1334 | } | ||
1335 | |||
1336 | agp_bridge->gatt_table = NULL; | ||
1337 | 1306 | ||
1338 | agp_bridge->gatt_bus_addr = temp; | 1307 | intel_i9xx_setup_flush(); |
1339 | 1308 | ||
1340 | return 0; | 1309 | return 0; |
1341 | } | 1310 | } |
@@ -1369,101 +1338,6 @@ static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge, | |||
1369 | return addr | bridge->driver->masks[type].mask; | 1338 | return addr | bridge->driver->masks[type].mask; |
1370 | } | 1339 | } |
1371 | 1340 | ||
1372 | static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) | ||
1373 | { | ||
1374 | u16 snb_gmch_ctl; | ||
1375 | |||
1376 | switch (agp_bridge->dev->device) { | ||
1377 | case PCI_DEVICE_ID_INTEL_GM45_HB: | ||
1378 | case PCI_DEVICE_ID_INTEL_EAGLELAKE_HB: | ||
1379 | case PCI_DEVICE_ID_INTEL_Q45_HB: | ||
1380 | case PCI_DEVICE_ID_INTEL_G45_HB: | ||
1381 | case PCI_DEVICE_ID_INTEL_G41_HB: | ||
1382 | case PCI_DEVICE_ID_INTEL_B43_HB: | ||
1383 | case PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB: | ||
1384 | case PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB: | ||
1385 | case PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB: | ||
1386 | case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB: | ||
1387 | *gtt_offset = *gtt_size = MB(2); | ||
1388 | break; | ||
1389 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB: | ||
1390 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB: | ||
1391 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB: | ||
1392 | *gtt_offset = MB(2); | ||
1393 | |||
1394 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); | ||
1395 | switch (snb_gmch_ctl & SNB_GTT_SIZE_MASK) { | ||
1396 | default: | ||
1397 | case SNB_GTT_SIZE_0M: | ||
1398 | printk(KERN_ERR "Bad GTT size mask: 0x%04x.\n", snb_gmch_ctl); | ||
1399 | *gtt_size = MB(0); | ||
1400 | break; | ||
1401 | case SNB_GTT_SIZE_1M: | ||
1402 | *gtt_size = MB(1); | ||
1403 | break; | ||
1404 | case SNB_GTT_SIZE_2M: | ||
1405 | *gtt_size = MB(2); | ||
1406 | break; | ||
1407 | } | ||
1408 | break; | ||
1409 | default: | ||
1410 | *gtt_offset = *gtt_size = KB(512); | ||
1411 | } | ||
1412 | } | ||
1413 | |||
1414 | /* The intel i965 automatically initializes the agp aperture during POST. | ||
1415 | * Use the memory already set aside for in the GTT. | ||
1416 | */ | ||
1417 | static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) | ||
1418 | { | ||
1419 | int page_order; | ||
1420 | struct aper_size_info_fixed *size; | ||
1421 | int num_entries; | ||
1422 | u32 temp; | ||
1423 | int gtt_offset, gtt_size; | ||
1424 | |||
1425 | size = agp_bridge->current_size; | ||
1426 | page_order = size->page_order; | ||
1427 | num_entries = size->num_entries; | ||
1428 | agp_bridge->gatt_table_real = NULL; | ||
1429 | |||
1430 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); | ||
1431 | |||
1432 | temp &= 0xfff00000; | ||
1433 | |||
1434 | intel_i965_get_gtt_range(>t_offset, >t_size); | ||
1435 | |||
1436 | intel_private.gtt = ioremap((temp + gtt_offset) , gtt_size); | ||
1437 | |||
1438 | if (!intel_private.gtt) | ||
1439 | return -ENOMEM; | ||
1440 | |||
1441 | intel_private.gtt_total_size = gtt_size / 4; | ||
1442 | |||
1443 | intel_private.registers = ioremap(temp, 128 * 4096); | ||
1444 | if (!intel_private.registers) { | ||
1445 | iounmap(intel_private.gtt); | ||
1446 | return -ENOMEM; | ||
1447 | } | ||
1448 | |||
1449 | temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; | ||
1450 | global_cache_flush(); /* FIXME: ? */ | ||
1451 | |||
1452 | /* we have to call this as early as possible after the MMIO base address is known */ | ||
1453 | intel_i830_init_gtt_entries(); | ||
1454 | if (intel_private.gtt_entries == 0) { | ||
1455 | iounmap(intel_private.gtt); | ||
1456 | iounmap(intel_private.registers); | ||
1457 | return -ENOMEM; | ||
1458 | } | ||
1459 | |||
1460 | agp_bridge->gatt_table = NULL; | ||
1461 | |||
1462 | agp_bridge->gatt_bus_addr = temp; | ||
1463 | |||
1464 | return 0; | ||
1465 | } | ||
1466 | |||
1467 | static const struct agp_bridge_driver intel_810_driver = { | 1341 | static const struct agp_bridge_driver intel_810_driver = { |
1468 | .owner = THIS_MODULE, | 1342 | .owner = THIS_MODULE, |
1469 | .aperture_sizes = intel_i810_sizes, | 1343 | .aperture_sizes = intel_i810_sizes, |
@@ -1475,7 +1349,7 @@ static const struct agp_bridge_driver intel_810_driver = { | |||
1475 | .cleanup = intel_i810_cleanup, | 1349 | .cleanup = intel_i810_cleanup, |
1476 | .mask_memory = intel_i810_mask_memory, | 1350 | .mask_memory = intel_i810_mask_memory, |
1477 | .masks = intel_i810_masks, | 1351 | .masks = intel_i810_masks, |
1478 | .agp_enable = intel_i810_agp_enable, | 1352 | .agp_enable = intel_fake_agp_enable, |
1479 | .cache_flush = global_cache_flush, | 1353 | .cache_flush = global_cache_flush, |
1480 | .create_gatt_table = agp_generic_create_gatt_table, | 1354 | .create_gatt_table = agp_generic_create_gatt_table, |
1481 | .free_gatt_table = agp_generic_free_gatt_table, | 1355 | .free_gatt_table = agp_generic_free_gatt_table, |
@@ -1492,22 +1366,22 @@ static const struct agp_bridge_driver intel_810_driver = { | |||
1492 | 1366 | ||
1493 | static const struct agp_bridge_driver intel_830_driver = { | 1367 | static const struct agp_bridge_driver intel_830_driver = { |
1494 | .owner = THIS_MODULE, | 1368 | .owner = THIS_MODULE, |
1495 | .aperture_sizes = intel_i830_sizes, | ||
1496 | .size_type = FIXED_APER_SIZE, | 1369 | .size_type = FIXED_APER_SIZE, |
1497 | .num_aperture_sizes = 4, | 1370 | .aperture_sizes = intel_fake_agp_sizes, |
1371 | .num_aperture_sizes = ARRAY_SIZE(intel_fake_agp_sizes), | ||
1498 | .needs_scratch_page = true, | 1372 | .needs_scratch_page = true, |
1499 | .configure = intel_i830_configure, | 1373 | .configure = intel_i830_configure, |
1500 | .fetch_size = intel_i830_fetch_size, | 1374 | .fetch_size = intel_fake_agp_fetch_size, |
1501 | .cleanup = intel_i830_cleanup, | 1375 | .cleanup = intel_gtt_cleanup, |
1502 | .mask_memory = intel_i810_mask_memory, | 1376 | .mask_memory = intel_i810_mask_memory, |
1503 | .masks = intel_i810_masks, | 1377 | .masks = intel_i810_masks, |
1504 | .agp_enable = intel_i810_agp_enable, | 1378 | .agp_enable = intel_fake_agp_enable, |
1505 | .cache_flush = global_cache_flush, | 1379 | .cache_flush = global_cache_flush, |
1506 | .create_gatt_table = intel_i830_create_gatt_table, | 1380 | .create_gatt_table = intel_fake_agp_create_gatt_table, |
1507 | .free_gatt_table = intel_i830_free_gatt_table, | 1381 | .free_gatt_table = intel_fake_agp_free_gatt_table, |
1508 | .insert_memory = intel_i830_insert_entries, | 1382 | .insert_memory = intel_i830_insert_entries, |
1509 | .remove_memory = intel_i830_remove_entries, | 1383 | .remove_memory = intel_i830_remove_entries, |
1510 | .alloc_by_type = intel_i830_alloc_by_type, | 1384 | .alloc_by_type = intel_fake_agp_alloc_by_type, |
1511 | .free_by_type = intel_i810_free_by_type, | 1385 | .free_by_type = intel_i810_free_by_type, |
1512 | .agp_alloc_page = agp_generic_alloc_page, | 1386 | .agp_alloc_page = agp_generic_alloc_page, |
1513 | .agp_alloc_pages = agp_generic_alloc_pages, | 1387 | .agp_alloc_pages = agp_generic_alloc_pages, |
@@ -1519,22 +1393,22 @@ static const struct agp_bridge_driver intel_830_driver = { | |||
1519 | 1393 | ||
1520 | static const struct agp_bridge_driver intel_915_driver = { | 1394 | static const struct agp_bridge_driver intel_915_driver = { |
1521 | .owner = THIS_MODULE, | 1395 | .owner = THIS_MODULE, |
1522 | .aperture_sizes = intel_i830_sizes, | ||
1523 | .size_type = FIXED_APER_SIZE, | 1396 | .size_type = FIXED_APER_SIZE, |
1524 | .num_aperture_sizes = 4, | 1397 | .aperture_sizes = intel_fake_agp_sizes, |
1398 | .num_aperture_sizes = ARRAY_SIZE(intel_fake_agp_sizes), | ||
1525 | .needs_scratch_page = true, | 1399 | .needs_scratch_page = true, |
1526 | .configure = intel_i9xx_configure, | 1400 | .configure = intel_i9xx_configure, |
1527 | .fetch_size = intel_i9xx_fetch_size, | 1401 | .fetch_size = intel_fake_agp_fetch_size, |
1528 | .cleanup = intel_i915_cleanup, | 1402 | .cleanup = intel_gtt_cleanup, |
1529 | .mask_memory = intel_i810_mask_memory, | 1403 | .mask_memory = intel_i810_mask_memory, |
1530 | .masks = intel_i810_masks, | 1404 | .masks = intel_i810_masks, |
1531 | .agp_enable = intel_i810_agp_enable, | 1405 | .agp_enable = intel_fake_agp_enable, |
1532 | .cache_flush = global_cache_flush, | 1406 | .cache_flush = global_cache_flush, |
1533 | .create_gatt_table = intel_i915_create_gatt_table, | 1407 | .create_gatt_table = intel_fake_agp_create_gatt_table, |
1534 | .free_gatt_table = intel_i830_free_gatt_table, | 1408 | .free_gatt_table = intel_fake_agp_free_gatt_table, |
1535 | .insert_memory = intel_i915_insert_entries, | 1409 | .insert_memory = intel_i915_insert_entries, |
1536 | .remove_memory = intel_i915_remove_entries, | 1410 | .remove_memory = intel_i915_remove_entries, |
1537 | .alloc_by_type = intel_i830_alloc_by_type, | 1411 | .alloc_by_type = intel_fake_agp_alloc_by_type, |
1538 | .free_by_type = intel_i810_free_by_type, | 1412 | .free_by_type = intel_i810_free_by_type, |
1539 | .agp_alloc_page = agp_generic_alloc_page, | 1413 | .agp_alloc_page = agp_generic_alloc_page, |
1540 | .agp_alloc_pages = agp_generic_alloc_pages, | 1414 | .agp_alloc_pages = agp_generic_alloc_pages, |
@@ -1552,22 +1426,22 @@ static const struct agp_bridge_driver intel_915_driver = { | |||
1552 | 1426 | ||
1553 | static const struct agp_bridge_driver intel_i965_driver = { | 1427 | static const struct agp_bridge_driver intel_i965_driver = { |
1554 | .owner = THIS_MODULE, | 1428 | .owner = THIS_MODULE, |
1555 | .aperture_sizes = intel_i830_sizes, | ||
1556 | .size_type = FIXED_APER_SIZE, | 1429 | .size_type = FIXED_APER_SIZE, |
1557 | .num_aperture_sizes = 4, | 1430 | .aperture_sizes = intel_fake_agp_sizes, |
1431 | .num_aperture_sizes = ARRAY_SIZE(intel_fake_agp_sizes), | ||
1558 | .needs_scratch_page = true, | 1432 | .needs_scratch_page = true, |
1559 | .configure = intel_i9xx_configure, | 1433 | .configure = intel_i9xx_configure, |
1560 | .fetch_size = intel_i9xx_fetch_size, | 1434 | .fetch_size = intel_fake_agp_fetch_size, |
1561 | .cleanup = intel_i915_cleanup, | 1435 | .cleanup = intel_gtt_cleanup, |
1562 | .mask_memory = intel_i965_mask_memory, | 1436 | .mask_memory = intel_i965_mask_memory, |
1563 | .masks = intel_i810_masks, | 1437 | .masks = intel_i810_masks, |
1564 | .agp_enable = intel_i810_agp_enable, | 1438 | .agp_enable = intel_fake_agp_enable, |
1565 | .cache_flush = global_cache_flush, | 1439 | .cache_flush = global_cache_flush, |
1566 | .create_gatt_table = intel_i965_create_gatt_table, | 1440 | .create_gatt_table = intel_fake_agp_create_gatt_table, |
1567 | .free_gatt_table = intel_i830_free_gatt_table, | 1441 | .free_gatt_table = intel_fake_agp_free_gatt_table, |
1568 | .insert_memory = intel_i915_insert_entries, | 1442 | .insert_memory = intel_i915_insert_entries, |
1569 | .remove_memory = intel_i915_remove_entries, | 1443 | .remove_memory = intel_i915_remove_entries, |
1570 | .alloc_by_type = intel_i830_alloc_by_type, | 1444 | .alloc_by_type = intel_fake_agp_alloc_by_type, |
1571 | .free_by_type = intel_i810_free_by_type, | 1445 | .free_by_type = intel_i810_free_by_type, |
1572 | .agp_alloc_page = agp_generic_alloc_page, | 1446 | .agp_alloc_page = agp_generic_alloc_page, |
1573 | .agp_alloc_pages = agp_generic_alloc_pages, | 1447 | .agp_alloc_pages = agp_generic_alloc_pages, |
@@ -1585,22 +1459,22 @@ static const struct agp_bridge_driver intel_i965_driver = { | |||
1585 | 1459 | ||
1586 | static const struct agp_bridge_driver intel_gen6_driver = { | 1460 | static const struct agp_bridge_driver intel_gen6_driver = { |
1587 | .owner = THIS_MODULE, | 1461 | .owner = THIS_MODULE, |
1588 | .aperture_sizes = intel_i830_sizes, | ||
1589 | .size_type = FIXED_APER_SIZE, | 1462 | .size_type = FIXED_APER_SIZE, |
1590 | .num_aperture_sizes = 4, | 1463 | .aperture_sizes = intel_fake_agp_sizes, |
1464 | .num_aperture_sizes = ARRAY_SIZE(intel_fake_agp_sizes), | ||
1591 | .needs_scratch_page = true, | 1465 | .needs_scratch_page = true, |
1592 | .configure = intel_i9xx_configure, | 1466 | .configure = intel_i9xx_configure, |
1593 | .fetch_size = intel_i9xx_fetch_size, | 1467 | .fetch_size = intel_fake_agp_fetch_size, |
1594 | .cleanup = intel_i915_cleanup, | 1468 | .cleanup = intel_gtt_cleanup, |
1595 | .mask_memory = intel_gen6_mask_memory, | 1469 | .mask_memory = intel_gen6_mask_memory, |
1596 | .masks = intel_gen6_masks, | 1470 | .masks = intel_gen6_masks, |
1597 | .agp_enable = intel_i810_agp_enable, | 1471 | .agp_enable = intel_fake_agp_enable, |
1598 | .cache_flush = global_cache_flush, | 1472 | .cache_flush = global_cache_flush, |
1599 | .create_gatt_table = intel_i965_create_gatt_table, | 1473 | .create_gatt_table = intel_fake_agp_create_gatt_table, |
1600 | .free_gatt_table = intel_i830_free_gatt_table, | 1474 | .free_gatt_table = intel_fake_agp_free_gatt_table, |
1601 | .insert_memory = intel_i915_insert_entries, | 1475 | .insert_memory = intel_i915_insert_entries, |
1602 | .remove_memory = intel_i915_remove_entries, | 1476 | .remove_memory = intel_i915_remove_entries, |
1603 | .alloc_by_type = intel_i830_alloc_by_type, | 1477 | .alloc_by_type = intel_fake_agp_alloc_by_type, |
1604 | .free_by_type = intel_i810_free_by_type, | 1478 | .free_by_type = intel_i810_free_by_type, |
1605 | .agp_alloc_page = agp_generic_alloc_page, | 1479 | .agp_alloc_page = agp_generic_alloc_page, |
1606 | .agp_alloc_pages = agp_generic_alloc_pages, | 1480 | .agp_alloc_pages = agp_generic_alloc_pages, |
@@ -1618,22 +1492,22 @@ static const struct agp_bridge_driver intel_gen6_driver = { | |||
1618 | 1492 | ||
1619 | static const struct agp_bridge_driver intel_g33_driver = { | 1493 | static const struct agp_bridge_driver intel_g33_driver = { |
1620 | .owner = THIS_MODULE, | 1494 | .owner = THIS_MODULE, |
1621 | .aperture_sizes = intel_i830_sizes, | ||
1622 | .size_type = FIXED_APER_SIZE, | 1495 | .size_type = FIXED_APER_SIZE, |
1623 | .num_aperture_sizes = 4, | 1496 | .aperture_sizes = intel_fake_agp_sizes, |
1497 | .num_aperture_sizes = ARRAY_SIZE(intel_fake_agp_sizes), | ||
1624 | .needs_scratch_page = true, | 1498 | .needs_scratch_page = true, |
1625 | .configure = intel_i9xx_configure, | 1499 | .configure = intel_i9xx_configure, |
1626 | .fetch_size = intel_i9xx_fetch_size, | 1500 | .fetch_size = intel_fake_agp_fetch_size, |
1627 | .cleanup = intel_i915_cleanup, | 1501 | .cleanup = intel_gtt_cleanup, |
1628 | .mask_memory = intel_i965_mask_memory, | 1502 | .mask_memory = intel_i965_mask_memory, |
1629 | .masks = intel_i810_masks, | 1503 | .masks = intel_i810_masks, |
1630 | .agp_enable = intel_i810_agp_enable, | 1504 | .agp_enable = intel_fake_agp_enable, |
1631 | .cache_flush = global_cache_flush, | 1505 | .cache_flush = global_cache_flush, |
1632 | .create_gatt_table = intel_i915_create_gatt_table, | 1506 | .create_gatt_table = intel_fake_agp_create_gatt_table, |
1633 | .free_gatt_table = intel_i830_free_gatt_table, | 1507 | .free_gatt_table = intel_fake_agp_free_gatt_table, |
1634 | .insert_memory = intel_i915_insert_entries, | 1508 | .insert_memory = intel_i915_insert_entries, |
1635 | .remove_memory = intel_i915_remove_entries, | 1509 | .remove_memory = intel_i915_remove_entries, |
1636 | .alloc_by_type = intel_i830_alloc_by_type, | 1510 | .alloc_by_type = intel_fake_agp_alloc_by_type, |
1637 | .free_by_type = intel_i810_free_by_type, | 1511 | .free_by_type = intel_i810_free_by_type, |
1638 | .agp_alloc_page = agp_generic_alloc_page, | 1512 | .agp_alloc_page = agp_generic_alloc_page, |
1639 | .agp_alloc_pages = agp_generic_alloc_pages, | 1513 | .agp_alloc_pages = agp_generic_alloc_pages, |
@@ -1648,3 +1522,217 @@ static const struct agp_bridge_driver intel_g33_driver = { | |||
1648 | .agp_unmap_memory = intel_agp_unmap_memory, | 1522 | .agp_unmap_memory = intel_agp_unmap_memory, |
1649 | #endif | 1523 | #endif |
1650 | }; | 1524 | }; |
1525 | |||
1526 | static const struct intel_gtt_driver i8xx_gtt_driver = { | ||
1527 | .gen = 2, | ||
1528 | .setup = i830_setup, | ||
1529 | }; | ||
1530 | static const struct intel_gtt_driver i915_gtt_driver = { | ||
1531 | .gen = 3, | ||
1532 | .setup = i9xx_setup, | ||
1533 | }; | ||
1534 | static const struct intel_gtt_driver g33_gtt_driver = { | ||
1535 | .gen = 3, | ||
1536 | .is_g33 = 1, | ||
1537 | .setup = i9xx_setup, | ||
1538 | }; | ||
1539 | static const struct intel_gtt_driver pineview_gtt_driver = { | ||
1540 | .gen = 3, | ||
1541 | .is_pineview = 1, .is_g33 = 1, | ||
1542 | .setup = i9xx_setup, | ||
1543 | }; | ||
1544 | static const struct intel_gtt_driver i965_gtt_driver = { | ||
1545 | .gen = 4, | ||
1546 | .setup = i9xx_setup, | ||
1547 | }; | ||
1548 | static const struct intel_gtt_driver g4x_gtt_driver = { | ||
1549 | .gen = 5, | ||
1550 | .setup = i9xx_setup, | ||
1551 | }; | ||
1552 | static const struct intel_gtt_driver ironlake_gtt_driver = { | ||
1553 | .gen = 5, | ||
1554 | .is_ironlake = 1, | ||
1555 | .setup = i9xx_setup, | ||
1556 | }; | ||
1557 | static const struct intel_gtt_driver sandybridge_gtt_driver = { | ||
1558 | .gen = 6, | ||
1559 | .setup = i9xx_setup, | ||
1560 | }; | ||
1561 | |||
1562 | /* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of | ||
1563 | * driver and gmch_driver must be non-null, and find_gmch will determine | ||
1564 | * which one should be used if a gmch_chip_id is present. | ||
1565 | */ | ||
1566 | static const struct intel_gtt_driver_description { | ||
1567 | unsigned int gmch_chip_id; | ||
1568 | char *name; | ||
1569 | const struct agp_bridge_driver *gmch_driver; | ||
1570 | const struct intel_gtt_driver *gtt_driver; | ||
1571 | } intel_gtt_chipsets[] = { | ||
1572 | { PCI_DEVICE_ID_INTEL_82810_IG1, "i810", &intel_810_driver , NULL}, | ||
1573 | { PCI_DEVICE_ID_INTEL_82810_IG3, "i810", &intel_810_driver , NULL}, | ||
1574 | { PCI_DEVICE_ID_INTEL_82810E_IG, "i810", &intel_810_driver , NULL}, | ||
1575 | { PCI_DEVICE_ID_INTEL_82815_CGC, "i815", &intel_810_driver , NULL}, | ||
1576 | { PCI_DEVICE_ID_INTEL_82830_CGC, "830M", | ||
1577 | &intel_830_driver , &i8xx_gtt_driver}, | ||
1578 | { PCI_DEVICE_ID_INTEL_82845G_IG, "830M", | ||
1579 | &intel_830_driver , &i8xx_gtt_driver}, | ||
1580 | { PCI_DEVICE_ID_INTEL_82854_IG, "854", | ||
1581 | &intel_830_driver , &i8xx_gtt_driver}, | ||
1582 | { PCI_DEVICE_ID_INTEL_82855GM_IG, "855GM", | ||
1583 | &intel_830_driver , &i8xx_gtt_driver}, | ||
1584 | { PCI_DEVICE_ID_INTEL_82865_IG, "865", | ||
1585 | &intel_830_driver , &i8xx_gtt_driver}, | ||
1586 | { PCI_DEVICE_ID_INTEL_E7221_IG, "E7221 (i915)", | ||
1587 | &intel_915_driver , &i915_gtt_driver }, | ||
1588 | { PCI_DEVICE_ID_INTEL_82915G_IG, "915G", | ||
1589 | &intel_915_driver , &i915_gtt_driver }, | ||
1590 | { PCI_DEVICE_ID_INTEL_82915GM_IG, "915GM", | ||
1591 | &intel_915_driver , &i915_gtt_driver }, | ||
1592 | { PCI_DEVICE_ID_INTEL_82945G_IG, "945G", | ||
1593 | &intel_915_driver , &i915_gtt_driver }, | ||
1594 | { PCI_DEVICE_ID_INTEL_82945GM_IG, "945GM", | ||
1595 | &intel_915_driver , &i915_gtt_driver }, | ||
1596 | { PCI_DEVICE_ID_INTEL_82945GME_IG, "945GME", | ||
1597 | &intel_915_driver , &i915_gtt_driver }, | ||
1598 | { PCI_DEVICE_ID_INTEL_82946GZ_IG, "946GZ", | ||
1599 | &intel_i965_driver , &i965_gtt_driver }, | ||
1600 | { PCI_DEVICE_ID_INTEL_82G35_IG, "G35", | ||
1601 | &intel_i965_driver , &i965_gtt_driver }, | ||
1602 | { PCI_DEVICE_ID_INTEL_82965Q_IG, "965Q", | ||
1603 | &intel_i965_driver , &i965_gtt_driver }, | ||
1604 | { PCI_DEVICE_ID_INTEL_82965G_IG, "965G", | ||
1605 | &intel_i965_driver , &i965_gtt_driver }, | ||
1606 | { PCI_DEVICE_ID_INTEL_82965GM_IG, "965GM", | ||
1607 | &intel_i965_driver , &i965_gtt_driver }, | ||
1608 | { PCI_DEVICE_ID_INTEL_82965GME_IG, "965GME/GLE", | ||
1609 | &intel_i965_driver , &i965_gtt_driver }, | ||
1610 | { PCI_DEVICE_ID_INTEL_G33_IG, "G33", | ||
1611 | &intel_g33_driver , &g33_gtt_driver }, | ||
1612 | { PCI_DEVICE_ID_INTEL_Q35_IG, "Q35", | ||
1613 | &intel_g33_driver , &g33_gtt_driver }, | ||
1614 | { PCI_DEVICE_ID_INTEL_Q33_IG, "Q33", | ||
1615 | &intel_g33_driver , &g33_gtt_driver }, | ||
1616 | { PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, "GMA3150", | ||
1617 | &intel_g33_driver , &pineview_gtt_driver }, | ||
1618 | { PCI_DEVICE_ID_INTEL_PINEVIEW_IG, "GMA3150", | ||
1619 | &intel_g33_driver , &pineview_gtt_driver }, | ||
1620 | { PCI_DEVICE_ID_INTEL_GM45_IG, "GM45", | ||
1621 | &intel_i965_driver , &g4x_gtt_driver }, | ||
1622 | { PCI_DEVICE_ID_INTEL_EAGLELAKE_IG, "Eaglelake", | ||
1623 | &intel_i965_driver , &g4x_gtt_driver }, | ||
1624 | { PCI_DEVICE_ID_INTEL_Q45_IG, "Q45/Q43", | ||
1625 | &intel_i965_driver , &g4x_gtt_driver }, | ||
1626 | { PCI_DEVICE_ID_INTEL_G45_IG, "G45/G43", | ||
1627 | &intel_i965_driver , &g4x_gtt_driver }, | ||
1628 | { PCI_DEVICE_ID_INTEL_B43_IG, "B43", | ||
1629 | &intel_i965_driver , &g4x_gtt_driver }, | ||
1630 | { PCI_DEVICE_ID_INTEL_B43_1_IG, "B43", | ||
1631 | &intel_i965_driver , &g4x_gtt_driver }, | ||
1632 | { PCI_DEVICE_ID_INTEL_G41_IG, "G41", | ||
1633 | &intel_i965_driver , &g4x_gtt_driver }, | ||
1634 | { PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, | ||
1635 | "HD Graphics", &intel_i965_driver , &ironlake_gtt_driver }, | ||
1636 | { PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, | ||
1637 | "HD Graphics", &intel_i965_driver , &ironlake_gtt_driver }, | ||
1638 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG, | ||
1639 | "Sandybridge", &intel_gen6_driver , &sandybridge_gtt_driver }, | ||
1640 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG, | ||
1641 | "Sandybridge", &intel_gen6_driver , &sandybridge_gtt_driver }, | ||
1642 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG, | ||
1643 | "Sandybridge", &intel_gen6_driver , &sandybridge_gtt_driver }, | ||
1644 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG, | ||
1645 | "Sandybridge", &intel_gen6_driver , &sandybridge_gtt_driver }, | ||
1646 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG, | ||
1647 | "Sandybridge", &intel_gen6_driver , &sandybridge_gtt_driver }, | ||
1648 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG, | ||
1649 | "Sandybridge", &intel_gen6_driver , &sandybridge_gtt_driver }, | ||
1650 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG, | ||
1651 | "Sandybridge", &intel_gen6_driver , &sandybridge_gtt_driver }, | ||
1652 | { 0, NULL, NULL } | ||
1653 | }; | ||
1654 | |||
1655 | static int find_gmch(u16 device) | ||
1656 | { | ||
1657 | struct pci_dev *gmch_device; | ||
1658 | |||
1659 | gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL); | ||
1660 | if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) { | ||
1661 | gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
1662 | device, gmch_device); | ||
1663 | } | ||
1664 | |||
1665 | if (!gmch_device) | ||
1666 | return 0; | ||
1667 | |||
1668 | intel_private.pcidev = gmch_device; | ||
1669 | return 1; | ||
1670 | } | ||
1671 | |||
1672 | int intel_gmch_probe(struct pci_dev *pdev, | ||
1673 | struct agp_bridge_data *bridge) | ||
1674 | { | ||
1675 | int i, mask; | ||
1676 | bridge->driver = NULL; | ||
1677 | |||
1678 | for (i = 0; intel_gtt_chipsets[i].name != NULL; i++) { | ||
1679 | if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) { | ||
1680 | bridge->driver = | ||
1681 | intel_gtt_chipsets[i].gmch_driver; | ||
1682 | intel_private.driver = | ||
1683 | intel_gtt_chipsets[i].gtt_driver; | ||
1684 | break; | ||
1685 | } | ||
1686 | } | ||
1687 | |||
1688 | if (!bridge->driver) | ||
1689 | return 0; | ||
1690 | |||
1691 | bridge->dev_private_data = &intel_private; | ||
1692 | bridge->dev = pdev; | ||
1693 | |||
1694 | intel_private.bridge_dev = pci_dev_get(pdev); | ||
1695 | |||
1696 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_gtt_chipsets[i].name); | ||
1697 | |||
1698 | if (bridge->driver->mask_memory == intel_gen6_mask_memory) | ||
1699 | mask = 40; | ||
1700 | else if (bridge->driver->mask_memory == intel_i965_mask_memory) | ||
1701 | mask = 36; | ||
1702 | else | ||
1703 | mask = 32; | ||
1704 | |||
1705 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask))) | ||
1706 | dev_err(&intel_private.pcidev->dev, | ||
1707 | "set gfx device dma mask %d-bit failed!\n", mask); | ||
1708 | else | ||
1709 | pci_set_consistent_dma_mask(intel_private.pcidev, | ||
1710 | DMA_BIT_MASK(mask)); | ||
1711 | |||
1712 | if (bridge->driver == &intel_810_driver) | ||
1713 | return 1; | ||
1714 | |||
1715 | if (intel_gtt_init() != 0) | ||
1716 | return 0; | ||
1717 | |||
1718 | return 1; | ||
1719 | } | ||
1720 | EXPORT_SYMBOL(intel_gmch_probe); | ||
1721 | |||
1722 | struct intel_gtt *intel_gtt_get(void) | ||
1723 | { | ||
1724 | return &intel_private.base; | ||
1725 | } | ||
1726 | EXPORT_SYMBOL(intel_gtt_get); | ||
1727 | |||
1728 | void intel_gmch_remove(struct pci_dev *pdev) | ||
1729 | { | ||
1730 | if (intel_private.pcidev) | ||
1731 | pci_dev_put(intel_private.pcidev); | ||
1732 | if (intel_private.bridge_dev) | ||
1733 | pci_dev_put(intel_private.bridge_dev); | ||
1734 | } | ||
1735 | EXPORT_SYMBOL(intel_gmch_remove); | ||
1736 | |||
1737 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); | ||
1738 | MODULE_LICENSE("GPL and additional rights"); | ||
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index f3a23a329f4e..997c43d04909 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | ccflags-y := -Iinclude/drm | 5 | ccflags-y := -Iinclude/drm |
6 | 6 | ||
7 | drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ | 7 | drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ |
8 | drm_context.o drm_dma.o drm_drawable.o \ | 8 | drm_context.o drm_dma.o \ |
9 | drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ | 9 | drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ |
10 | drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ | 10 | drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ |
11 | drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ | 11 | drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ |
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c index ba38e0147220..252fdb98b73a 100644 --- a/drivers/gpu/drm/drm_agpsupport.c +++ b/drivers/gpu/drm/drm_agpsupport.c | |||
@@ -193,7 +193,7 @@ int drm_agp_enable_ioctl(struct drm_device *dev, void *data, | |||
193 | * \return zero on success or a negative number on failure. | 193 | * \return zero on success or a negative number on failure. |
194 | * | 194 | * |
195 | * Verifies the AGP device is present and has been acquired, allocates the | 195 | * Verifies the AGP device is present and has been acquired, allocates the |
196 | * memory via alloc_agp() and creates a drm_agp_mem entry for it. | 196 | * memory via agp_allocate_memory() and creates a drm_agp_mem entry for it. |
197 | */ | 197 | */ |
198 | int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request) | 198 | int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request) |
199 | { | 199 | { |
@@ -211,7 +211,7 @@ int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request) | |||
211 | 211 | ||
212 | pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; | 212 | pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; |
213 | type = (u32) request->type; | 213 | type = (u32) request->type; |
214 | if (!(memory = drm_alloc_agp(dev, pages, type))) { | 214 | if (!(memory = agp_allocate_memory(dev->agp->bridge, pages, type))) { |
215 | kfree(entry); | 215 | kfree(entry); |
216 | return -ENOMEM; | 216 | return -ENOMEM; |
217 | } | 217 | } |
@@ -423,38 +423,6 @@ struct drm_agp_head *drm_agp_init(struct drm_device *dev) | |||
423 | return head; | 423 | return head; |
424 | } | 424 | } |
425 | 425 | ||
426 | /** Calls agp_allocate_memory() */ | ||
427 | DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data * bridge, | ||
428 | size_t pages, u32 type) | ||
429 | { | ||
430 | return agp_allocate_memory(bridge, pages, type); | ||
431 | } | ||
432 | |||
433 | /** Calls agp_free_memory() */ | ||
434 | int drm_agp_free_memory(DRM_AGP_MEM * handle) | ||
435 | { | ||
436 | if (!handle) | ||
437 | return 0; | ||
438 | agp_free_memory(handle); | ||
439 | return 1; | ||
440 | } | ||
441 | |||
442 | /** Calls agp_bind_memory() */ | ||
443 | int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start) | ||
444 | { | ||
445 | if (!handle) | ||
446 | return -EINVAL; | ||
447 | return agp_bind_memory(handle, start); | ||
448 | } | ||
449 | |||
450 | /** Calls agp_unbind_memory() */ | ||
451 | int drm_agp_unbind_memory(DRM_AGP_MEM * handle) | ||
452 | { | ||
453 | if (!handle) | ||
454 | return -EINVAL; | ||
455 | return agp_unbind_memory(handle); | ||
456 | } | ||
457 | |||
458 | /** | 426 | /** |
459 | * Binds a collection of pages into AGP memory at the given offset, returning | 427 | * Binds a collection of pages into AGP memory at the given offset, returning |
460 | * the AGP memory structure containing them. | 428 | * the AGP memory structure containing them. |
@@ -474,7 +442,7 @@ drm_agp_bind_pages(struct drm_device *dev, | |||
474 | 442 | ||
475 | DRM_DEBUG("\n"); | 443 | DRM_DEBUG("\n"); |
476 | 444 | ||
477 | mem = drm_agp_allocate_memory(dev->agp->bridge, num_pages, | 445 | mem = agp_allocate_memory(dev->agp->bridge, num_pages, |
478 | type); | 446 | type); |
479 | if (mem == NULL) { | 447 | if (mem == NULL) { |
480 | DRM_ERROR("Failed to allocate memory for %ld pages\n", | 448 | DRM_ERROR("Failed to allocate memory for %ld pages\n", |
@@ -487,7 +455,7 @@ drm_agp_bind_pages(struct drm_device *dev, | |||
487 | mem->page_count = num_pages; | 455 | mem->page_count = num_pages; |
488 | 456 | ||
489 | mem->is_flushed = true; | 457 | mem->is_flushed = true; |
490 | ret = drm_agp_bind_memory(mem, gtt_offset / PAGE_SIZE); | 458 | ret = agp_bind_memory(mem, gtt_offset / PAGE_SIZE); |
491 | if (ret != 0) { | 459 | if (ret != 0) { |
492 | DRM_ERROR("Failed to bind AGP memory: %d\n", ret); | 460 | DRM_ERROR("Failed to bind AGP memory: %d\n", ret); |
493 | agp_free_memory(mem); | 461 | agp_free_memory(mem); |
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c index 2607753a320b..6d440fb894cf 100644 --- a/drivers/gpu/drm/drm_context.c +++ b/drivers/gpu/drm/drm_context.c | |||
@@ -333,14 +333,6 @@ int drm_addctx(struct drm_device *dev, void *data, | |||
333 | return -ENOMEM; | 333 | return -ENOMEM; |
334 | } | 334 | } |
335 | 335 | ||
336 | if (ctx->handle != DRM_KERNEL_CONTEXT) { | ||
337 | if (dev->driver->context_ctor) | ||
338 | if (!dev->driver->context_ctor(dev, ctx->handle)) { | ||
339 | DRM_DEBUG("Running out of ctxs or memory.\n"); | ||
340 | return -ENOMEM; | ||
341 | } | ||
342 | } | ||
343 | |||
344 | ctx_entry = kmalloc(sizeof(*ctx_entry), GFP_KERNEL); | 336 | ctx_entry = kmalloc(sizeof(*ctx_entry), GFP_KERNEL); |
345 | if (!ctx_entry) { | 337 | if (!ctx_entry) { |
346 | DRM_DEBUG("out of memory\n"); | 338 | DRM_DEBUG("out of memory\n"); |
diff --git a/drivers/gpu/drm/drm_drawable.c b/drivers/gpu/drm/drm_drawable.c deleted file mode 100644 index c53c9768cc11..000000000000 --- a/drivers/gpu/drm/drm_drawable.c +++ /dev/null | |||
@@ -1,198 +0,0 @@ | |||
1 | /** | ||
2 | * \file drm_drawable.c | ||
3 | * IOCTLs for drawables | ||
4 | * | ||
5 | * \author Rickard E. (Rik) Faith <faith@valinux.com> | ||
6 | * \author Gareth Hughes <gareth@valinux.com> | ||
7 | * \author Michel Dänzer <michel@tungstengraphics.com> | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com | ||
12 | * | ||
13 | * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | ||
14 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | ||
15 | * Copyright 2006 Tungsten Graphics, Inc., Bismarck, North Dakota. | ||
16 | * All Rights Reserved. | ||
17 | * | ||
18 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
19 | * copy of this software and associated documentation files (the "Software"), | ||
20 | * to deal in the Software without restriction, including without limitation | ||
21 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
22 | * and/or sell copies of the Software, and to permit persons to whom the | ||
23 | * Software is furnished to do so, subject to the following conditions: | ||
24 | * | ||
25 | * The above copyright notice and this permission notice (including the next | ||
26 | * paragraph) shall be included in all copies or substantial portions of the | ||
27 | * Software. | ||
28 | * | ||
29 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
30 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
31 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
32 | * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
33 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
34 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
35 | * OTHER DEALINGS IN THE SOFTWARE. | ||
36 | */ | ||
37 | |||
38 | #include "drmP.h" | ||
39 | |||
40 | /** | ||
41 | * Allocate drawable ID and memory to store information about it. | ||
42 | */ | ||
43 | int drm_adddraw(struct drm_device *dev, void *data, struct drm_file *file_priv) | ||
44 | { | ||
45 | unsigned long irqflags; | ||
46 | struct drm_draw *draw = data; | ||
47 | int new_id = 0; | ||
48 | int ret; | ||
49 | |||
50 | again: | ||
51 | if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) { | ||
52 | DRM_ERROR("Out of memory expanding drawable idr\n"); | ||
53 | return -ENOMEM; | ||
54 | } | ||
55 | |||
56 | spin_lock_irqsave(&dev->drw_lock, irqflags); | ||
57 | ret = idr_get_new_above(&dev->drw_idr, NULL, 1, &new_id); | ||
58 | if (ret == -EAGAIN) { | ||
59 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
60 | goto again; | ||
61 | } | ||
62 | |||
63 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
64 | |||
65 | draw->handle = new_id; | ||
66 | |||
67 | DRM_DEBUG("%d\n", draw->handle); | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * Free drawable ID and memory to store information about it. | ||
74 | */ | ||
75 | int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv) | ||
76 | { | ||
77 | struct drm_draw *draw = data; | ||
78 | unsigned long irqflags; | ||
79 | struct drm_drawable_info *info; | ||
80 | |||
81 | spin_lock_irqsave(&dev->drw_lock, irqflags); | ||
82 | |||
83 | info = drm_get_drawable_info(dev, draw->handle); | ||
84 | if (info == NULL) { | ||
85 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | kfree(info->rects); | ||
89 | kfree(info); | ||
90 | |||
91 | idr_remove(&dev->drw_idr, draw->handle); | ||
92 | |||
93 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
94 | DRM_DEBUG("%d\n", draw->handle); | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file *file_priv) | ||
99 | { | ||
100 | struct drm_update_draw *update = data; | ||
101 | unsigned long irqflags; | ||
102 | struct drm_clip_rect *rects; | ||
103 | struct drm_drawable_info *info; | ||
104 | int err; | ||
105 | |||
106 | info = idr_find(&dev->drw_idr, update->handle); | ||
107 | if (!info) { | ||
108 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
109 | if (!info) | ||
110 | return -ENOMEM; | ||
111 | if (IS_ERR(idr_replace(&dev->drw_idr, info, update->handle))) { | ||
112 | DRM_ERROR("No such drawable %d\n", update->handle); | ||
113 | kfree(info); | ||
114 | return -EINVAL; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | switch (update->type) { | ||
119 | case DRM_DRAWABLE_CLIPRECTS: | ||
120 | if (update->num == 0) | ||
121 | rects = NULL; | ||
122 | else if (update->num != info->num_rects) { | ||
123 | rects = kmalloc(update->num * | ||
124 | sizeof(struct drm_clip_rect), | ||
125 | GFP_KERNEL); | ||
126 | } else | ||
127 | rects = info->rects; | ||
128 | |||
129 | if (update->num && !rects) { | ||
130 | DRM_ERROR("Failed to allocate cliprect memory\n"); | ||
131 | err = -ENOMEM; | ||
132 | goto error; | ||
133 | } | ||
134 | |||
135 | if (update->num && DRM_COPY_FROM_USER(rects, | ||
136 | (struct drm_clip_rect __user *) | ||
137 | (unsigned long)update->data, | ||
138 | update->num * | ||
139 | sizeof(*rects))) { | ||
140 | DRM_ERROR("Failed to copy cliprects from userspace\n"); | ||
141 | err = -EFAULT; | ||
142 | goto error; | ||
143 | } | ||
144 | |||
145 | spin_lock_irqsave(&dev->drw_lock, irqflags); | ||
146 | |||
147 | if (rects != info->rects) { | ||
148 | kfree(info->rects); | ||
149 | } | ||
150 | |||
151 | info->rects = rects; | ||
152 | info->num_rects = update->num; | ||
153 | |||
154 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
155 | |||
156 | DRM_DEBUG("Updated %d cliprects for drawable %d\n", | ||
157 | info->num_rects, update->handle); | ||
158 | break; | ||
159 | default: | ||
160 | DRM_ERROR("Invalid update type %d\n", update->type); | ||
161 | return -EINVAL; | ||
162 | } | ||
163 | |||
164 | return 0; | ||
165 | |||
166 | error: | ||
167 | if (rects != info->rects) | ||
168 | kfree(rects); | ||
169 | |||
170 | return err; | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * Caller must hold the drawable spinlock! | ||
175 | */ | ||
176 | struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev, drm_drawable_t id) | ||
177 | { | ||
178 | return idr_find(&dev->drw_idr, id); | ||
179 | } | ||
180 | EXPORT_SYMBOL(drm_get_drawable_info); | ||
181 | |||
182 | static int drm_drawable_free(int idr, void *p, void *data) | ||
183 | { | ||
184 | struct drm_drawable_info *info = p; | ||
185 | |||
186 | if (info) { | ||
187 | kfree(info->rects); | ||
188 | kfree(info); | ||
189 | } | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | void drm_drawable_free_all(struct drm_device *dev) | ||
195 | { | ||
196 | idr_for_each(&dev->drw_idr, drm_drawable_free, NULL); | ||
197 | idr_remove_all(&dev->drw_idr); | ||
198 | } | ||
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 84da748555bc..5ff75a3a6b9d 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -91,8 +91,8 @@ static struct drm_ioctl_desc drm_ioctls[] = { | |||
91 | DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 91 | DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
92 | DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH), | 92 | DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH), |
93 | 93 | ||
94 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 94 | DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
95 | DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 95 | DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
96 | 96 | ||
97 | DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH), | 97 | DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH), |
98 | DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH), | 98 | DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH), |
@@ -127,7 +127,7 @@ static struct drm_ioctl_desc drm_ioctls[] = { | |||
127 | 127 | ||
128 | DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), | 128 | DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), |
129 | 129 | ||
130 | DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 130 | DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
131 | 131 | ||
132 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED), | 132 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED), |
133 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), | 133 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), |
@@ -180,10 +180,6 @@ int drm_lastclose(struct drm_device * dev) | |||
180 | 180 | ||
181 | mutex_lock(&dev->struct_mutex); | 181 | mutex_lock(&dev->struct_mutex); |
182 | 182 | ||
183 | /* Free drawable information memory */ | ||
184 | drm_drawable_free_all(dev); | ||
185 | del_timer(&dev->timer); | ||
186 | |||
187 | /* Clear AGP information */ | 183 | /* Clear AGP information */ |
188 | if (drm_core_has_AGP(dev) && dev->agp && | 184 | if (drm_core_has_AGP(dev) && dev->agp && |
189 | !drm_core_check_feature(dev, DRIVER_MODESET)) { | 185 | !drm_core_check_feature(dev, DRIVER_MODESET)) { |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 96e963108225..fd033ebbdf84 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
33 | #include <linux/i2c-algo-bit.h> | ||
34 | #include "drmP.h" | 33 | #include "drmP.h" |
35 | #include "drm_edid.h" | 34 | #include "drm_edid.h" |
36 | #include "drm_edid_modes.h" | 35 | #include "drm_edid_modes.h" |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index bf92d07510df..cff7317d3830 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -474,9 +474,7 @@ drm_gem_object_free_unlocked(struct kref *kref) | |||
474 | struct drm_gem_object *obj = (struct drm_gem_object *) kref; | 474 | struct drm_gem_object *obj = (struct drm_gem_object *) kref; |
475 | struct drm_device *dev = obj->dev; | 475 | struct drm_device *dev = obj->dev; |
476 | 476 | ||
477 | if (dev->driver->gem_free_object_unlocked != NULL) | 477 | if (dev->driver->gem_free_object != NULL) { |
478 | dev->driver->gem_free_object_unlocked(obj); | ||
479 | else if (dev->driver->gem_free_object != NULL) { | ||
480 | mutex_lock(&dev->struct_mutex); | 478 | mutex_lock(&dev->struct_mutex); |
481 | dev->driver->gem_free_object(obj); | 479 | dev->driver->gem_free_object(obj); |
482 | mutex_unlock(&dev->struct_mutex); | 480 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index 9bf93bc9a32c..1e28b9072068 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c | |||
@@ -37,6 +37,8 @@ | |||
37 | 37 | ||
38 | static int drm_notifier(void *priv); | 38 | static int drm_notifier(void *priv); |
39 | 39 | ||
40 | static int drm_lock_take(struct drm_lock_data *lock_data, unsigned int context); | ||
41 | |||
40 | /** | 42 | /** |
41 | * Lock ioctl. | 43 | * Lock ioctl. |
42 | * | 44 | * |
@@ -124,9 +126,6 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
124 | block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); | 126 | block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); |
125 | } | 127 | } |
126 | 128 | ||
127 | if (dev->driver->dma_ready && (lock->flags & _DRM_LOCK_READY)) | ||
128 | dev->driver->dma_ready(dev); | ||
129 | |||
130 | if (dev->driver->dma_quiescent && (lock->flags & _DRM_LOCK_QUIESCENT)) | 129 | if (dev->driver->dma_quiescent && (lock->flags & _DRM_LOCK_QUIESCENT)) |
131 | { | 130 | { |
132 | if (dev->driver->dma_quiescent(dev)) { | 131 | if (dev->driver->dma_quiescent(dev)) { |
@@ -136,12 +135,6 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
136 | } | 135 | } |
137 | } | 136 | } |
138 | 137 | ||
139 | if (dev->driver->kernel_context_switch && | ||
140 | dev->last_context != lock->context) { | ||
141 | dev->driver->kernel_context_switch(dev, dev->last_context, | ||
142 | lock->context); | ||
143 | } | ||
144 | |||
145 | return 0; | 138 | return 0; |
146 | } | 139 | } |
147 | 140 | ||
@@ -159,7 +152,6 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
159 | int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) | 152 | int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) |
160 | { | 153 | { |
161 | struct drm_lock *lock = data; | 154 | struct drm_lock *lock = data; |
162 | struct drm_master *master = file_priv->master; | ||
163 | 155 | ||
164 | if (lock->context == DRM_KERNEL_CONTEXT) { | 156 | if (lock->context == DRM_KERNEL_CONTEXT) { |
165 | DRM_ERROR("Process %d using kernel context %d\n", | 157 | DRM_ERROR("Process %d using kernel context %d\n", |
@@ -169,17 +161,6 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
169 | 161 | ||
170 | atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); | 162 | atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); |
171 | 163 | ||
172 | /* kernel_context_switch isn't used by any of the x86 drm | ||
173 | * modules but is required by the Sparc driver. | ||
174 | */ | ||
175 | if (dev->driver->kernel_context_switch_unlock) | ||
176 | dev->driver->kernel_context_switch_unlock(dev); | ||
177 | else { | ||
178 | if (drm_lock_free(&master->lock, lock->context)) { | ||
179 | /* FIXME: Should really bail out here. */ | ||
180 | } | ||
181 | } | ||
182 | |||
183 | unblock_all_signals(); | 164 | unblock_all_signals(); |
184 | return 0; | 165 | return 0; |
185 | } | 166 | } |
@@ -193,6 +174,7 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
193 | * | 174 | * |
194 | * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction. | 175 | * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction. |
195 | */ | 176 | */ |
177 | static | ||
196 | int drm_lock_take(struct drm_lock_data *lock_data, | 178 | int drm_lock_take(struct drm_lock_data *lock_data, |
197 | unsigned int context) | 179 | unsigned int context) |
198 | { | 180 | { |
@@ -229,7 +211,6 @@ int drm_lock_take(struct drm_lock_data *lock_data, | |||
229 | } | 211 | } |
230 | return 0; | 212 | return 0; |
231 | } | 213 | } |
232 | EXPORT_SYMBOL(drm_lock_take); | ||
233 | 214 | ||
234 | /** | 215 | /** |
235 | * This takes a lock forcibly and hands it to context. Should ONLY be used | 216 | * This takes a lock forcibly and hands it to context. Should ONLY be used |
@@ -297,7 +278,6 @@ int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context) | |||
297 | wake_up_interruptible(&lock_data->lock_queue); | 278 | wake_up_interruptible(&lock_data->lock_queue); |
298 | return 0; | 279 | return 0; |
299 | } | 280 | } |
300 | EXPORT_SYMBOL(drm_lock_free); | ||
301 | 281 | ||
302 | /** | 282 | /** |
303 | * If we get here, it means that the process has called DRM_IOCTL_LOCK | 283 | * If we get here, it means that the process has called DRM_IOCTL_LOCK |
@@ -360,7 +340,6 @@ void drm_idlelock_take(struct drm_lock_data *lock_data) | |||
360 | } | 340 | } |
361 | spin_unlock_bh(&lock_data->spinlock); | 341 | spin_unlock_bh(&lock_data->spinlock); |
362 | } | 342 | } |
363 | EXPORT_SYMBOL(drm_idlelock_take); | ||
364 | 343 | ||
365 | void drm_idlelock_release(struct drm_lock_data *lock_data) | 344 | void drm_idlelock_release(struct drm_lock_data *lock_data) |
366 | { | 345 | { |
@@ -380,8 +359,6 @@ void drm_idlelock_release(struct drm_lock_data *lock_data) | |||
380 | } | 359 | } |
381 | spin_unlock_bh(&lock_data->spinlock); | 360 | spin_unlock_bh(&lock_data->spinlock); |
382 | } | 361 | } |
383 | EXPORT_SYMBOL(drm_idlelock_release); | ||
384 | |||
385 | 362 | ||
386 | int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv) | 363 | int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv) |
387 | { | 364 | { |
@@ -390,5 +367,3 @@ int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv) | |||
390 | _DRM_LOCK_IS_HELD(master->lock.hw_lock->lock) && | 367 | _DRM_LOCK_IS_HELD(master->lock.hw_lock->lock) && |
391 | master->lock.file_priv == file_priv); | 368 | master->lock.file_priv == file_priv); |
392 | } | 369 | } |
393 | |||
394 | EXPORT_SYMBOL(drm_i_have_hw_lock); | ||
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c index 7732268eced2..c9b805000a11 100644 --- a/drivers/gpu/drm/drm_memory.c +++ b/drivers/gpu/drm/drm_memory.c | |||
@@ -99,29 +99,23 @@ static void *agp_remap(unsigned long offset, unsigned long size, | |||
99 | return addr; | 99 | return addr; |
100 | } | 100 | } |
101 | 101 | ||
102 | /** Wrapper around agp_allocate_memory() */ | ||
103 | DRM_AGP_MEM *drm_alloc_agp(struct drm_device * dev, int pages, u32 type) | ||
104 | { | ||
105 | return drm_agp_allocate_memory(dev->agp->bridge, pages, type); | ||
106 | } | ||
107 | |||
108 | /** Wrapper around agp_free_memory() */ | 102 | /** Wrapper around agp_free_memory() */ |
109 | int drm_free_agp(DRM_AGP_MEM * handle, int pages) | 103 | void drm_free_agp(DRM_AGP_MEM * handle, int pages) |
110 | { | 104 | { |
111 | return drm_agp_free_memory(handle) ? 0 : -EINVAL; | 105 | agp_free_memory(handle); |
112 | } | 106 | } |
113 | EXPORT_SYMBOL(drm_free_agp); | 107 | EXPORT_SYMBOL(drm_free_agp); |
114 | 108 | ||
115 | /** Wrapper around agp_bind_memory() */ | 109 | /** Wrapper around agp_bind_memory() */ |
116 | int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) | 110 | int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) |
117 | { | 111 | { |
118 | return drm_agp_bind_memory(handle, start); | 112 | return agp_bind_memory(handle, start); |
119 | } | 113 | } |
120 | 114 | ||
121 | /** Wrapper around agp_unbind_memory() */ | 115 | /** Wrapper around agp_unbind_memory() */ |
122 | int drm_unbind_agp(DRM_AGP_MEM * handle) | 116 | int drm_unbind_agp(DRM_AGP_MEM * handle) |
123 | { | 117 | { |
124 | return drm_agp_unbind_memory(handle); | 118 | return agp_unbind_memory(handle); |
125 | } | 119 | } |
126 | EXPORT_SYMBOL(drm_unbind_agp); | 120 | EXPORT_SYMBOL(drm_unbind_agp); |
127 | 121 | ||
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index a9ba6b69ad35..e571de536dc5 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c | |||
@@ -151,7 +151,6 @@ fail: | |||
151 | int drm_proc_init(struct drm_minor *minor, int minor_id, | 151 | int drm_proc_init(struct drm_minor *minor, int minor_id, |
152 | struct proc_dir_entry *root) | 152 | struct proc_dir_entry *root) |
153 | { | 153 | { |
154 | struct drm_device *dev = minor->dev; | ||
155 | char name[64]; | 154 | char name[64]; |
156 | int ret; | 155 | int ret; |
157 | 156 | ||
@@ -172,14 +171,6 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, | |||
172 | return ret; | 171 | return ret; |
173 | } | 172 | } |
174 | 173 | ||
175 | if (dev->driver->proc_init) { | ||
176 | ret = dev->driver->proc_init(minor); | ||
177 | if (ret) { | ||
178 | DRM_ERROR("DRM: Driver failed to initialize " | ||
179 | "/proc/dri.\n"); | ||
180 | return ret; | ||
181 | } | ||
182 | } | ||
183 | return 0; | 174 | return 0; |
184 | } | 175 | } |
185 | 176 | ||
@@ -216,15 +207,11 @@ int drm_proc_remove_files(struct drm_info_list *files, int count, | |||
216 | */ | 207 | */ |
217 | int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) | 208 | int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) |
218 | { | 209 | { |
219 | struct drm_device *dev = minor->dev; | ||
220 | char name[64]; | 210 | char name[64]; |
221 | 211 | ||
222 | if (!root || !minor->proc_root) | 212 | if (!root || !minor->proc_root) |
223 | return 0; | 213 | return 0; |
224 | 214 | ||
225 | if (dev->driver->proc_cleanup) | ||
226 | dev->driver->proc_cleanup(minor); | ||
227 | |||
228 | drm_proc_remove_files(drm_proc_list, DRM_PROC_ENTRIES, minor); | 215 | drm_proc_remove_files(drm_proc_list, DRM_PROC_ENTRIES, minor); |
229 | 216 | ||
230 | sprintf(name, "%d", minor->index); | 217 | sprintf(name, "%d", minor->index); |
diff --git a/drivers/gpu/drm/drm_scatter.c b/drivers/gpu/drm/drm_scatter.c index 9034c4c6100d..d15e09b0ae0b 100644 --- a/drivers/gpu/drm/drm_scatter.c +++ b/drivers/gpu/drm/drm_scatter.c | |||
@@ -184,8 +184,6 @@ int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request) | |||
184 | drm_sg_cleanup(entry); | 184 | drm_sg_cleanup(entry); |
185 | return -ENOMEM; | 185 | return -ENOMEM; |
186 | } | 186 | } |
187 | EXPORT_SYMBOL(drm_sg_alloc); | ||
188 | |||
189 | 187 | ||
190 | int drm_sg_alloc_ioctl(struct drm_device *dev, void *data, | 188 | int drm_sg_alloc_ioctl(struct drm_device *dev, void *data, |
191 | struct drm_file *file_priv) | 189 | struct drm_file *file_priv) |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index d1ad57450df1..cdc89ee042cc 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -240,14 +240,10 @@ int drm_fill_in_dev(struct drm_device *dev, | |||
240 | INIT_LIST_HEAD(&dev->vblank_event_list); | 240 | INIT_LIST_HEAD(&dev->vblank_event_list); |
241 | 241 | ||
242 | spin_lock_init(&dev->count_lock); | 242 | spin_lock_init(&dev->count_lock); |
243 | spin_lock_init(&dev->drw_lock); | ||
244 | spin_lock_init(&dev->event_lock); | 243 | spin_lock_init(&dev->event_lock); |
245 | init_timer(&dev->timer); | ||
246 | mutex_init(&dev->struct_mutex); | 244 | mutex_init(&dev->struct_mutex); |
247 | mutex_init(&dev->ctxlist_mutex); | 245 | mutex_init(&dev->ctxlist_mutex); |
248 | 246 | ||
249 | idr_init(&dev->drw_idr); | ||
250 | |||
251 | if (drm_ht_create(&dev->map_hash, 12)) { | 247 | if (drm_ht_create(&dev->map_hash, 12)) { |
252 | return -ENOMEM; | 248 | return -ENOMEM; |
253 | } | 249 | } |
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index fda67468e603..ee879d6bb522 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c | |||
@@ -515,14 +515,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) | |||
515 | return 0; | 515 | return 0; |
516 | } | 516 | } |
517 | 517 | ||
518 | resource_size_t drm_core_get_map_ofs(struct drm_local_map * map) | 518 | static resource_size_t drm_core_get_reg_ofs(struct drm_device *dev) |
519 | { | ||
520 | return map->offset; | ||
521 | } | ||
522 | |||
523 | EXPORT_SYMBOL(drm_core_get_map_ofs); | ||
524 | |||
525 | resource_size_t drm_core_get_reg_ofs(struct drm_device *dev) | ||
526 | { | 519 | { |
527 | #ifdef __alpha__ | 520 | #ifdef __alpha__ |
528 | return dev->hose->dense_mem_base - dev->hose->mem_space->start; | 521 | return dev->hose->dense_mem_base - dev->hose->mem_space->start; |
@@ -531,8 +524,6 @@ resource_size_t drm_core_get_reg_ofs(struct drm_device *dev) | |||
531 | #endif | 524 | #endif |
532 | } | 525 | } |
533 | 526 | ||
534 | EXPORT_SYMBOL(drm_core_get_reg_ofs); | ||
535 | |||
536 | /** | 527 | /** |
537 | * mmap DMA memory. | 528 | * mmap DMA memory. |
538 | * | 529 | * |
@@ -619,7 +610,7 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) | |||
619 | #endif | 610 | #endif |
620 | case _DRM_FRAME_BUFFER: | 611 | case _DRM_FRAME_BUFFER: |
621 | case _DRM_REGISTERS: | 612 | case _DRM_REGISTERS: |
622 | offset = dev->driver->get_reg_ofs(dev); | 613 | offset = drm_core_get_reg_ofs(dev); |
623 | vma->vm_flags |= VM_IO; /* not in core dump */ | 614 | vma->vm_flags |= VM_IO; /* not in core dump */ |
624 | vma->vm_page_prot = drm_io_prot(map->type, vma); | 615 | vma->vm_page_prot = drm_io_prot(map->type, vma); |
625 | #if !defined(__arm__) | 616 | #if !defined(__arm__) |
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index b4250b2cac1f..1c73b0c43c1e 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c | |||
@@ -52,8 +52,6 @@ static struct drm_driver driver = { | |||
52 | .device_is_agp = i810_driver_device_is_agp, | 52 | .device_is_agp = i810_driver_device_is_agp, |
53 | .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked, | 53 | .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked, |
54 | .dma_quiescent = i810_driver_dma_quiescent, | 54 | .dma_quiescent = i810_driver_dma_quiescent, |
55 | .get_map_ofs = drm_core_get_map_ofs, | ||
56 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
57 | .ioctls = i810_ioctls, | 55 | .ioctls = i810_ioctls, |
58 | .fops = { | 56 | .fops = { |
59 | .owner = THIS_MODULE, | 57 | .owner = THIS_MODULE, |
diff --git a/drivers/gpu/drm/i830/i830_drv.c b/drivers/gpu/drm/i830/i830_drv.c index a5c66aa82f0c..7140ffc12eee 100644 --- a/drivers/gpu/drm/i830/i830_drv.c +++ b/drivers/gpu/drm/i830/i830_drv.c | |||
@@ -57,8 +57,6 @@ static struct drm_driver driver = { | |||
57 | .device_is_agp = i830_driver_device_is_agp, | 57 | .device_is_agp = i830_driver_device_is_agp, |
58 | .reclaim_buffers_locked = i830_driver_reclaim_buffers_locked, | 58 | .reclaim_buffers_locked = i830_driver_reclaim_buffers_locked, |
59 | .dma_quiescent = i830_driver_dma_quiescent, | 59 | .dma_quiescent = i830_driver_dma_quiescent, |
60 | .get_map_ofs = drm_core_get_map_ofs, | ||
61 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
62 | #if USE_IRQS | 60 | #if USE_IRQS |
63 | .irq_preinstall = i830_driver_irq_preinstall, | 61 | .irq_preinstall = i830_driver_irq_preinstall, |
64 | .irq_postinstall = i830_driver_irq_postinstall, | 62 | .irq_postinstall = i830_driver_irq_postinstall, |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 5c8e53458edb..f6e98dd416c9 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -26,13 +26,13 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
26 | intel_dvo.o \ | 26 | intel_dvo.o \ |
27 | intel_ringbuffer.o \ | 27 | intel_ringbuffer.o \ |
28 | intel_overlay.o \ | 28 | intel_overlay.o \ |
29 | intel_opregion.o \ | ||
29 | dvo_ch7xxx.o \ | 30 | dvo_ch7xxx.o \ |
30 | dvo_ch7017.o \ | 31 | dvo_ch7017.o \ |
31 | dvo_ivch.o \ | 32 | dvo_ivch.o \ |
32 | dvo_tfp410.o \ | 33 | dvo_tfp410.o \ |
33 | dvo_sil164.o | 34 | dvo_sil164.o |
34 | 35 | ||
35 | i915-$(CONFIG_ACPI) += i915_opregion.o | ||
36 | i915-$(CONFIG_COMPAT) += i915_ioc32.o | 36 | i915-$(CONFIG_COMPAT) += i915_ioc32.o |
37 | 37 | ||
38 | obj-$(CONFIG_DRM_I915) += i915.o | 38 | obj-$(CONFIG_DRM_I915) += i915.o |
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c index 14d59804acd7..0bc8ce1ad9aa 100644 --- a/drivers/gpu/drm/i915/dvo_ch7017.c +++ b/drivers/gpu/drm/i915/dvo_ch7017.c | |||
@@ -168,7 +168,6 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, int mode); | |||
168 | static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) | 168 | static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) |
169 | { | 169 | { |
170 | struct i2c_adapter *adapter = dvo->i2c_bus; | 170 | struct i2c_adapter *adapter = dvo->i2c_bus; |
171 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
172 | u8 out_buf[2]; | 171 | u8 out_buf[2]; |
173 | u8 in_buf[2]; | 172 | u8 in_buf[2]; |
174 | 173 | ||
@@ -190,7 +189,7 @@ static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) | |||
190 | out_buf[0] = addr; | 189 | out_buf[0] = addr; |
191 | out_buf[1] = 0; | 190 | out_buf[1] = 0; |
192 | 191 | ||
193 | if (i2c_transfer(&i2cbus->adapter, msgs, 2) == 2) { | 192 | if (i2c_transfer(adapter, msgs, 2) == 2) { |
194 | *val= in_buf[0]; | 193 | *val= in_buf[0]; |
195 | return true; | 194 | return true; |
196 | }; | 195 | }; |
@@ -201,7 +200,6 @@ static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) | |||
201 | static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) | 200 | static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) |
202 | { | 201 | { |
203 | struct i2c_adapter *adapter = dvo->i2c_bus; | 202 | struct i2c_adapter *adapter = dvo->i2c_bus; |
204 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
205 | uint8_t out_buf[2]; | 203 | uint8_t out_buf[2]; |
206 | struct i2c_msg msg = { | 204 | struct i2c_msg msg = { |
207 | .addr = dvo->slave_addr, | 205 | .addr = dvo->slave_addr, |
@@ -213,7 +211,7 @@ static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) | |||
213 | out_buf[0] = addr; | 211 | out_buf[0] = addr; |
214 | out_buf[1] = val; | 212 | out_buf[1] = val; |
215 | 213 | ||
216 | if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1) | 214 | if (i2c_transfer(adapter, &msg, 1) == 1) |
217 | return true; | 215 | return true; |
218 | 216 | ||
219 | return false; | 217 | return false; |
@@ -223,7 +221,6 @@ static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) | |||
223 | static bool ch7017_init(struct intel_dvo_device *dvo, | 221 | static bool ch7017_init(struct intel_dvo_device *dvo, |
224 | struct i2c_adapter *adapter) | 222 | struct i2c_adapter *adapter) |
225 | { | 223 | { |
226 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
227 | struct ch7017_priv *priv; | 224 | struct ch7017_priv *priv; |
228 | uint8_t val; | 225 | uint8_t val; |
229 | 226 | ||
@@ -242,7 +239,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo, | |||
242 | val != CH7019_DEVICE_ID_VALUE) { | 239 | val != CH7019_DEVICE_ID_VALUE) { |
243 | DRM_DEBUG_KMS("ch701x not detected, got %d: from %s " | 240 | DRM_DEBUG_KMS("ch701x not detected, got %d: from %s " |
244 | "Slave %d.\n", | 241 | "Slave %d.\n", |
245 | val, i2cbus->adapter.name,dvo->slave_addr); | 242 | val, adapter->name,dvo->slave_addr); |
246 | goto fail; | 243 | goto fail; |
247 | } | 244 | } |
248 | 245 | ||
diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c index 6f1944b24441..7eaa94e4ff06 100644 --- a/drivers/gpu/drm/i915/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c | |||
@@ -113,7 +113,6 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
113 | { | 113 | { |
114 | struct ch7xxx_priv *ch7xxx= dvo->dev_priv; | 114 | struct ch7xxx_priv *ch7xxx= dvo->dev_priv; |
115 | struct i2c_adapter *adapter = dvo->i2c_bus; | 115 | struct i2c_adapter *adapter = dvo->i2c_bus; |
116 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
117 | u8 out_buf[2]; | 116 | u8 out_buf[2]; |
118 | u8 in_buf[2]; | 117 | u8 in_buf[2]; |
119 | 118 | ||
@@ -135,14 +134,14 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
135 | out_buf[0] = addr; | 134 | out_buf[0] = addr; |
136 | out_buf[1] = 0; | 135 | out_buf[1] = 0; |
137 | 136 | ||
138 | if (i2c_transfer(&i2cbus->adapter, msgs, 2) == 2) { | 137 | if (i2c_transfer(adapter, msgs, 2) == 2) { |
139 | *ch = in_buf[0]; | 138 | *ch = in_buf[0]; |
140 | return true; | 139 | return true; |
141 | }; | 140 | }; |
142 | 141 | ||
143 | if (!ch7xxx->quiet) { | 142 | if (!ch7xxx->quiet) { |
144 | DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n", | 143 | DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n", |
145 | addr, i2cbus->adapter.name, dvo->slave_addr); | 144 | addr, adapter->name, dvo->slave_addr); |
146 | } | 145 | } |
147 | return false; | 146 | return false; |
148 | } | 147 | } |
@@ -152,7 +151,6 @@ static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
152 | { | 151 | { |
153 | struct ch7xxx_priv *ch7xxx = dvo->dev_priv; | 152 | struct ch7xxx_priv *ch7xxx = dvo->dev_priv; |
154 | struct i2c_adapter *adapter = dvo->i2c_bus; | 153 | struct i2c_adapter *adapter = dvo->i2c_bus; |
155 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
156 | uint8_t out_buf[2]; | 154 | uint8_t out_buf[2]; |
157 | struct i2c_msg msg = { | 155 | struct i2c_msg msg = { |
158 | .addr = dvo->slave_addr, | 156 | .addr = dvo->slave_addr, |
@@ -164,12 +162,12 @@ static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
164 | out_buf[0] = addr; | 162 | out_buf[0] = addr; |
165 | out_buf[1] = ch; | 163 | out_buf[1] = ch; |
166 | 164 | ||
167 | if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1) | 165 | if (i2c_transfer(adapter, &msg, 1) == 1) |
168 | return true; | 166 | return true; |
169 | 167 | ||
170 | if (!ch7xxx->quiet) { | 168 | if (!ch7xxx->quiet) { |
171 | DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n", | 169 | DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n", |
172 | addr, i2cbus->adapter.name, dvo->slave_addr); | 170 | addr, adapter->name, dvo->slave_addr); |
173 | } | 171 | } |
174 | 172 | ||
175 | return false; | 173 | return false; |
diff --git a/drivers/gpu/drm/i915/dvo_ivch.c b/drivers/gpu/drm/i915/dvo_ivch.c index a2ec3f487202..a12ed9414cc7 100644 --- a/drivers/gpu/drm/i915/dvo_ivch.c +++ b/drivers/gpu/drm/i915/dvo_ivch.c | |||
@@ -167,7 +167,6 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) | |||
167 | { | 167 | { |
168 | struct ivch_priv *priv = dvo->dev_priv; | 168 | struct ivch_priv *priv = dvo->dev_priv; |
169 | struct i2c_adapter *adapter = dvo->i2c_bus; | 169 | struct i2c_adapter *adapter = dvo->i2c_bus; |
170 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
171 | u8 out_buf[1]; | 170 | u8 out_buf[1]; |
172 | u8 in_buf[2]; | 171 | u8 in_buf[2]; |
173 | 172 | ||
@@ -193,7 +192,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) | |||
193 | 192 | ||
194 | out_buf[0] = addr; | 193 | out_buf[0] = addr; |
195 | 194 | ||
196 | if (i2c_transfer(&i2cbus->adapter, msgs, 3) == 3) { | 195 | if (i2c_transfer(adapter, msgs, 3) == 3) { |
197 | *data = (in_buf[1] << 8) | in_buf[0]; | 196 | *data = (in_buf[1] << 8) | in_buf[0]; |
198 | return true; | 197 | return true; |
199 | }; | 198 | }; |
@@ -201,7 +200,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) | |||
201 | if (!priv->quiet) { | 200 | if (!priv->quiet) { |
202 | DRM_DEBUG_KMS("Unable to read register 0x%02x from " | 201 | DRM_DEBUG_KMS("Unable to read register 0x%02x from " |
203 | "%s:%02x.\n", | 202 | "%s:%02x.\n", |
204 | addr, i2cbus->adapter.name, dvo->slave_addr); | 203 | addr, adapter->name, dvo->slave_addr); |
205 | } | 204 | } |
206 | return false; | 205 | return false; |
207 | } | 206 | } |
@@ -211,7 +210,6 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) | |||
211 | { | 210 | { |
212 | struct ivch_priv *priv = dvo->dev_priv; | 211 | struct ivch_priv *priv = dvo->dev_priv; |
213 | struct i2c_adapter *adapter = dvo->i2c_bus; | 212 | struct i2c_adapter *adapter = dvo->i2c_bus; |
214 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
215 | u8 out_buf[3]; | 213 | u8 out_buf[3]; |
216 | struct i2c_msg msg = { | 214 | struct i2c_msg msg = { |
217 | .addr = dvo->slave_addr, | 215 | .addr = dvo->slave_addr, |
@@ -224,12 +222,12 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) | |||
224 | out_buf[1] = data & 0xff; | 222 | out_buf[1] = data & 0xff; |
225 | out_buf[2] = data >> 8; | 223 | out_buf[2] = data >> 8; |
226 | 224 | ||
227 | if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1) | 225 | if (i2c_transfer(adapter, &msg, 1) == 1) |
228 | return true; | 226 | return true; |
229 | 227 | ||
230 | if (!priv->quiet) { | 228 | if (!priv->quiet) { |
231 | DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n", | 229 | DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n", |
232 | addr, i2cbus->adapter.name, dvo->slave_addr); | 230 | addr, adapter->name, dvo->slave_addr); |
233 | } | 231 | } |
234 | 232 | ||
235 | return false; | 233 | return false; |
diff --git a/drivers/gpu/drm/i915/dvo_sil164.c b/drivers/gpu/drm/i915/dvo_sil164.c index 9b8e6765cf26..e4b4091df942 100644 --- a/drivers/gpu/drm/i915/dvo_sil164.c +++ b/drivers/gpu/drm/i915/dvo_sil164.c | |||
@@ -69,7 +69,6 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
69 | { | 69 | { |
70 | struct sil164_priv *sil = dvo->dev_priv; | 70 | struct sil164_priv *sil = dvo->dev_priv; |
71 | struct i2c_adapter *adapter = dvo->i2c_bus; | 71 | struct i2c_adapter *adapter = dvo->i2c_bus; |
72 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
73 | u8 out_buf[2]; | 72 | u8 out_buf[2]; |
74 | u8 in_buf[2]; | 73 | u8 in_buf[2]; |
75 | 74 | ||
@@ -91,14 +90,14 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
91 | out_buf[0] = addr; | 90 | out_buf[0] = addr; |
92 | out_buf[1] = 0; | 91 | out_buf[1] = 0; |
93 | 92 | ||
94 | if (i2c_transfer(&i2cbus->adapter, msgs, 2) == 2) { | 93 | if (i2c_transfer(adapter, msgs, 2) == 2) { |
95 | *ch = in_buf[0]; | 94 | *ch = in_buf[0]; |
96 | return true; | 95 | return true; |
97 | }; | 96 | }; |
98 | 97 | ||
99 | if (!sil->quiet) { | 98 | if (!sil->quiet) { |
100 | DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n", | 99 | DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n", |
101 | addr, i2cbus->adapter.name, dvo->slave_addr); | 100 | addr, adapter->name, dvo->slave_addr); |
102 | } | 101 | } |
103 | return false; | 102 | return false; |
104 | } | 103 | } |
@@ -107,7 +106,6 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
107 | { | 106 | { |
108 | struct sil164_priv *sil= dvo->dev_priv; | 107 | struct sil164_priv *sil= dvo->dev_priv; |
109 | struct i2c_adapter *adapter = dvo->i2c_bus; | 108 | struct i2c_adapter *adapter = dvo->i2c_bus; |
110 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
111 | uint8_t out_buf[2]; | 109 | uint8_t out_buf[2]; |
112 | struct i2c_msg msg = { | 110 | struct i2c_msg msg = { |
113 | .addr = dvo->slave_addr, | 111 | .addr = dvo->slave_addr, |
@@ -119,12 +117,12 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
119 | out_buf[0] = addr; | 117 | out_buf[0] = addr; |
120 | out_buf[1] = ch; | 118 | out_buf[1] = ch; |
121 | 119 | ||
122 | if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1) | 120 | if (i2c_transfer(adapter, &msg, 1) == 1) |
123 | return true; | 121 | return true; |
124 | 122 | ||
125 | if (!sil->quiet) { | 123 | if (!sil->quiet) { |
126 | DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n", | 124 | DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n", |
127 | addr, i2cbus->adapter.name, dvo->slave_addr); | 125 | addr, adapter->name, dvo->slave_addr); |
128 | } | 126 | } |
129 | 127 | ||
130 | return false; | 128 | return false; |
diff --git a/drivers/gpu/drm/i915/dvo_tfp410.c b/drivers/gpu/drm/i915/dvo_tfp410.c index 56f66426207f..8ab2855bb544 100644 --- a/drivers/gpu/drm/i915/dvo_tfp410.c +++ b/drivers/gpu/drm/i915/dvo_tfp410.c | |||
@@ -94,7 +94,6 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
94 | { | 94 | { |
95 | struct tfp410_priv *tfp = dvo->dev_priv; | 95 | struct tfp410_priv *tfp = dvo->dev_priv; |
96 | struct i2c_adapter *adapter = dvo->i2c_bus; | 96 | struct i2c_adapter *adapter = dvo->i2c_bus; |
97 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
98 | u8 out_buf[2]; | 97 | u8 out_buf[2]; |
99 | u8 in_buf[2]; | 98 | u8 in_buf[2]; |
100 | 99 | ||
@@ -116,14 +115,14 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
116 | out_buf[0] = addr; | 115 | out_buf[0] = addr; |
117 | out_buf[1] = 0; | 116 | out_buf[1] = 0; |
118 | 117 | ||
119 | if (i2c_transfer(&i2cbus->adapter, msgs, 2) == 2) { | 118 | if (i2c_transfer(adapter, msgs, 2) == 2) { |
120 | *ch = in_buf[0]; | 119 | *ch = in_buf[0]; |
121 | return true; | 120 | return true; |
122 | }; | 121 | }; |
123 | 122 | ||
124 | if (!tfp->quiet) { | 123 | if (!tfp->quiet) { |
125 | DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n", | 124 | DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n", |
126 | addr, i2cbus->adapter.name, dvo->slave_addr); | 125 | addr, adapter->name, dvo->slave_addr); |
127 | } | 126 | } |
128 | return false; | 127 | return false; |
129 | } | 128 | } |
@@ -132,7 +131,6 @@ static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
132 | { | 131 | { |
133 | struct tfp410_priv *tfp = dvo->dev_priv; | 132 | struct tfp410_priv *tfp = dvo->dev_priv; |
134 | struct i2c_adapter *adapter = dvo->i2c_bus; | 133 | struct i2c_adapter *adapter = dvo->i2c_bus; |
135 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
136 | uint8_t out_buf[2]; | 134 | uint8_t out_buf[2]; |
137 | struct i2c_msg msg = { | 135 | struct i2c_msg msg = { |
138 | .addr = dvo->slave_addr, | 136 | .addr = dvo->slave_addr, |
@@ -144,12 +142,12 @@ static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
144 | out_buf[0] = addr; | 142 | out_buf[0] = addr; |
145 | out_buf[1] = ch; | 143 | out_buf[1] = ch; |
146 | 144 | ||
147 | if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1) | 145 | if (i2c_transfer(adapter, &msg, 1) == 1) |
148 | return true; | 146 | return true; |
149 | 147 | ||
150 | if (!tfp->quiet) { | 148 | if (!tfp->quiet) { |
151 | DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n", | 149 | DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n", |
152 | addr, i2cbus->adapter.name, dvo->slave_addr); | 150 | addr, adapter->name, dvo->slave_addr); |
153 | } | 151 | } |
154 | 152 | ||
155 | return false; | 153 | return false; |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5e43d7076789..fb5c2a621907 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -44,6 +44,46 @@ | |||
44 | #define FLUSHING_LIST 2 | 44 | #define FLUSHING_LIST 2 |
45 | #define INACTIVE_LIST 3 | 45 | #define INACTIVE_LIST 3 |
46 | 46 | ||
47 | static const char *yesno(int v) | ||
48 | { | ||
49 | return v ? "yes" : "no"; | ||
50 | } | ||
51 | |||
52 | static int i915_capabilities(struct seq_file *m, void *data) | ||
53 | { | ||
54 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
55 | struct drm_device *dev = node->minor->dev; | ||
56 | const struct intel_device_info *info = INTEL_INFO(dev); | ||
57 | |||
58 | seq_printf(m, "gen: %d\n", info->gen); | ||
59 | #define B(x) seq_printf(m, #x ": %s\n", yesno(info->x)) | ||
60 | B(is_mobile); | ||
61 | B(is_i8xx); | ||
62 | B(is_i85x); | ||
63 | B(is_i915g); | ||
64 | B(is_i9xx); | ||
65 | B(is_i945gm); | ||
66 | B(is_i965g); | ||
67 | B(is_i965gm); | ||
68 | B(is_g33); | ||
69 | B(need_gfx_hws); | ||
70 | B(is_g4x); | ||
71 | B(is_pineview); | ||
72 | B(is_broadwater); | ||
73 | B(is_crestline); | ||
74 | B(is_ironlake); | ||
75 | B(has_fbc); | ||
76 | B(has_rc6); | ||
77 | B(has_pipe_cxsr); | ||
78 | B(has_hotplug); | ||
79 | B(cursor_needs_physical); | ||
80 | B(has_overlay); | ||
81 | B(overlay_needs_physical); | ||
82 | #undef B | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
47 | static const char *get_pin_flag(struct drm_i915_gem_object *obj_priv) | 87 | static const char *get_pin_flag(struct drm_i915_gem_object *obj_priv) |
48 | { | 88 | { |
49 | if (obj_priv->user_pin_count > 0) | 89 | if (obj_priv->user_pin_count > 0) |
@@ -64,6 +104,27 @@ static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv) | |||
64 | } | 104 | } |
65 | } | 105 | } |
66 | 106 | ||
107 | static void | ||
108 | describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | ||
109 | { | ||
110 | seq_printf(m, "%p: %s%s %8zd %08x %08x %d%s%s", | ||
111 | &obj->base, | ||
112 | get_pin_flag(obj), | ||
113 | get_tiling_flag(obj), | ||
114 | obj->base.size, | ||
115 | obj->base.read_domains, | ||
116 | obj->base.write_domain, | ||
117 | obj->last_rendering_seqno, | ||
118 | obj->dirty ? " dirty" : "", | ||
119 | obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); | ||
120 | if (obj->base.name) | ||
121 | seq_printf(m, " (name: %d)", obj->base.name); | ||
122 | if (obj->fence_reg != I915_FENCE_REG_NONE) | ||
123 | seq_printf(m, " (fence: %d)", obj->fence_reg); | ||
124 | if (obj->gtt_space != NULL) | ||
125 | seq_printf(m, " (gtt_offset: %08x)", obj->gtt_offset); | ||
126 | } | ||
127 | |||
67 | static int i915_gem_object_list_info(struct seq_file *m, void *data) | 128 | static int i915_gem_object_list_info(struct seq_file *m, void *data) |
68 | { | 129 | { |
69 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 130 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
@@ -72,12 +133,15 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
72 | struct drm_device *dev = node->minor->dev; | 133 | struct drm_device *dev = node->minor->dev; |
73 | drm_i915_private_t *dev_priv = dev->dev_private; | 134 | drm_i915_private_t *dev_priv = dev->dev_private; |
74 | struct drm_i915_gem_object *obj_priv; | 135 | struct drm_i915_gem_object *obj_priv; |
75 | spinlock_t *lock = NULL; | 136 | int ret; |
137 | |||
138 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
139 | if (ret) | ||
140 | return ret; | ||
76 | 141 | ||
77 | switch (list) { | 142 | switch (list) { |
78 | case ACTIVE_LIST: | 143 | case ACTIVE_LIST: |
79 | seq_printf(m, "Active:\n"); | 144 | seq_printf(m, "Active:\n"); |
80 | lock = &dev_priv->mm.active_list_lock; | ||
81 | head = &dev_priv->render_ring.active_list; | 145 | head = &dev_priv->render_ring.active_list; |
82 | break; | 146 | break; |
83 | case INACTIVE_LIST: | 147 | case INACTIVE_LIST: |
@@ -89,36 +153,17 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
89 | head = &dev_priv->mm.flushing_list; | 153 | head = &dev_priv->mm.flushing_list; |
90 | break; | 154 | break; |
91 | default: | 155 | default: |
92 | DRM_INFO("Ooops, unexpected list\n"); | 156 | mutex_unlock(&dev->struct_mutex); |
93 | return 0; | 157 | return -EINVAL; |
94 | } | 158 | } |
95 | 159 | ||
96 | if (lock) | 160 | list_for_each_entry(obj_priv, head, list) { |
97 | spin_lock(lock); | 161 | seq_printf(m, " "); |
98 | list_for_each_entry(obj_priv, head, list) | 162 | describe_obj(m, obj_priv); |
99 | { | ||
100 | seq_printf(m, " %p: %s %8zd %08x %08x %d%s%s", | ||
101 | &obj_priv->base, | ||
102 | get_pin_flag(obj_priv), | ||
103 | obj_priv->base.size, | ||
104 | obj_priv->base.read_domains, | ||
105 | obj_priv->base.write_domain, | ||
106 | obj_priv->last_rendering_seqno, | ||
107 | obj_priv->dirty ? " dirty" : "", | ||
108 | obj_priv->madv == I915_MADV_DONTNEED ? " purgeable" : ""); | ||
109 | |||
110 | if (obj_priv->base.name) | ||
111 | seq_printf(m, " (name: %d)", obj_priv->base.name); | ||
112 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | ||
113 | seq_printf(m, " (fence: %d)", obj_priv->fence_reg); | ||
114 | if (obj_priv->gtt_space != NULL) | ||
115 | seq_printf(m, " (gtt_offset: %08x)", obj_priv->gtt_offset); | ||
116 | |||
117 | seq_printf(m, "\n"); | 163 | seq_printf(m, "\n"); |
118 | } | 164 | } |
119 | 165 | ||
120 | if (lock) | 166 | mutex_unlock(&dev->struct_mutex); |
121 | spin_unlock(lock); | ||
122 | return 0; | 167 | return 0; |
123 | } | 168 | } |
124 | 169 | ||
@@ -176,6 +221,11 @@ static int i915_gem_request_info(struct seq_file *m, void *data) | |||
176 | struct drm_device *dev = node->minor->dev; | 221 | struct drm_device *dev = node->minor->dev; |
177 | drm_i915_private_t *dev_priv = dev->dev_private; | 222 | drm_i915_private_t *dev_priv = dev->dev_private; |
178 | struct drm_i915_gem_request *gem_request; | 223 | struct drm_i915_gem_request *gem_request; |
224 | int ret; | ||
225 | |||
226 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
227 | if (ret) | ||
228 | return ret; | ||
179 | 229 | ||
180 | seq_printf(m, "Request:\n"); | 230 | seq_printf(m, "Request:\n"); |
181 | list_for_each_entry(gem_request, &dev_priv->render_ring.request_list, | 231 | list_for_each_entry(gem_request, &dev_priv->render_ring.request_list, |
@@ -184,6 +234,8 @@ static int i915_gem_request_info(struct seq_file *m, void *data) | |||
184 | gem_request->seqno, | 234 | gem_request->seqno, |
185 | (int) (jiffies - gem_request->emitted_jiffies)); | 235 | (int) (jiffies - gem_request->emitted_jiffies)); |
186 | } | 236 | } |
237 | mutex_unlock(&dev->struct_mutex); | ||
238 | |||
187 | return 0; | 239 | return 0; |
188 | } | 240 | } |
189 | 241 | ||
@@ -192,6 +244,11 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) | |||
192 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 244 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
193 | struct drm_device *dev = node->minor->dev; | 245 | struct drm_device *dev = node->minor->dev; |
194 | drm_i915_private_t *dev_priv = dev->dev_private; | 246 | drm_i915_private_t *dev_priv = dev->dev_private; |
247 | int ret; | ||
248 | |||
249 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
250 | if (ret) | ||
251 | return ret; | ||
195 | 252 | ||
196 | if (dev_priv->render_ring.status_page.page_addr != NULL) { | 253 | if (dev_priv->render_ring.status_page.page_addr != NULL) { |
197 | seq_printf(m, "Current sequence: %d\n", | 254 | seq_printf(m, "Current sequence: %d\n", |
@@ -202,6 +259,9 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) | |||
202 | seq_printf(m, "Waiter sequence: %d\n", | 259 | seq_printf(m, "Waiter sequence: %d\n", |
203 | dev_priv->mm.waiting_gem_seqno); | 260 | dev_priv->mm.waiting_gem_seqno); |
204 | seq_printf(m, "IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); | 261 | seq_printf(m, "IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); |
262 | |||
263 | mutex_unlock(&dev->struct_mutex); | ||
264 | |||
205 | return 0; | 265 | return 0; |
206 | } | 266 | } |
207 | 267 | ||
@@ -211,6 +271,11 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
211 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 271 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
212 | struct drm_device *dev = node->minor->dev; | 272 | struct drm_device *dev = node->minor->dev; |
213 | drm_i915_private_t *dev_priv = dev->dev_private; | 273 | drm_i915_private_t *dev_priv = dev->dev_private; |
274 | int ret; | ||
275 | |||
276 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
277 | if (ret) | ||
278 | return ret; | ||
214 | 279 | ||
215 | if (!HAS_PCH_SPLIT(dev)) { | 280 | if (!HAS_PCH_SPLIT(dev)) { |
216 | seq_printf(m, "Interrupt enable: %08x\n", | 281 | seq_printf(m, "Interrupt enable: %08x\n", |
@@ -255,6 +320,8 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
255 | dev_priv->mm.waiting_gem_seqno); | 320 | dev_priv->mm.waiting_gem_seqno); |
256 | seq_printf(m, "IRQ sequence: %d\n", | 321 | seq_printf(m, "IRQ sequence: %d\n", |
257 | dev_priv->mm.irq_gem_seqno); | 322 | dev_priv->mm.irq_gem_seqno); |
323 | mutex_unlock(&dev->struct_mutex); | ||
324 | |||
258 | return 0; | 325 | return 0; |
259 | } | 326 | } |
260 | 327 | ||
@@ -263,7 +330,11 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) | |||
263 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 330 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
264 | struct drm_device *dev = node->minor->dev; | 331 | struct drm_device *dev = node->minor->dev; |
265 | drm_i915_private_t *dev_priv = dev->dev_private; | 332 | drm_i915_private_t *dev_priv = dev->dev_private; |
266 | int i; | 333 | int i, ret; |
334 | |||
335 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
336 | if (ret) | ||
337 | return ret; | ||
267 | 338 | ||
268 | seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start); | 339 | seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start); |
269 | seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs); | 340 | seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs); |
@@ -289,6 +360,7 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) | |||
289 | seq_printf(m, "\n"); | 360 | seq_printf(m, "\n"); |
290 | } | 361 | } |
291 | } | 362 | } |
363 | mutex_unlock(&dev->struct_mutex); | ||
292 | 364 | ||
293 | return 0; | 365 | return 0; |
294 | } | 366 | } |
@@ -319,10 +391,10 @@ static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_co | |||
319 | uint32_t *mem; | 391 | uint32_t *mem; |
320 | 392 | ||
321 | for (page = 0; page < page_count; page++) { | 393 | for (page = 0; page < page_count; page++) { |
322 | mem = kmap_atomic(pages[page], KM_USER0); | 394 | mem = kmap(pages[page]); |
323 | for (i = 0; i < PAGE_SIZE; i += 4) | 395 | for (i = 0; i < PAGE_SIZE; i += 4) |
324 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); | 396 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); |
325 | kunmap_atomic(mem, KM_USER0); | 397 | kunmap(pages[page]); |
326 | } | 398 | } |
327 | } | 399 | } |
328 | 400 | ||
@@ -335,7 +407,9 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) | |||
335 | struct drm_i915_gem_object *obj_priv; | 407 | struct drm_i915_gem_object *obj_priv; |
336 | int ret; | 408 | int ret; |
337 | 409 | ||
338 | spin_lock(&dev_priv->mm.active_list_lock); | 410 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
411 | if (ret) | ||
412 | return ret; | ||
339 | 413 | ||
340 | list_for_each_entry(obj_priv, &dev_priv->render_ring.active_list, | 414 | list_for_each_entry(obj_priv, &dev_priv->render_ring.active_list, |
341 | list) { | 415 | list) { |
@@ -343,8 +417,7 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) | |||
343 | if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { | 417 | if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { |
344 | ret = i915_gem_object_get_pages(obj, 0); | 418 | ret = i915_gem_object_get_pages(obj, 0); |
345 | if (ret) { | 419 | if (ret) { |
346 | DRM_ERROR("Failed to get pages: %d\n", ret); | 420 | mutex_unlock(&dev->struct_mutex); |
347 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
348 | return ret; | 421 | return ret; |
349 | } | 422 | } |
350 | 423 | ||
@@ -355,7 +428,7 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) | |||
355 | } | 428 | } |
356 | } | 429 | } |
357 | 430 | ||
358 | spin_unlock(&dev_priv->mm.active_list_lock); | 431 | mutex_unlock(&dev->struct_mutex); |
359 | 432 | ||
360 | return 0; | 433 | return 0; |
361 | } | 434 | } |
@@ -365,20 +438,24 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data) | |||
365 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 438 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
366 | struct drm_device *dev = node->minor->dev; | 439 | struct drm_device *dev = node->minor->dev; |
367 | drm_i915_private_t *dev_priv = dev->dev_private; | 440 | drm_i915_private_t *dev_priv = dev->dev_private; |
368 | u8 *virt; | 441 | int ret; |
369 | uint32_t *ptr, off; | 442 | |
443 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
444 | if (ret) | ||
445 | return ret; | ||
370 | 446 | ||
371 | if (!dev_priv->render_ring.gem_object) { | 447 | if (!dev_priv->render_ring.gem_object) { |
372 | seq_printf(m, "No ringbuffer setup\n"); | 448 | seq_printf(m, "No ringbuffer setup\n"); |
373 | return 0; | 449 | } else { |
374 | } | 450 | u8 *virt = dev_priv->render_ring.virtual_start; |
375 | 451 | uint32_t off; | |
376 | virt = dev_priv->render_ring.virtual_start; | ||
377 | 452 | ||
378 | for (off = 0; off < dev_priv->render_ring.size; off += 4) { | 453 | for (off = 0; off < dev_priv->render_ring.size; off += 4) { |
379 | ptr = (uint32_t *)(virt + off); | 454 | uint32_t *ptr = (uint32_t *)(virt + off); |
380 | seq_printf(m, "%08x : %08x\n", off, *ptr); | 455 | seq_printf(m, "%08x : %08x\n", off, *ptr); |
456 | } | ||
381 | } | 457 | } |
458 | mutex_unlock(&dev->struct_mutex); | ||
382 | 459 | ||
383 | return 0; | 460 | return 0; |
384 | } | 461 | } |
@@ -642,6 +719,9 @@ static int i915_fbc_status(struct seq_file *m, void *unused) | |||
642 | } else { | 719 | } else { |
643 | seq_printf(m, "FBC disabled: "); | 720 | seq_printf(m, "FBC disabled: "); |
644 | switch (dev_priv->no_fbc_reason) { | 721 | switch (dev_priv->no_fbc_reason) { |
722 | case FBC_NO_OUTPUT: | ||
723 | seq_printf(m, "no outputs"); | ||
724 | break; | ||
645 | case FBC_STOLEN_TOO_SMALL: | 725 | case FBC_STOLEN_TOO_SMALL: |
646 | seq_printf(m, "not enough stolen memory"); | 726 | seq_printf(m, "not enough stolen memory"); |
647 | break; | 727 | break; |
@@ -675,15 +755,17 @@ static int i915_sr_status(struct seq_file *m, void *unused) | |||
675 | drm_i915_private_t *dev_priv = dev->dev_private; | 755 | drm_i915_private_t *dev_priv = dev->dev_private; |
676 | bool sr_enabled = false; | 756 | bool sr_enabled = false; |
677 | 757 | ||
678 | if (IS_I965GM(dev) || IS_I945G(dev) || IS_I945GM(dev)) | 758 | if (IS_IRONLAKE(dev)) |
759 | sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; | ||
760 | else if (IS_I965GM(dev) || IS_I945G(dev) || IS_I945GM(dev)) | ||
679 | sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; | 761 | sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; |
680 | else if (IS_I915GM(dev)) | 762 | else if (IS_I915GM(dev)) |
681 | sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; | 763 | sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; |
682 | else if (IS_PINEVIEW(dev)) | 764 | else if (IS_PINEVIEW(dev)) |
683 | sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN; | 765 | sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN; |
684 | 766 | ||
685 | seq_printf(m, "self-refresh: %s\n", sr_enabled ? "enabled" : | 767 | seq_printf(m, "self-refresh: %s\n", |
686 | "disabled"); | 768 | sr_enabled ? "enabled" : "disabled"); |
687 | 769 | ||
688 | return 0; | 770 | return 0; |
689 | } | 771 | } |
@@ -694,10 +776,16 @@ static int i915_emon_status(struct seq_file *m, void *unused) | |||
694 | struct drm_device *dev = node->minor->dev; | 776 | struct drm_device *dev = node->minor->dev; |
695 | drm_i915_private_t *dev_priv = dev->dev_private; | 777 | drm_i915_private_t *dev_priv = dev->dev_private; |
696 | unsigned long temp, chipset, gfx; | 778 | unsigned long temp, chipset, gfx; |
779 | int ret; | ||
780 | |||
781 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
782 | if (ret) | ||
783 | return ret; | ||
697 | 784 | ||
698 | temp = i915_mch_val(dev_priv); | 785 | temp = i915_mch_val(dev_priv); |
699 | chipset = i915_chipset_val(dev_priv); | 786 | chipset = i915_chipset_val(dev_priv); |
700 | gfx = i915_gfx_val(dev_priv); | 787 | gfx = i915_gfx_val(dev_priv); |
788 | mutex_unlock(&dev->struct_mutex); | ||
701 | 789 | ||
702 | seq_printf(m, "GMCH temp: %ld\n", temp); | 790 | seq_printf(m, "GMCH temp: %ld\n", temp); |
703 | seq_printf(m, "Chipset power: %ld\n", chipset); | 791 | seq_printf(m, "Chipset power: %ld\n", chipset); |
@@ -718,6 +806,68 @@ static int i915_gfxec(struct seq_file *m, void *unused) | |||
718 | return 0; | 806 | return 0; |
719 | } | 807 | } |
720 | 808 | ||
809 | static int i915_opregion(struct seq_file *m, void *unused) | ||
810 | { | ||
811 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
812 | struct drm_device *dev = node->minor->dev; | ||
813 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
814 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
815 | int ret; | ||
816 | |||
817 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
818 | if (ret) | ||
819 | return ret; | ||
820 | |||
821 | if (opregion->header) | ||
822 | seq_write(m, opregion->header, OPREGION_SIZE); | ||
823 | |||
824 | mutex_unlock(&dev->struct_mutex); | ||
825 | |||
826 | return 0; | ||
827 | } | ||
828 | |||
829 | static int i915_gem_framebuffer_info(struct seq_file *m, void *data) | ||
830 | { | ||
831 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
832 | struct drm_device *dev = node->minor->dev; | ||
833 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
834 | struct intel_fbdev *ifbdev; | ||
835 | struct intel_framebuffer *fb; | ||
836 | int ret; | ||
837 | |||
838 | ret = mutex_lock_interruptible(&dev->mode_config.mutex); | ||
839 | if (ret) | ||
840 | return ret; | ||
841 | |||
842 | ifbdev = dev_priv->fbdev; | ||
843 | fb = to_intel_framebuffer(ifbdev->helper.fb); | ||
844 | |||
845 | seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, obj ", | ||
846 | fb->base.width, | ||
847 | fb->base.height, | ||
848 | fb->base.depth, | ||
849 | fb->base.bits_per_pixel); | ||
850 | describe_obj(m, to_intel_bo(fb->obj)); | ||
851 | seq_printf(m, "\n"); | ||
852 | |||
853 | list_for_each_entry(fb, &dev->mode_config.fb_list, base.head) { | ||
854 | if (&fb->base == ifbdev->helper.fb) | ||
855 | continue; | ||
856 | |||
857 | seq_printf(m, "user size: %d x %d, depth %d, %d bpp, obj ", | ||
858 | fb->base.width, | ||
859 | fb->base.height, | ||
860 | fb->base.depth, | ||
861 | fb->base.bits_per_pixel); | ||
862 | describe_obj(m, to_intel_bo(fb->obj)); | ||
863 | seq_printf(m, "\n"); | ||
864 | } | ||
865 | |||
866 | mutex_unlock(&dev->mode_config.mutex); | ||
867 | |||
868 | return 0; | ||
869 | } | ||
870 | |||
721 | static int | 871 | static int |
722 | i915_wedged_open(struct inode *inode, | 872 | i915_wedged_open(struct inode *inode, |
723 | struct file *filp) | 873 | struct file *filp) |
@@ -741,6 +891,9 @@ i915_wedged_read(struct file *filp, | |||
741 | "wedged : %d\n", | 891 | "wedged : %d\n", |
742 | atomic_read(&dev_priv->mm.wedged)); | 892 | atomic_read(&dev_priv->mm.wedged)); |
743 | 893 | ||
894 | if (len > sizeof (buf)) | ||
895 | len = sizeof (buf); | ||
896 | |||
744 | return simple_read_from_buffer(ubuf, max, ppos, buf, len); | 897 | return simple_read_from_buffer(ubuf, max, ppos, buf, len); |
745 | } | 898 | } |
746 | 899 | ||
@@ -823,6 +976,7 @@ static int i915_wedged_create(struct dentry *root, struct drm_minor *minor) | |||
823 | } | 976 | } |
824 | 977 | ||
825 | static struct drm_info_list i915_debugfs_list[] = { | 978 | static struct drm_info_list i915_debugfs_list[] = { |
979 | {"i915_capabilities", i915_capabilities, 0, 0}, | ||
826 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 980 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
827 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, | 981 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, |
828 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, | 982 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, |
@@ -845,6 +999,8 @@ static struct drm_info_list i915_debugfs_list[] = { | |||
845 | {"i915_gfxec", i915_gfxec, 0}, | 999 | {"i915_gfxec", i915_gfxec, 0}, |
846 | {"i915_fbc_status", i915_fbc_status, 0}, | 1000 | {"i915_fbc_status", i915_fbc_status, 0}, |
847 | {"i915_sr_status", i915_sr_status, 0}, | 1001 | {"i915_sr_status", i915_sr_status, 0}, |
1002 | {"i915_opregion", i915_opregion, 0}, | ||
1003 | {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, | ||
848 | }; | 1004 | }; |
849 | #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) | 1005 | #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) |
850 | 1006 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9d67b4853030..39aaffe79583 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -40,8 +40,7 @@ | |||
40 | #include <linux/pnp.h> | 40 | #include <linux/pnp.h> |
41 | #include <linux/vga_switcheroo.h> | 41 | #include <linux/vga_switcheroo.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | 43 | #include <acpi/video.h> | |
44 | extern int intel_max_stolen; /* from AGP driver */ | ||
45 | 44 | ||
46 | /** | 45 | /** |
47 | * Sets up the hardware status page for devices that need a physical address | 46 | * Sets up the hardware status page for devices that need a physical address |
@@ -990,174 +989,6 @@ intel_teardown_mchbar(struct drm_device *dev) | |||
990 | release_resource(&dev_priv->mch_res); | 989 | release_resource(&dev_priv->mch_res); |
991 | } | 990 | } |
992 | 991 | ||
993 | /** | ||
994 | * i915_probe_agp - get AGP bootup configuration | ||
995 | * @pdev: PCI device | ||
996 | * @aperture_size: returns AGP aperture configured size | ||
997 | * @preallocated_size: returns size of BIOS preallocated AGP space | ||
998 | * | ||
999 | * Since Intel integrated graphics are UMA, the BIOS has to set aside | ||
1000 | * some RAM for the framebuffer at early boot. This code figures out | ||
1001 | * how much was set aside so we can use it for our own purposes. | ||
1002 | */ | ||
1003 | static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, | ||
1004 | uint32_t *preallocated_size, | ||
1005 | uint32_t *start) | ||
1006 | { | ||
1007 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1008 | u16 tmp = 0; | ||
1009 | unsigned long overhead; | ||
1010 | unsigned long stolen; | ||
1011 | |||
1012 | /* Get the fb aperture size and "stolen" memory amount. */ | ||
1013 | pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &tmp); | ||
1014 | |||
1015 | *aperture_size = 1024 * 1024; | ||
1016 | *preallocated_size = 1024 * 1024; | ||
1017 | |||
1018 | switch (dev->pdev->device) { | ||
1019 | case PCI_DEVICE_ID_INTEL_82830_CGC: | ||
1020 | case PCI_DEVICE_ID_INTEL_82845G_IG: | ||
1021 | case PCI_DEVICE_ID_INTEL_82855GM_IG: | ||
1022 | case PCI_DEVICE_ID_INTEL_82865_IG: | ||
1023 | if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) | ||
1024 | *aperture_size *= 64; | ||
1025 | else | ||
1026 | *aperture_size *= 128; | ||
1027 | break; | ||
1028 | default: | ||
1029 | /* 9xx supports large sizes, just look at the length */ | ||
1030 | *aperture_size = pci_resource_len(dev->pdev, 2); | ||
1031 | break; | ||
1032 | } | ||
1033 | |||
1034 | /* | ||
1035 | * Some of the preallocated space is taken by the GTT | ||
1036 | * and popup. GTT is 1K per MB of aperture size, and popup is 4K. | ||
1037 | */ | ||
1038 | if (IS_G4X(dev) || IS_PINEVIEW(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) | ||
1039 | overhead = 4096; | ||
1040 | else | ||
1041 | overhead = (*aperture_size / 1024) + 4096; | ||
1042 | |||
1043 | if (IS_GEN6(dev)) { | ||
1044 | /* SNB has memory control reg at 0x50.w */ | ||
1045 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &tmp); | ||
1046 | |||
1047 | switch (tmp & SNB_GMCH_GMS_STOLEN_MASK) { | ||
1048 | case INTEL_855_GMCH_GMS_DISABLED: | ||
1049 | DRM_ERROR("video memory is disabled\n"); | ||
1050 | return -1; | ||
1051 | case SNB_GMCH_GMS_STOLEN_32M: | ||
1052 | stolen = 32 * 1024 * 1024; | ||
1053 | break; | ||
1054 | case SNB_GMCH_GMS_STOLEN_64M: | ||
1055 | stolen = 64 * 1024 * 1024; | ||
1056 | break; | ||
1057 | case SNB_GMCH_GMS_STOLEN_96M: | ||
1058 | stolen = 96 * 1024 * 1024; | ||
1059 | break; | ||
1060 | case SNB_GMCH_GMS_STOLEN_128M: | ||
1061 | stolen = 128 * 1024 * 1024; | ||
1062 | break; | ||
1063 | case SNB_GMCH_GMS_STOLEN_160M: | ||
1064 | stolen = 160 * 1024 * 1024; | ||
1065 | break; | ||
1066 | case SNB_GMCH_GMS_STOLEN_192M: | ||
1067 | stolen = 192 * 1024 * 1024; | ||
1068 | break; | ||
1069 | case SNB_GMCH_GMS_STOLEN_224M: | ||
1070 | stolen = 224 * 1024 * 1024; | ||
1071 | break; | ||
1072 | case SNB_GMCH_GMS_STOLEN_256M: | ||
1073 | stolen = 256 * 1024 * 1024; | ||
1074 | break; | ||
1075 | case SNB_GMCH_GMS_STOLEN_288M: | ||
1076 | stolen = 288 * 1024 * 1024; | ||
1077 | break; | ||
1078 | case SNB_GMCH_GMS_STOLEN_320M: | ||
1079 | stolen = 320 * 1024 * 1024; | ||
1080 | break; | ||
1081 | case SNB_GMCH_GMS_STOLEN_352M: | ||
1082 | stolen = 352 * 1024 * 1024; | ||
1083 | break; | ||
1084 | case SNB_GMCH_GMS_STOLEN_384M: | ||
1085 | stolen = 384 * 1024 * 1024; | ||
1086 | break; | ||
1087 | case SNB_GMCH_GMS_STOLEN_416M: | ||
1088 | stolen = 416 * 1024 * 1024; | ||
1089 | break; | ||
1090 | case SNB_GMCH_GMS_STOLEN_448M: | ||
1091 | stolen = 448 * 1024 * 1024; | ||
1092 | break; | ||
1093 | case SNB_GMCH_GMS_STOLEN_480M: | ||
1094 | stolen = 480 * 1024 * 1024; | ||
1095 | break; | ||
1096 | case SNB_GMCH_GMS_STOLEN_512M: | ||
1097 | stolen = 512 * 1024 * 1024; | ||
1098 | break; | ||
1099 | default: | ||
1100 | DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n", | ||
1101 | tmp & SNB_GMCH_GMS_STOLEN_MASK); | ||
1102 | return -1; | ||
1103 | } | ||
1104 | } else { | ||
1105 | switch (tmp & INTEL_GMCH_GMS_MASK) { | ||
1106 | case INTEL_855_GMCH_GMS_DISABLED: | ||
1107 | DRM_ERROR("video memory is disabled\n"); | ||
1108 | return -1; | ||
1109 | case INTEL_855_GMCH_GMS_STOLEN_1M: | ||
1110 | stolen = 1 * 1024 * 1024; | ||
1111 | break; | ||
1112 | case INTEL_855_GMCH_GMS_STOLEN_4M: | ||
1113 | stolen = 4 * 1024 * 1024; | ||
1114 | break; | ||
1115 | case INTEL_855_GMCH_GMS_STOLEN_8M: | ||
1116 | stolen = 8 * 1024 * 1024; | ||
1117 | break; | ||
1118 | case INTEL_855_GMCH_GMS_STOLEN_16M: | ||
1119 | stolen = 16 * 1024 * 1024; | ||
1120 | break; | ||
1121 | case INTEL_855_GMCH_GMS_STOLEN_32M: | ||
1122 | stolen = 32 * 1024 * 1024; | ||
1123 | break; | ||
1124 | case INTEL_915G_GMCH_GMS_STOLEN_48M: | ||
1125 | stolen = 48 * 1024 * 1024; | ||
1126 | break; | ||
1127 | case INTEL_915G_GMCH_GMS_STOLEN_64M: | ||
1128 | stolen = 64 * 1024 * 1024; | ||
1129 | break; | ||
1130 | case INTEL_GMCH_GMS_STOLEN_128M: | ||
1131 | stolen = 128 * 1024 * 1024; | ||
1132 | break; | ||
1133 | case INTEL_GMCH_GMS_STOLEN_256M: | ||
1134 | stolen = 256 * 1024 * 1024; | ||
1135 | break; | ||
1136 | case INTEL_GMCH_GMS_STOLEN_96M: | ||
1137 | stolen = 96 * 1024 * 1024; | ||
1138 | break; | ||
1139 | case INTEL_GMCH_GMS_STOLEN_160M: | ||
1140 | stolen = 160 * 1024 * 1024; | ||
1141 | break; | ||
1142 | case INTEL_GMCH_GMS_STOLEN_224M: | ||
1143 | stolen = 224 * 1024 * 1024; | ||
1144 | break; | ||
1145 | case INTEL_GMCH_GMS_STOLEN_352M: | ||
1146 | stolen = 352 * 1024 * 1024; | ||
1147 | break; | ||
1148 | default: | ||
1149 | DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n", | ||
1150 | tmp & INTEL_GMCH_GMS_MASK); | ||
1151 | return -1; | ||
1152 | } | ||
1153 | } | ||
1154 | |||
1155 | *preallocated_size = stolen - overhead; | ||
1156 | *start = overhead; | ||
1157 | |||
1158 | return 0; | ||
1159 | } | ||
1160 | |||
1161 | #define PTE_ADDRESS_MASK 0xfffff000 | 992 | #define PTE_ADDRESS_MASK 0xfffff000 |
1162 | #define PTE_ADDRESS_MASK_HIGH 0x000000f0 /* i915+ */ | 993 | #define PTE_ADDRESS_MASK_HIGH 0x000000f0 /* i915+ */ |
1163 | #define PTE_MAPPING_TYPE_UNCACHED (0 << 1) | 994 | #define PTE_MAPPING_TYPE_UNCACHED (0 << 1) |
@@ -1252,7 +1083,7 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1252 | unsigned long ll_base = 0; | 1083 | unsigned long ll_base = 0; |
1253 | 1084 | ||
1254 | /* Leave 1M for line length buffer & misc. */ | 1085 | /* Leave 1M for line length buffer & misc. */ |
1255 | compressed_fb = drm_mm_search_free(&dev_priv->vram, size, 4096, 0); | 1086 | compressed_fb = drm_mm_search_free(&dev_priv->mm.vram, size, 4096, 0); |
1256 | if (!compressed_fb) { | 1087 | if (!compressed_fb) { |
1257 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | 1088 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; |
1258 | i915_warn_stolen(dev); | 1089 | i915_warn_stolen(dev); |
@@ -1273,7 +1104,7 @@ static void i915_setup_compression(struct drm_device *dev, int size) | |||
1273 | } | 1104 | } |
1274 | 1105 | ||
1275 | if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) { | 1106 | if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) { |
1276 | compressed_llb = drm_mm_search_free(&dev_priv->vram, 4096, | 1107 | compressed_llb = drm_mm_search_free(&dev_priv->mm.vram, 4096, |
1277 | 4096, 0); | 1108 | 4096, 0); |
1278 | if (!compressed_llb) { | 1109 | if (!compressed_llb) { |
1279 | i915_warn_stolen(dev); | 1110 | i915_warn_stolen(dev); |
@@ -1363,19 +1194,14 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) | |||
1363 | } | 1194 | } |
1364 | 1195 | ||
1365 | static int i915_load_modeset_init(struct drm_device *dev, | 1196 | static int i915_load_modeset_init(struct drm_device *dev, |
1366 | unsigned long prealloc_start, | ||
1367 | unsigned long prealloc_size, | 1197 | unsigned long prealloc_size, |
1368 | unsigned long agp_size) | 1198 | unsigned long agp_size) |
1369 | { | 1199 | { |
1370 | struct drm_i915_private *dev_priv = dev->dev_private; | 1200 | struct drm_i915_private *dev_priv = dev->dev_private; |
1371 | int fb_bar = IS_I9XX(dev) ? 2 : 0; | ||
1372 | int ret = 0; | 1201 | int ret = 0; |
1373 | 1202 | ||
1374 | dev->mode_config.fb_base = pci_resource_start(dev->pdev, fb_bar) & | 1203 | /* Basic memrange allocator for stolen space (aka mm.vram) */ |
1375 | 0xff000000; | 1204 | drm_mm_init(&dev_priv->mm.vram, 0, prealloc_size); |
1376 | |||
1377 | /* Basic memrange allocator for stolen space (aka vram) */ | ||
1378 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); | ||
1379 | DRM_INFO("set up %ldM of stolen space\n", prealloc_size / (1024*1024)); | 1205 | DRM_INFO("set up %ldM of stolen space\n", prealloc_size / (1024*1024)); |
1380 | 1206 | ||
1381 | /* We're off and running w/KMS */ | 1207 | /* We're off and running w/KMS */ |
@@ -1443,12 +1269,6 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
1443 | /* FIXME: do pre/post-mode set stuff in core KMS code */ | 1269 | /* FIXME: do pre/post-mode set stuff in core KMS code */ |
1444 | dev->vblank_disable_allowed = 1; | 1270 | dev->vblank_disable_allowed = 1; |
1445 | 1271 | ||
1446 | /* | ||
1447 | * Initialize the hardware status page IRQ location. | ||
1448 | */ | ||
1449 | |||
1450 | I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); | ||
1451 | |||
1452 | ret = intel_fbdev_init(dev); | 1272 | ret = intel_fbdev_init(dev); |
1453 | if (ret) | 1273 | if (ret) |
1454 | goto cleanup_irq; | 1274 | goto cleanup_irq; |
@@ -1907,7 +1727,7 @@ static struct drm_i915_private *i915_mch_dev; | |||
1907 | * - dev_priv->fmax | 1727 | * - dev_priv->fmax |
1908 | * - dev_priv->gpu_busy | 1728 | * - dev_priv->gpu_busy |
1909 | */ | 1729 | */ |
1910 | DEFINE_SPINLOCK(mchdev_lock); | 1730 | static DEFINE_SPINLOCK(mchdev_lock); |
1911 | 1731 | ||
1912 | /** | 1732 | /** |
1913 | * i915_read_mch_val - return value for IPS use | 1733 | * i915_read_mch_val - return value for IPS use |
@@ -2062,7 +1882,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2062 | struct drm_i915_private *dev_priv; | 1882 | struct drm_i915_private *dev_priv; |
2063 | resource_size_t base, size; | 1883 | resource_size_t base, size; |
2064 | int ret = 0, mmio_bar; | 1884 | int ret = 0, mmio_bar; |
2065 | uint32_t agp_size, prealloc_size, prealloc_start; | 1885 | uint32_t agp_size, prealloc_size; |
2066 | /* i915 has 4 more counters */ | 1886 | /* i915 has 4 more counters */ |
2067 | dev->counters += 4; | 1887 | dev->counters += 4; |
2068 | dev->types[6] = _DRM_STAT_IRQ; | 1888 | dev->types[6] = _DRM_STAT_IRQ; |
@@ -2121,17 +1941,32 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2121 | "performance may suffer.\n"); | 1941 | "performance may suffer.\n"); |
2122 | } | 1942 | } |
2123 | 1943 | ||
2124 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size, &prealloc_start); | 1944 | dev_priv->mm.gtt = intel_gtt_get(); |
2125 | if (ret) | 1945 | if (!dev_priv->mm.gtt) { |
1946 | DRM_ERROR("Failed to initialize GTT\n"); | ||
1947 | ret = -ENODEV; | ||
2126 | goto out_iomapfree; | 1948 | goto out_iomapfree; |
2127 | |||
2128 | if (prealloc_size > intel_max_stolen) { | ||
2129 | DRM_INFO("detected %dM stolen memory, trimming to %dM\n", | ||
2130 | prealloc_size >> 20, intel_max_stolen >> 20); | ||
2131 | prealloc_size = intel_max_stolen; | ||
2132 | } | 1949 | } |
2133 | 1950 | ||
2134 | dev_priv->wq = create_singlethread_workqueue("i915"); | 1951 | prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; |
1952 | agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | ||
1953 | |||
1954 | /* The i915 workqueue is primarily used for batched retirement of | ||
1955 | * requests (and thus managing bo) once the task has been completed | ||
1956 | * by the GPU. i915_gem_retire_requests() is called directly when we | ||
1957 | * need high-priority retirement, such as waiting for an explicit | ||
1958 | * bo. | ||
1959 | * | ||
1960 | * It is also used for periodic low-priority events, such as | ||
1961 | * idle-timers and hangcheck. | ||
1962 | * | ||
1963 | * All tasks on the workqueue are expected to acquire the dev mutex | ||
1964 | * so there is no point in running more than one instance of the | ||
1965 | * workqueue at any time: max_active = 1 and NON_REENTRANT. | ||
1966 | */ | ||
1967 | dev_priv->wq = alloc_workqueue("i915", | ||
1968 | WQ_UNBOUND | WQ_NON_REENTRANT, | ||
1969 | 1); | ||
2135 | if (dev_priv->wq == NULL) { | 1970 | if (dev_priv->wq == NULL) { |
2136 | DRM_ERROR("Failed to create our workqueue.\n"); | 1971 | DRM_ERROR("Failed to create our workqueue.\n"); |
2137 | ret = -ENOMEM; | 1972 | ret = -ENOMEM; |
@@ -2166,6 +2001,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2166 | 2001 | ||
2167 | /* Try to make sure MCHBAR is enabled before poking at it */ | 2002 | /* Try to make sure MCHBAR is enabled before poking at it */ |
2168 | intel_setup_mchbar(dev); | 2003 | intel_setup_mchbar(dev); |
2004 | intel_setup_gmbus(dev); | ||
2005 | intel_opregion_setup(dev); | ||
2169 | 2006 | ||
2170 | i915_gem_load(dev); | 2007 | i915_gem_load(dev); |
2171 | 2008 | ||
@@ -2212,8 +2049,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2212 | intel_detect_pch(dev); | 2049 | intel_detect_pch(dev); |
2213 | 2050 | ||
2214 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 2051 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
2215 | ret = i915_load_modeset_init(dev, prealloc_start, | 2052 | ret = i915_load_modeset_init(dev, prealloc_size, agp_size); |
2216 | prealloc_size, agp_size); | ||
2217 | if (ret < 0) { | 2053 | if (ret < 0) { |
2218 | DRM_ERROR("failed to init modeset\n"); | 2054 | DRM_ERROR("failed to init modeset\n"); |
2219 | goto out_workqueue_free; | 2055 | goto out_workqueue_free; |
@@ -2221,7 +2057,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2221 | } | 2057 | } |
2222 | 2058 | ||
2223 | /* Must be done after probing outputs */ | 2059 | /* Must be done after probing outputs */ |
2224 | intel_opregion_init(dev, 0); | 2060 | intel_opregion_init(dev); |
2061 | acpi_video_register(); | ||
2225 | 2062 | ||
2226 | setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, | 2063 | setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, |
2227 | (unsigned long) dev); | 2064 | (unsigned long) dev); |
@@ -2249,15 +2086,20 @@ free_priv: | |||
2249 | int i915_driver_unload(struct drm_device *dev) | 2086 | int i915_driver_unload(struct drm_device *dev) |
2250 | { | 2087 | { |
2251 | struct drm_i915_private *dev_priv = dev->dev_private; | 2088 | struct drm_i915_private *dev_priv = dev->dev_private; |
2252 | 2089 | int ret; | |
2253 | i915_destroy_error_state(dev); | ||
2254 | 2090 | ||
2255 | spin_lock(&mchdev_lock); | 2091 | spin_lock(&mchdev_lock); |
2256 | i915_mch_dev = NULL; | 2092 | i915_mch_dev = NULL; |
2257 | spin_unlock(&mchdev_lock); | 2093 | spin_unlock(&mchdev_lock); |
2258 | 2094 | ||
2259 | destroy_workqueue(dev_priv->wq); | 2095 | mutex_lock(&dev->struct_mutex); |
2260 | del_timer_sync(&dev_priv->hangcheck_timer); | 2096 | ret = i915_gpu_idle(dev); |
2097 | if (ret) | ||
2098 | DRM_ERROR("failed to idle hardware: %d\n", ret); | ||
2099 | mutex_unlock(&dev->struct_mutex); | ||
2100 | |||
2101 | /* Cancel the retire work handler, which should be idle now. */ | ||
2102 | cancel_delayed_work_sync(&dev_priv->mm.retire_work); | ||
2261 | 2103 | ||
2262 | io_mapping_free(dev_priv->mm.gtt_mapping); | 2104 | io_mapping_free(dev_priv->mm.gtt_mapping); |
2263 | if (dev_priv->mm.gtt_mtrr >= 0) { | 2105 | if (dev_priv->mm.gtt_mtrr >= 0) { |
@@ -2266,6 +2108,8 @@ int i915_driver_unload(struct drm_device *dev) | |||
2266 | dev_priv->mm.gtt_mtrr = -1; | 2108 | dev_priv->mm.gtt_mtrr = -1; |
2267 | } | 2109 | } |
2268 | 2110 | ||
2111 | acpi_video_unregister(); | ||
2112 | |||
2269 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 2113 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
2270 | intel_modeset_cleanup(dev); | 2114 | intel_modeset_cleanup(dev); |
2271 | 2115 | ||
@@ -2278,20 +2122,28 @@ int i915_driver_unload(struct drm_device *dev) | |||
2278 | dev_priv->child_dev = NULL; | 2122 | dev_priv->child_dev = NULL; |
2279 | dev_priv->child_dev_num = 0; | 2123 | dev_priv->child_dev_num = 0; |
2280 | } | 2124 | } |
2281 | drm_irq_uninstall(dev); | 2125 | |
2282 | vga_switcheroo_unregister_client(dev->pdev); | 2126 | vga_switcheroo_unregister_client(dev->pdev); |
2283 | vga_client_register(dev->pdev, NULL, NULL, NULL); | 2127 | vga_client_register(dev->pdev, NULL, NULL, NULL); |
2284 | } | 2128 | } |
2285 | 2129 | ||
2130 | /* Free error state after interrupts are fully disabled. */ | ||
2131 | del_timer_sync(&dev_priv->hangcheck_timer); | ||
2132 | cancel_work_sync(&dev_priv->error_work); | ||
2133 | i915_destroy_error_state(dev); | ||
2134 | |||
2286 | if (dev->pdev->msi_enabled) | 2135 | if (dev->pdev->msi_enabled) |
2287 | pci_disable_msi(dev->pdev); | 2136 | pci_disable_msi(dev->pdev); |
2288 | 2137 | ||
2289 | if (dev_priv->regs != NULL) | 2138 | if (dev_priv->regs != NULL) |
2290 | iounmap(dev_priv->regs); | 2139 | iounmap(dev_priv->regs); |
2291 | 2140 | ||
2292 | intel_opregion_free(dev, 0); | 2141 | intel_opregion_fini(dev); |
2293 | 2142 | ||
2294 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 2143 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
2144 | /* Flush any outstanding unpin_work. */ | ||
2145 | flush_workqueue(dev_priv->wq); | ||
2146 | |||
2295 | i915_gem_free_all_phys_object(dev); | 2147 | i915_gem_free_all_phys_object(dev); |
2296 | 2148 | ||
2297 | mutex_lock(&dev->struct_mutex); | 2149 | mutex_lock(&dev->struct_mutex); |
@@ -2299,14 +2151,16 @@ int i915_driver_unload(struct drm_device *dev) | |||
2299 | mutex_unlock(&dev->struct_mutex); | 2151 | mutex_unlock(&dev->struct_mutex); |
2300 | if (I915_HAS_FBC(dev) && i915_powersave) | 2152 | if (I915_HAS_FBC(dev) && i915_powersave) |
2301 | i915_cleanup_compression(dev); | 2153 | i915_cleanup_compression(dev); |
2302 | drm_mm_takedown(&dev_priv->vram); | 2154 | drm_mm_takedown(&dev_priv->mm.vram); |
2303 | i915_gem_lastclose(dev); | ||
2304 | 2155 | ||
2305 | intel_cleanup_overlay(dev); | 2156 | intel_cleanup_overlay(dev); |
2306 | } | 2157 | } |
2307 | 2158 | ||
2159 | intel_teardown_gmbus(dev); | ||
2308 | intel_teardown_mchbar(dev); | 2160 | intel_teardown_mchbar(dev); |
2309 | 2161 | ||
2162 | destroy_workqueue(dev_priv->wq); | ||
2163 | |||
2310 | pci_dev_put(dev_priv->bridge_dev); | 2164 | pci_dev_put(dev_priv->bridge_dev); |
2311 | kfree(dev->dev_private); | 2165 | kfree(dev->dev_private); |
2312 | 2166 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 6dbe14cc4f74..13dca9da6507 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -62,49 +62,60 @@ extern int intel_agp_enabled; | |||
62 | 62 | ||
63 | static const struct intel_device_info intel_i830_info = { | 63 | static const struct intel_device_info intel_i830_info = { |
64 | .gen = 2, .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, | 64 | .gen = 2, .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, |
65 | .has_overlay = 1, .overlay_needs_physical = 1, | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | static const struct intel_device_info intel_845g_info = { | 68 | static const struct intel_device_info intel_845g_info = { |
68 | .gen = 2, .is_i8xx = 1, | 69 | .gen = 2, .is_i8xx = 1, |
70 | .has_overlay = 1, .overlay_needs_physical = 1, | ||
69 | }; | 71 | }; |
70 | 72 | ||
71 | static const struct intel_device_info intel_i85x_info = { | 73 | static const struct intel_device_info intel_i85x_info = { |
72 | .gen = 2, .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, | 74 | .gen = 2, .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, |
73 | .cursor_needs_physical = 1, | 75 | .cursor_needs_physical = 1, |
76 | .has_overlay = 1, .overlay_needs_physical = 1, | ||
74 | }; | 77 | }; |
75 | 78 | ||
76 | static const struct intel_device_info intel_i865g_info = { | 79 | static const struct intel_device_info intel_i865g_info = { |
77 | .gen = 2, .is_i8xx = 1, | 80 | .gen = 2, .is_i8xx = 1, |
81 | .has_overlay = 1, .overlay_needs_physical = 1, | ||
78 | }; | 82 | }; |
79 | 83 | ||
80 | static const struct intel_device_info intel_i915g_info = { | 84 | static const struct intel_device_info intel_i915g_info = { |
81 | .gen = 3, .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, | 85 | .gen = 3, .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, |
86 | .has_overlay = 1, .overlay_needs_physical = 1, | ||
82 | }; | 87 | }; |
83 | static const struct intel_device_info intel_i915gm_info = { | 88 | static const struct intel_device_info intel_i915gm_info = { |
84 | .gen = 3, .is_i9xx = 1, .is_mobile = 1, | 89 | .gen = 3, .is_i9xx = 1, .is_mobile = 1, |
85 | .cursor_needs_physical = 1, | 90 | .cursor_needs_physical = 1, |
91 | .has_overlay = 1, .overlay_needs_physical = 1, | ||
86 | }; | 92 | }; |
87 | static const struct intel_device_info intel_i945g_info = { | 93 | static const struct intel_device_info intel_i945g_info = { |
88 | .gen = 3, .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, | 94 | .gen = 3, .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, |
95 | .has_overlay = 1, .overlay_needs_physical = 1, | ||
89 | }; | 96 | }; |
90 | static const struct intel_device_info intel_i945gm_info = { | 97 | static const struct intel_device_info intel_i945gm_info = { |
91 | .gen = 3, .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, | 98 | .gen = 3, .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, |
92 | .has_hotplug = 1, .cursor_needs_physical = 1, | 99 | .has_hotplug = 1, .cursor_needs_physical = 1, |
100 | .has_overlay = 1, .overlay_needs_physical = 1, | ||
93 | }; | 101 | }; |
94 | 102 | ||
95 | static const struct intel_device_info intel_i965g_info = { | 103 | static const struct intel_device_info intel_i965g_info = { |
96 | .gen = 4, .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, | 104 | .gen = 4, .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, |
97 | .has_hotplug = 1, | 105 | .has_hotplug = 1, |
106 | .has_overlay = 1, | ||
98 | }; | 107 | }; |
99 | 108 | ||
100 | static const struct intel_device_info intel_i965gm_info = { | 109 | static const struct intel_device_info intel_i965gm_info = { |
101 | .gen = 4, .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, | 110 | .gen = 4, .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, |
102 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, | 111 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, |
112 | .has_overlay = 1, | ||
103 | }; | 113 | }; |
104 | 114 | ||
105 | static const struct intel_device_info intel_g33_info = { | 115 | static const struct intel_device_info intel_g33_info = { |
106 | .gen = 3, .is_g33 = 1, .is_i9xx = 1, | 116 | .gen = 3, .is_g33 = 1, .is_i9xx = 1, |
107 | .need_gfx_hws = 1, .has_hotplug = 1, | 117 | .need_gfx_hws = 1, .has_hotplug = 1, |
118 | .has_overlay = 1, | ||
108 | }; | 119 | }; |
109 | 120 | ||
110 | static const struct intel_device_info intel_g45_info = { | 121 | static const struct intel_device_info intel_g45_info = { |
@@ -121,6 +132,7 @@ static const struct intel_device_info intel_gm45_info = { | |||
121 | static const struct intel_device_info intel_pineview_info = { | 132 | static const struct intel_device_info intel_pineview_info = { |
122 | .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, | 133 | .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, |
123 | .need_gfx_hws = 1, .has_hotplug = 1, | 134 | .need_gfx_hws = 1, .has_hotplug = 1, |
135 | .has_overlay = 1, | ||
124 | }; | 136 | }; |
125 | 137 | ||
126 | static const struct intel_device_info intel_ironlake_d_info = { | 138 | static const struct intel_device_info intel_ironlake_d_info = { |
@@ -237,7 +249,7 @@ static int i915_drm_freeze(struct drm_device *dev) | |||
237 | 249 | ||
238 | i915_save_state(dev); | 250 | i915_save_state(dev); |
239 | 251 | ||
240 | intel_opregion_free(dev, 1); | 252 | intel_opregion_fini(dev); |
241 | 253 | ||
242 | /* Modeset on resume, not lid events */ | 254 | /* Modeset on resume, not lid events */ |
243 | dev_priv->modeset_on_lid = 0; | 255 | dev_priv->modeset_on_lid = 0; |
@@ -277,8 +289,7 @@ static int i915_drm_thaw(struct drm_device *dev) | |||
277 | int error = 0; | 289 | int error = 0; |
278 | 290 | ||
279 | i915_restore_state(dev); | 291 | i915_restore_state(dev); |
280 | 292 | intel_opregion_setup(dev); | |
281 | intel_opregion_init(dev, 1); | ||
282 | 293 | ||
283 | /* KMS EnterVT equivalent */ | 294 | /* KMS EnterVT equivalent */ |
284 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 295 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
@@ -294,6 +305,8 @@ static int i915_drm_thaw(struct drm_device *dev) | |||
294 | drm_helper_resume_force_mode(dev); | 305 | drm_helper_resume_force_mode(dev); |
295 | } | 306 | } |
296 | 307 | ||
308 | intel_opregion_init(dev); | ||
309 | |||
297 | dev_priv->modeset_on_lid = 0; | 310 | dev_priv->modeset_on_lid = 0; |
298 | 311 | ||
299 | return error; | 312 | return error; |
@@ -524,8 +537,6 @@ static struct drm_driver driver = { | |||
524 | .irq_uninstall = i915_driver_irq_uninstall, | 537 | .irq_uninstall = i915_driver_irq_uninstall, |
525 | .irq_handler = i915_driver_irq_handler, | 538 | .irq_handler = i915_driver_irq_handler, |
526 | .reclaim_buffers = drm_core_reclaim_buffers, | 539 | .reclaim_buffers = drm_core_reclaim_buffers, |
527 | .get_map_ofs = drm_core_get_map_ofs, | ||
528 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
529 | .master_create = i915_master_create, | 540 | .master_create = i915_master_create, |
530 | .master_destroy = i915_master_destroy, | 541 | .master_destroy = i915_master_destroy, |
531 | #if defined(CONFIG_DEBUG_FS) | 542 | #if defined(CONFIG_DEBUG_FS) |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index af4a263cf257..cf08128798a7 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -34,6 +34,8 @@ | |||
34 | #include "intel_bios.h" | 34 | #include "intel_bios.h" |
35 | #include "intel_ringbuffer.h" | 35 | #include "intel_ringbuffer.h" |
36 | #include <linux/io-mapping.h> | 36 | #include <linux/io-mapping.h> |
37 | #include <linux/i2c.h> | ||
38 | #include <drm/intel-gtt.h> | ||
37 | 39 | ||
38 | /* General customization: | 40 | /* General customization: |
39 | */ | 41 | */ |
@@ -110,8 +112,9 @@ struct intel_opregion { | |||
110 | struct opregion_acpi *acpi; | 112 | struct opregion_acpi *acpi; |
111 | struct opregion_swsci *swsci; | 113 | struct opregion_swsci *swsci; |
112 | struct opregion_asle *asle; | 114 | struct opregion_asle *asle; |
113 | int enabled; | 115 | void *vbt; |
114 | }; | 116 | }; |
117 | #define OPREGION_SIZE (8*1024) | ||
115 | 118 | ||
116 | struct intel_overlay; | 119 | struct intel_overlay; |
117 | struct intel_overlay_error_state; | 120 | struct intel_overlay_error_state; |
@@ -212,9 +215,12 @@ struct intel_device_info { | |||
212 | u8 has_pipe_cxsr : 1; | 215 | u8 has_pipe_cxsr : 1; |
213 | u8 has_hotplug : 1; | 216 | u8 has_hotplug : 1; |
214 | u8 cursor_needs_physical : 1; | 217 | u8 cursor_needs_physical : 1; |
218 | u8 has_overlay : 1; | ||
219 | u8 overlay_needs_physical : 1; | ||
215 | }; | 220 | }; |
216 | 221 | ||
217 | enum no_fbc_reason { | 222 | enum no_fbc_reason { |
223 | FBC_NO_OUTPUT, /* no outputs enabled to compress */ | ||
218 | FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */ | 224 | FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */ |
219 | FBC_UNSUPPORTED_MODE, /* interlace or doublescanned mode */ | 225 | FBC_UNSUPPORTED_MODE, /* interlace or doublescanned mode */ |
220 | FBC_MODE_TOO_LARGE, /* mode too large for compression */ | 226 | FBC_MODE_TOO_LARGE, /* mode too large for compression */ |
@@ -241,6 +247,12 @@ typedef struct drm_i915_private { | |||
241 | 247 | ||
242 | void __iomem *regs; | 248 | void __iomem *regs; |
243 | 249 | ||
250 | struct intel_gmbus { | ||
251 | struct i2c_adapter adapter; | ||
252 | struct i2c_adapter *force_bitbanging; | ||
253 | int pin; | ||
254 | } *gmbus; | ||
255 | |||
244 | struct pci_dev *bridge_dev; | 256 | struct pci_dev *bridge_dev; |
245 | struct intel_ring_buffer render_ring; | 257 | struct intel_ring_buffer render_ring; |
246 | struct intel_ring_buffer bsd_ring; | 258 | struct intel_ring_buffer bsd_ring; |
@@ -263,6 +275,9 @@ typedef struct drm_i915_private { | |||
263 | int front_offset; | 275 | int front_offset; |
264 | int current_page; | 276 | int current_page; |
265 | int page_flipping; | 277 | int page_flipping; |
278 | #define I915_DEBUG_READ (1<<0) | ||
279 | #define I915_DEBUG_WRITE (1<<1) | ||
280 | unsigned long debug_flags; | ||
266 | 281 | ||
267 | wait_queue_head_t irq_queue; | 282 | wait_queue_head_t irq_queue; |
268 | atomic_t irq_received; | 283 | atomic_t irq_received; |
@@ -289,24 +304,21 @@ typedef struct drm_i915_private { | |||
289 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; | 304 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; |
290 | int vblank_pipe; | 305 | int vblank_pipe; |
291 | int num_pipe; | 306 | int num_pipe; |
292 | u32 flush_rings; | ||
293 | #define FLUSH_RENDER_RING 0x1 | ||
294 | #define FLUSH_BSD_RING 0x2 | ||
295 | 307 | ||
296 | /* For hangcheck timer */ | 308 | /* For hangcheck timer */ |
297 | #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ | 309 | #define DRM_I915_HANGCHECK_PERIOD 250 /* in ms */ |
298 | struct timer_list hangcheck_timer; | 310 | struct timer_list hangcheck_timer; |
299 | int hangcheck_count; | 311 | int hangcheck_count; |
300 | uint32_t last_acthd; | 312 | uint32_t last_acthd; |
301 | uint32_t last_instdone; | 313 | uint32_t last_instdone; |
302 | uint32_t last_instdone1; | 314 | uint32_t last_instdone1; |
303 | 315 | ||
304 | struct drm_mm vram; | ||
305 | |||
306 | unsigned long cfb_size; | 316 | unsigned long cfb_size; |
307 | unsigned long cfb_pitch; | 317 | unsigned long cfb_pitch; |
318 | unsigned long cfb_offset; | ||
308 | int cfb_fence; | 319 | int cfb_fence; |
309 | int cfb_plane; | 320 | int cfb_plane; |
321 | int cfb_y; | ||
310 | 322 | ||
311 | int irq_enabled; | 323 | int irq_enabled; |
312 | 324 | ||
@@ -316,7 +328,7 @@ typedef struct drm_i915_private { | |||
316 | struct intel_overlay *overlay; | 328 | struct intel_overlay *overlay; |
317 | 329 | ||
318 | /* LVDS info */ | 330 | /* LVDS info */ |
319 | int backlight_duty_cycle; /* restore backlight to this value */ | 331 | int backlight_level; /* restore backlight to this value */ |
320 | bool panel_wants_dither; | 332 | bool panel_wants_dither; |
321 | struct drm_display_mode *panel_fixed_mode; | 333 | struct drm_display_mode *panel_fixed_mode; |
322 | struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ | 334 | struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ |
@@ -334,7 +346,7 @@ typedef struct drm_i915_private { | |||
334 | 346 | ||
335 | struct notifier_block lid_notifier; | 347 | struct notifier_block lid_notifier; |
336 | 348 | ||
337 | int crt_ddc_bus; /* 0 = unknown, else GPIO to use for CRT DDC */ | 349 | int crt_ddc_pin; |
338 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ | 350 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ |
339 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ | 351 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
340 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ | 352 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ |
@@ -507,6 +519,11 @@ typedef struct drm_i915_private { | |||
507 | u32 saveMCHBAR_RENDER_STANDBY; | 519 | u32 saveMCHBAR_RENDER_STANDBY; |
508 | 520 | ||
509 | struct { | 521 | struct { |
522 | /** Bridge to intel-gtt-ko */ | ||
523 | struct intel_gtt *gtt; | ||
524 | /** Memory allocator for GTT stolen memory */ | ||
525 | struct drm_mm vram; | ||
526 | /** Memory allocator for GTT */ | ||
510 | struct drm_mm gtt_space; | 527 | struct drm_mm gtt_space; |
511 | 528 | ||
512 | struct io_mapping *gtt_mapping; | 529 | struct io_mapping *gtt_mapping; |
@@ -521,8 +538,6 @@ typedef struct drm_i915_private { | |||
521 | */ | 538 | */ |
522 | struct list_head shrink_list; | 539 | struct list_head shrink_list; |
523 | 540 | ||
524 | spinlock_t active_list_lock; | ||
525 | |||
526 | /** | 541 | /** |
527 | * List of objects which are not in the ringbuffer but which | 542 | * List of objects which are not in the ringbuffer but which |
528 | * still have a write_domain which needs to be flushed before | 543 | * still have a write_domain which needs to be flushed before |
@@ -626,8 +641,6 @@ typedef struct drm_i915_private { | |||
626 | /* Reclocking support */ | 641 | /* Reclocking support */ |
627 | bool render_reclock_avail; | 642 | bool render_reclock_avail; |
628 | bool lvds_downclock_avail; | 643 | bool lvds_downclock_avail; |
629 | /* indicate whether the LVDS EDID is OK */ | ||
630 | bool lvds_edid_good; | ||
631 | /* indicates the reduced downclock for LVDS*/ | 644 | /* indicates the reduced downclock for LVDS*/ |
632 | int lvds_downclock; | 645 | int lvds_downclock; |
633 | struct work_struct idle_work; | 646 | struct work_struct idle_work; |
@@ -871,7 +884,6 @@ extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); | |||
871 | 884 | ||
872 | /* i915_irq.c */ | 885 | /* i915_irq.c */ |
873 | void i915_hangcheck_elapsed(unsigned long data); | 886 | void i915_hangcheck_elapsed(unsigned long data); |
874 | void i915_destroy_error_state(struct drm_device *dev); | ||
875 | extern int i915_irq_emit(struct drm_device *dev, void *data, | 887 | extern int i915_irq_emit(struct drm_device *dev, void *data, |
876 | struct drm_file *file_priv); | 888 | struct drm_file *file_priv); |
877 | extern int i915_irq_wait(struct drm_device *dev, void *data, | 889 | extern int i915_irq_wait(struct drm_device *dev, void *data, |
@@ -908,6 +920,12 @@ i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); | |||
908 | 920 | ||
909 | void intel_enable_asle (struct drm_device *dev); | 921 | void intel_enable_asle (struct drm_device *dev); |
910 | 922 | ||
923 | #ifdef CONFIG_DEBUG_FS | ||
924 | extern void i915_destroy_error_state(struct drm_device *dev); | ||
925 | #else | ||
926 | #define i915_destroy_error_state(x) | ||
927 | #endif | ||
928 | |||
911 | 929 | ||
912 | /* i915_mem.c */ | 930 | /* i915_mem.c */ |
913 | extern int i915_mem_alloc(struct drm_device *dev, void *data, | 931 | extern int i915_mem_alloc(struct drm_device *dev, void *data, |
@@ -975,10 +993,11 @@ void i915_gem_lastclose(struct drm_device *dev); | |||
975 | uint32_t i915_get_gem_seqno(struct drm_device *dev, | 993 | uint32_t i915_get_gem_seqno(struct drm_device *dev, |
976 | struct intel_ring_buffer *ring); | 994 | struct intel_ring_buffer *ring); |
977 | bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); | 995 | bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); |
978 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); | 996 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, |
979 | int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); | 997 | bool interruptible); |
998 | int i915_gem_object_put_fence_reg(struct drm_gem_object *obj, | ||
999 | bool interruptible); | ||
980 | void i915_gem_retire_requests(struct drm_device *dev); | 1000 | void i915_gem_retire_requests(struct drm_device *dev); |
981 | void i915_gem_retire_work_handler(struct work_struct *work); | ||
982 | void i915_gem_clflush_object(struct drm_gem_object *obj); | 1001 | void i915_gem_clflush_object(struct drm_gem_object *obj); |
983 | int i915_gem_object_set_domain(struct drm_gem_object *obj, | 1002 | int i915_gem_object_set_domain(struct drm_gem_object *obj, |
984 | uint32_t read_domains, | 1003 | uint32_t read_domains, |
@@ -990,16 +1009,21 @@ int i915_gem_do_init(struct drm_device *dev, unsigned long start, | |||
990 | int i915_gpu_idle(struct drm_device *dev); | 1009 | int i915_gpu_idle(struct drm_device *dev); |
991 | int i915_gem_idle(struct drm_device *dev); | 1010 | int i915_gem_idle(struct drm_device *dev); |
992 | uint32_t i915_add_request(struct drm_device *dev, | 1011 | uint32_t i915_add_request(struct drm_device *dev, |
993 | struct drm_file *file_priv, | 1012 | struct drm_file *file_priv, |
994 | uint32_t flush_domains, | 1013 | struct drm_i915_gem_request *request, |
995 | struct intel_ring_buffer *ring); | 1014 | struct intel_ring_buffer *ring); |
996 | int i915_do_wait_request(struct drm_device *dev, | 1015 | int i915_do_wait_request(struct drm_device *dev, |
997 | uint32_t seqno, int interruptible, | 1016 | uint32_t seqno, |
998 | struct intel_ring_buffer *ring); | 1017 | bool interruptible, |
1018 | struct intel_ring_buffer *ring); | ||
999 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | 1019 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
1020 | void i915_gem_process_flushing_list(struct drm_device *dev, | ||
1021 | uint32_t flush_domains, | ||
1022 | struct intel_ring_buffer *ring); | ||
1000 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, | 1023 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, |
1001 | int write); | 1024 | int write); |
1002 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); | 1025 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj, |
1026 | bool pipelined); | ||
1003 | int i915_gem_attach_phys_object(struct drm_device *dev, | 1027 | int i915_gem_attach_phys_object(struct drm_device *dev, |
1004 | struct drm_gem_object *obj, | 1028 | struct drm_gem_object *obj, |
1005 | int id, | 1029 | int id, |
@@ -1010,7 +1034,6 @@ void i915_gem_free_all_phys_object(struct drm_device *dev); | |||
1010 | int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask); | 1034 | int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask); |
1011 | void i915_gem_object_put_pages(struct drm_gem_object *obj); | 1035 | void i915_gem_object_put_pages(struct drm_gem_object *obj); |
1012 | void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); | 1036 | void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); |
1013 | int i915_gem_object_flush_write_domain(struct drm_gem_object *obj); | ||
1014 | 1037 | ||
1015 | void i915_gem_shrinker_init(void); | 1038 | void i915_gem_shrinker_init(void); |
1016 | void i915_gem_shrinker_exit(void); | 1039 | void i915_gem_shrinker_exit(void); |
@@ -1054,19 +1077,25 @@ extern int i915_restore_state(struct drm_device *dev); | |||
1054 | extern int i915_save_state(struct drm_device *dev); | 1077 | extern int i915_save_state(struct drm_device *dev); |
1055 | extern int i915_restore_state(struct drm_device *dev); | 1078 | extern int i915_restore_state(struct drm_device *dev); |
1056 | 1079 | ||
1080 | /* intel_i2c.c */ | ||
1081 | extern int intel_setup_gmbus(struct drm_device *dev); | ||
1082 | extern void intel_teardown_gmbus(struct drm_device *dev); | ||
1083 | extern void intel_i2c_reset(struct drm_device *dev); | ||
1084 | |||
1085 | /* intel_opregion.c */ | ||
1086 | extern int intel_opregion_setup(struct drm_device *dev); | ||
1057 | #ifdef CONFIG_ACPI | 1087 | #ifdef CONFIG_ACPI |
1058 | /* i915_opregion.c */ | 1088 | extern void intel_opregion_init(struct drm_device *dev); |
1059 | extern int intel_opregion_init(struct drm_device *dev, int resume); | 1089 | extern void intel_opregion_fini(struct drm_device *dev); |
1060 | extern void intel_opregion_free(struct drm_device *dev, int suspend); | 1090 | extern void intel_opregion_asle_intr(struct drm_device *dev); |
1061 | extern void opregion_asle_intr(struct drm_device *dev); | 1091 | extern void intel_opregion_gse_intr(struct drm_device *dev); |
1062 | extern void ironlake_opregion_gse_intr(struct drm_device *dev); | 1092 | extern void intel_opregion_enable_asle(struct drm_device *dev); |
1063 | extern void opregion_enable_asle(struct drm_device *dev); | ||
1064 | #else | 1093 | #else |
1065 | static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; } | 1094 | static inline void intel_opregion_init(struct drm_device *dev) { return; } |
1066 | static inline void intel_opregion_free(struct drm_device *dev, int suspend) { return; } | 1095 | static inline void intel_opregion_fini(struct drm_device *dev) { return; } |
1067 | static inline void opregion_asle_intr(struct drm_device *dev) { return; } | 1096 | static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; } |
1068 | static inline void ironlake_opregion_gse_intr(struct drm_device *dev) { return; } | 1097 | static inline void intel_opregion_gse_intr(struct drm_device *dev) { return; } |
1069 | static inline void opregion_enable_asle(struct drm_device *dev) { return; } | 1098 | static inline void intel_opregion_enable_asle(struct drm_device *dev) { return; } |
1070 | #endif | 1099 | #endif |
1071 | 1100 | ||
1072 | /* modesetting */ | 1101 | /* modesetting */ |
@@ -1084,8 +1113,10 @@ extern void intel_detect_pch (struct drm_device *dev); | |||
1084 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | 1113 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); |
1085 | 1114 | ||
1086 | /* overlay */ | 1115 | /* overlay */ |
1116 | #ifdef CONFIG_DEBUG_FS | ||
1087 | extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); | 1117 | extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); |
1088 | extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); | 1118 | extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); |
1119 | #endif | ||
1089 | 1120 | ||
1090 | /** | 1121 | /** |
1091 | * Lock test for when it's just for synchronization of ring access. | 1122 | * Lock test for when it's just for synchronization of ring access. |
@@ -1099,8 +1130,26 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove | |||
1099 | LOCK_TEST_WITH_RETURN(dev, file_priv); \ | 1130 | LOCK_TEST_WITH_RETURN(dev, file_priv); \ |
1100 | } while (0) | 1131 | } while (0) |
1101 | 1132 | ||
1102 | #define I915_READ(reg) readl(dev_priv->regs + (reg)) | 1133 | static inline u32 i915_read(struct drm_i915_private *dev_priv, u32 reg) |
1103 | #define I915_WRITE(reg, val) writel(val, dev_priv->regs + (reg)) | 1134 | { |
1135 | u32 val; | ||
1136 | |||
1137 | val = readl(dev_priv->regs + reg); | ||
1138 | if (dev_priv->debug_flags & I915_DEBUG_READ) | ||
1139 | printk(KERN_ERR "read 0x%08x from 0x%08x\n", val, reg); | ||
1140 | return val; | ||
1141 | } | ||
1142 | |||
1143 | static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, | ||
1144 | u32 val) | ||
1145 | { | ||
1146 | writel(val, dev_priv->regs + reg); | ||
1147 | if (dev_priv->debug_flags & I915_DEBUG_WRITE) | ||
1148 | printk(KERN_ERR "wrote 0x%08x to 0x%08x\n", val, reg); | ||
1149 | } | ||
1150 | |||
1151 | #define I915_READ(reg) i915_read(dev_priv, (reg)) | ||
1152 | #define I915_WRITE(reg, val) i915_write(dev_priv, (reg), (val)) | ||
1104 | #define I915_READ16(reg) readw(dev_priv->regs + (reg)) | 1153 | #define I915_READ16(reg) readw(dev_priv->regs + (reg)) |
1105 | #define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg)) | 1154 | #define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg)) |
1106 | #define I915_READ8(reg) readb(dev_priv->regs + (reg)) | 1155 | #define I915_READ8(reg) readb(dev_priv->regs + (reg)) |
@@ -1110,6 +1159,11 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove | |||
1110 | #define POSTING_READ(reg) (void)I915_READ(reg) | 1159 | #define POSTING_READ(reg) (void)I915_READ(reg) |
1111 | #define POSTING_READ16(reg) (void)I915_READ16(reg) | 1160 | #define POSTING_READ16(reg) (void)I915_READ16(reg) |
1112 | 1161 | ||
1162 | #define I915_DEBUG_ENABLE_IO() (dev_priv->debug_flags |= I915_DEBUG_READ | \ | ||
1163 | I915_DEBUG_WRITE) | ||
1164 | #define I915_DEBUG_DISABLE_IO() (dev_priv->debug_flags &= ~(I915_DEBUG_READ | \ | ||
1165 | I915_DEBUG_WRITE)) | ||
1166 | |||
1113 | #define I915_VERBOSE 0 | 1167 | #define I915_VERBOSE 0 |
1114 | 1168 | ||
1115 | #define BEGIN_LP_RING(n) do { \ | 1169 | #define BEGIN_LP_RING(n) do { \ |
@@ -1191,6 +1245,9 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove | |||
1191 | #define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev)) | 1245 | #define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev)) |
1192 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) | 1246 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) |
1193 | 1247 | ||
1248 | #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) | ||
1249 | #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) | ||
1250 | |||
1194 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte | 1251 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte |
1195 | * rows, which changed the alignment requirements and fence programming. | 1252 | * rows, which changed the alignment requirements and fence programming. |
1196 | */ | 1253 | */ |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index cf4ffbee1c00..0355cd28b270 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -37,7 +37,9 @@ | |||
37 | #include <linux/intel-gtt.h> | 37 | #include <linux/intel-gtt.h> |
38 | 38 | ||
39 | static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); | 39 | static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); |
40 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); | 40 | |
41 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, | ||
42 | bool pipelined); | ||
41 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); | 43 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); |
42 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); | 44 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); |
43 | static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, | 45 | static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, |
@@ -46,7 +48,8 @@ static int i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, | |||
46 | uint64_t offset, | 48 | uint64_t offset, |
47 | uint64_t size); | 49 | uint64_t size); |
48 | static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj); | 50 | static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj); |
49 | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); | 51 | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj, |
52 | bool interruptible); | ||
50 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 53 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, |
51 | unsigned alignment); | 54 | unsigned alignment); |
52 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); | 55 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); |
@@ -1179,7 +1182,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1179 | 1182 | ||
1180 | /* Need a new fence register? */ | 1183 | /* Need a new fence register? */ |
1181 | if (obj_priv->tiling_mode != I915_TILING_NONE) { | 1184 | if (obj_priv->tiling_mode != I915_TILING_NONE) { |
1182 | ret = i915_gem_object_get_fence_reg(obj); | 1185 | ret = i915_gem_object_get_fence_reg(obj, true); |
1183 | if (ret) | 1186 | if (ret) |
1184 | goto unlock; | 1187 | goto unlock; |
1185 | } | 1188 | } |
@@ -1468,13 +1471,25 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) | |||
1468 | obj_priv->pages = NULL; | 1471 | obj_priv->pages = NULL; |
1469 | } | 1472 | } |
1470 | 1473 | ||
1474 | static uint32_t | ||
1475 | i915_gem_next_request_seqno(struct drm_device *dev, | ||
1476 | struct intel_ring_buffer *ring) | ||
1477 | { | ||
1478 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1479 | |||
1480 | ring->outstanding_lazy_request = true; | ||
1481 | |||
1482 | return dev_priv->next_seqno; | ||
1483 | } | ||
1484 | |||
1471 | static void | 1485 | static void |
1472 | i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno, | 1486 | i915_gem_object_move_to_active(struct drm_gem_object *obj, |
1473 | struct intel_ring_buffer *ring) | 1487 | struct intel_ring_buffer *ring) |
1474 | { | 1488 | { |
1475 | struct drm_device *dev = obj->dev; | 1489 | struct drm_device *dev = obj->dev; |
1476 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1477 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1490 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1491 | uint32_t seqno = i915_gem_next_request_seqno(dev, ring); | ||
1492 | |||
1478 | BUG_ON(ring == NULL); | 1493 | BUG_ON(ring == NULL); |
1479 | obj_priv->ring = ring; | 1494 | obj_priv->ring = ring; |
1480 | 1495 | ||
@@ -1483,10 +1498,9 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno, | |||
1483 | drm_gem_object_reference(obj); | 1498 | drm_gem_object_reference(obj); |
1484 | obj_priv->active = 1; | 1499 | obj_priv->active = 1; |
1485 | } | 1500 | } |
1501 | |||
1486 | /* Move from whatever list we were on to the tail of execution. */ | 1502 | /* Move from whatever list we were on to the tail of execution. */ |
1487 | spin_lock(&dev_priv->mm.active_list_lock); | ||
1488 | list_move_tail(&obj_priv->list, &ring->active_list); | 1503 | list_move_tail(&obj_priv->list, &ring->active_list); |
1489 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
1490 | obj_priv->last_rendering_seqno = seqno; | 1504 | obj_priv->last_rendering_seqno = seqno; |
1491 | } | 1505 | } |
1492 | 1506 | ||
@@ -1553,9 +1567,9 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) | |||
1553 | i915_verify_inactive(dev, __FILE__, __LINE__); | 1567 | i915_verify_inactive(dev, __FILE__, __LINE__); |
1554 | } | 1568 | } |
1555 | 1569 | ||
1556 | static void | 1570 | void |
1557 | i915_gem_process_flushing_list(struct drm_device *dev, | 1571 | i915_gem_process_flushing_list(struct drm_device *dev, |
1558 | uint32_t flush_domains, uint32_t seqno, | 1572 | uint32_t flush_domains, |
1559 | struct intel_ring_buffer *ring) | 1573 | struct intel_ring_buffer *ring) |
1560 | { | 1574 | { |
1561 | drm_i915_private_t *dev_priv = dev->dev_private; | 1575 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -1566,14 +1580,13 @@ i915_gem_process_flushing_list(struct drm_device *dev, | |||
1566 | gpu_write_list) { | 1580 | gpu_write_list) { |
1567 | struct drm_gem_object *obj = &obj_priv->base; | 1581 | struct drm_gem_object *obj = &obj_priv->base; |
1568 | 1582 | ||
1569 | if ((obj->write_domain & flush_domains) == | 1583 | if (obj->write_domain & flush_domains && |
1570 | obj->write_domain && | 1584 | obj_priv->ring == ring) { |
1571 | obj_priv->ring->ring_flag == ring->ring_flag) { | ||
1572 | uint32_t old_write_domain = obj->write_domain; | 1585 | uint32_t old_write_domain = obj->write_domain; |
1573 | 1586 | ||
1574 | obj->write_domain = 0; | 1587 | obj->write_domain = 0; |
1575 | list_del_init(&obj_priv->gpu_write_list); | 1588 | list_del_init(&obj_priv->gpu_write_list); |
1576 | i915_gem_object_move_to_active(obj, seqno, ring); | 1589 | i915_gem_object_move_to_active(obj, ring); |
1577 | 1590 | ||
1578 | /* update the fence lru list */ | 1591 | /* update the fence lru list */ |
1579 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | 1592 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { |
@@ -1591,23 +1604,26 @@ i915_gem_process_flushing_list(struct drm_device *dev, | |||
1591 | } | 1604 | } |
1592 | 1605 | ||
1593 | uint32_t | 1606 | uint32_t |
1594 | i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | 1607 | i915_add_request(struct drm_device *dev, |
1595 | uint32_t flush_domains, struct intel_ring_buffer *ring) | 1608 | struct drm_file *file_priv, |
1609 | struct drm_i915_gem_request *request, | ||
1610 | struct intel_ring_buffer *ring) | ||
1596 | { | 1611 | { |
1597 | drm_i915_private_t *dev_priv = dev->dev_private; | 1612 | drm_i915_private_t *dev_priv = dev->dev_private; |
1598 | struct drm_i915_file_private *i915_file_priv = NULL; | 1613 | struct drm_i915_file_private *i915_file_priv = NULL; |
1599 | struct drm_i915_gem_request *request; | ||
1600 | uint32_t seqno; | 1614 | uint32_t seqno; |
1601 | int was_empty; | 1615 | int was_empty; |
1602 | 1616 | ||
1603 | if (file_priv != NULL) | 1617 | if (file_priv != NULL) |
1604 | i915_file_priv = file_priv->driver_priv; | 1618 | i915_file_priv = file_priv->driver_priv; |
1605 | 1619 | ||
1606 | request = kzalloc(sizeof(*request), GFP_KERNEL); | 1620 | if (request == NULL) { |
1607 | if (request == NULL) | 1621 | request = kzalloc(sizeof(*request), GFP_KERNEL); |
1608 | return 0; | 1622 | if (request == NULL) |
1623 | return 0; | ||
1624 | } | ||
1609 | 1625 | ||
1610 | seqno = ring->add_request(dev, ring, file_priv, flush_domains); | 1626 | seqno = ring->add_request(dev, ring, file_priv, 0); |
1611 | 1627 | ||
1612 | request->seqno = seqno; | 1628 | request->seqno = seqno; |
1613 | request->ring = ring; | 1629 | request->ring = ring; |
@@ -1622,16 +1638,12 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
1622 | INIT_LIST_HEAD(&request->client_list); | 1638 | INIT_LIST_HEAD(&request->client_list); |
1623 | } | 1639 | } |
1624 | 1640 | ||
1625 | /* Associate any objects on the flushing list matching the write | ||
1626 | * domain we're flushing with our flush. | ||
1627 | */ | ||
1628 | if (flush_domains != 0) | ||
1629 | i915_gem_process_flushing_list(dev, flush_domains, seqno, ring); | ||
1630 | |||
1631 | if (!dev_priv->mm.suspended) { | 1641 | if (!dev_priv->mm.suspended) { |
1632 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); | 1642 | mod_timer(&dev_priv->hangcheck_timer, |
1643 | jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); | ||
1633 | if (was_empty) | 1644 | if (was_empty) |
1634 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); | 1645 | queue_delayed_work(dev_priv->wq, |
1646 | &dev_priv->mm.retire_work, HZ); | ||
1635 | } | 1647 | } |
1636 | return seqno; | 1648 | return seqno; |
1637 | } | 1649 | } |
@@ -1642,7 +1654,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
1642 | * Ensures that all commands in the ring are finished | 1654 | * Ensures that all commands in the ring are finished |
1643 | * before signalling the CPU | 1655 | * before signalling the CPU |
1644 | */ | 1656 | */ |
1645 | static uint32_t | 1657 | static void |
1646 | i915_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring) | 1658 | i915_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring) |
1647 | { | 1659 | { |
1648 | uint32_t flush_domains = 0; | 1660 | uint32_t flush_domains = 0; |
@@ -1653,7 +1665,6 @@ i915_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring) | |||
1653 | 1665 | ||
1654 | ring->flush(dev, ring, | 1666 | ring->flush(dev, ring, |
1655 | I915_GEM_DOMAIN_COMMAND, flush_domains); | 1667 | I915_GEM_DOMAIN_COMMAND, flush_domains); |
1656 | return flush_domains; | ||
1657 | } | 1668 | } |
1658 | 1669 | ||
1659 | /** | 1670 | /** |
@@ -1664,14 +1675,11 @@ static void | |||
1664 | i915_gem_retire_request(struct drm_device *dev, | 1675 | i915_gem_retire_request(struct drm_device *dev, |
1665 | struct drm_i915_gem_request *request) | 1676 | struct drm_i915_gem_request *request) |
1666 | { | 1677 | { |
1667 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1668 | |||
1669 | trace_i915_gem_request_retire(dev, request->seqno); | 1678 | trace_i915_gem_request_retire(dev, request->seqno); |
1670 | 1679 | ||
1671 | /* Move any buffers on the active list that are no longer referenced | 1680 | /* Move any buffers on the active list that are no longer referenced |
1672 | * by the ringbuffer to the flushing/inactive lists as appropriate. | 1681 | * by the ringbuffer to the flushing/inactive lists as appropriate. |
1673 | */ | 1682 | */ |
1674 | spin_lock(&dev_priv->mm.active_list_lock); | ||
1675 | while (!list_empty(&request->ring->active_list)) { | 1683 | while (!list_empty(&request->ring->active_list)) { |
1676 | struct drm_gem_object *obj; | 1684 | struct drm_gem_object *obj; |
1677 | struct drm_i915_gem_object *obj_priv; | 1685 | struct drm_i915_gem_object *obj_priv; |
@@ -1686,7 +1694,7 @@ i915_gem_retire_request(struct drm_device *dev, | |||
1686 | * this seqno. | 1694 | * this seqno. |
1687 | */ | 1695 | */ |
1688 | if (obj_priv->last_rendering_seqno != request->seqno) | 1696 | if (obj_priv->last_rendering_seqno != request->seqno) |
1689 | goto out; | 1697 | return; |
1690 | 1698 | ||
1691 | #if WATCH_LRU | 1699 | #if WATCH_LRU |
1692 | DRM_INFO("%s: retire %d moves to inactive list %p\n", | 1700 | DRM_INFO("%s: retire %d moves to inactive list %p\n", |
@@ -1695,22 +1703,9 @@ i915_gem_retire_request(struct drm_device *dev, | |||
1695 | 1703 | ||
1696 | if (obj->write_domain != 0) | 1704 | if (obj->write_domain != 0) |
1697 | i915_gem_object_move_to_flushing(obj); | 1705 | i915_gem_object_move_to_flushing(obj); |
1698 | else { | 1706 | else |
1699 | /* Take a reference on the object so it won't be | ||
1700 | * freed while the spinlock is held. The list | ||
1701 | * protection for this spinlock is safe when breaking | ||
1702 | * the lock like this since the next thing we do | ||
1703 | * is just get the head of the list again. | ||
1704 | */ | ||
1705 | drm_gem_object_reference(obj); | ||
1706 | i915_gem_object_move_to_inactive(obj); | 1707 | i915_gem_object_move_to_inactive(obj); |
1707 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
1708 | drm_gem_object_unreference(obj); | ||
1709 | spin_lock(&dev_priv->mm.active_list_lock); | ||
1710 | } | ||
1711 | } | 1708 | } |
1712 | out: | ||
1713 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
1714 | } | 1709 | } |
1715 | 1710 | ||
1716 | /** | 1711 | /** |
@@ -1797,7 +1792,7 @@ i915_gem_retire_requests(struct drm_device *dev) | |||
1797 | i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring); | 1792 | i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring); |
1798 | } | 1793 | } |
1799 | 1794 | ||
1800 | void | 1795 | static void |
1801 | i915_gem_retire_work_handler(struct work_struct *work) | 1796 | i915_gem_retire_work_handler(struct work_struct *work) |
1802 | { | 1797 | { |
1803 | drm_i915_private_t *dev_priv; | 1798 | drm_i915_private_t *dev_priv; |
@@ -1820,7 +1815,7 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
1820 | 1815 | ||
1821 | int | 1816 | int |
1822 | i915_do_wait_request(struct drm_device *dev, uint32_t seqno, | 1817 | i915_do_wait_request(struct drm_device *dev, uint32_t seqno, |
1823 | int interruptible, struct intel_ring_buffer *ring) | 1818 | bool interruptible, struct intel_ring_buffer *ring) |
1824 | { | 1819 | { |
1825 | drm_i915_private_t *dev_priv = dev->dev_private; | 1820 | drm_i915_private_t *dev_priv = dev->dev_private; |
1826 | u32 ier; | 1821 | u32 ier; |
@@ -1828,6 +1823,12 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, | |||
1828 | 1823 | ||
1829 | BUG_ON(seqno == 0); | 1824 | BUG_ON(seqno == 0); |
1830 | 1825 | ||
1826 | if (seqno == dev_priv->next_seqno) { | ||
1827 | seqno = i915_add_request(dev, NULL, NULL, ring); | ||
1828 | if (seqno == 0) | ||
1829 | return -ENOMEM; | ||
1830 | } | ||
1831 | |||
1831 | if (atomic_read(&dev_priv->mm.wedged)) | 1832 | if (atomic_read(&dev_priv->mm.wedged)) |
1832 | return -EIO; | 1833 | return -EIO; |
1833 | 1834 | ||
@@ -1867,8 +1868,9 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, | |||
1867 | ret = -EIO; | 1868 | ret = -EIO; |
1868 | 1869 | ||
1869 | if (ret && ret != -ERESTARTSYS) | 1870 | if (ret && ret != -ERESTARTSYS) |
1870 | DRM_ERROR("%s returns %d (awaiting %d at %d)\n", | 1871 | DRM_ERROR("%s returns %d (awaiting %d at %d, next %d)\n", |
1871 | __func__, ret, seqno, ring->get_gem_seqno(dev, ring)); | 1872 | __func__, ret, seqno, ring->get_gem_seqno(dev, ring), |
1873 | dev_priv->next_seqno); | ||
1872 | 1874 | ||
1873 | /* Directly dispatch request retiring. While we have the work queue | 1875 | /* Directly dispatch request retiring. While we have the work queue |
1874 | * to handle this, the waiter on a request often wants an associated | 1876 | * to handle this, the waiter on a request often wants an associated |
@@ -1898,8 +1900,10 @@ i915_gem_flush(struct drm_device *dev, | |||
1898 | uint32_t flush_domains) | 1900 | uint32_t flush_domains) |
1899 | { | 1901 | { |
1900 | drm_i915_private_t *dev_priv = dev->dev_private; | 1902 | drm_i915_private_t *dev_priv = dev->dev_private; |
1903 | |||
1901 | if (flush_domains & I915_GEM_DOMAIN_CPU) | 1904 | if (flush_domains & I915_GEM_DOMAIN_CPU) |
1902 | drm_agp_chipset_flush(dev); | 1905 | drm_agp_chipset_flush(dev); |
1906 | |||
1903 | dev_priv->render_ring.flush(dev, &dev_priv->render_ring, | 1907 | dev_priv->render_ring.flush(dev, &dev_priv->render_ring, |
1904 | invalidate_domains, | 1908 | invalidate_domains, |
1905 | flush_domains); | 1909 | flush_domains); |
@@ -1915,7 +1919,8 @@ i915_gem_flush(struct drm_device *dev, | |||
1915 | * safe to unbind from the GTT or access from the CPU. | 1919 | * safe to unbind from the GTT or access from the CPU. |
1916 | */ | 1920 | */ |
1917 | static int | 1921 | static int |
1918 | i915_gem_object_wait_rendering(struct drm_gem_object *obj) | 1922 | i915_gem_object_wait_rendering(struct drm_gem_object *obj, |
1923 | bool interruptible) | ||
1919 | { | 1924 | { |
1920 | struct drm_device *dev = obj->dev; | 1925 | struct drm_device *dev = obj->dev; |
1921 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1926 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
@@ -1934,9 +1939,11 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj) | |||
1934 | DRM_INFO("%s: object %p wait for seqno %08x\n", | 1939 | DRM_INFO("%s: object %p wait for seqno %08x\n", |
1935 | __func__, obj, obj_priv->last_rendering_seqno); | 1940 | __func__, obj, obj_priv->last_rendering_seqno); |
1936 | #endif | 1941 | #endif |
1937 | ret = i915_wait_request(dev, | 1942 | ret = i915_do_wait_request(dev, |
1938 | obj_priv->last_rendering_seqno, obj_priv->ring); | 1943 | obj_priv->last_rendering_seqno, |
1939 | if (ret != 0) | 1944 | interruptible, |
1945 | obj_priv->ring); | ||
1946 | if (ret) | ||
1940 | return ret; | 1947 | return ret; |
1941 | } | 1948 | } |
1942 | 1949 | ||
@@ -1950,7 +1957,6 @@ int | |||
1950 | i915_gem_object_unbind(struct drm_gem_object *obj) | 1957 | i915_gem_object_unbind(struct drm_gem_object *obj) |
1951 | { | 1958 | { |
1952 | struct drm_device *dev = obj->dev; | 1959 | struct drm_device *dev = obj->dev; |
1953 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1954 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1960 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1955 | int ret = 0; | 1961 | int ret = 0; |
1956 | 1962 | ||
@@ -2005,10 +2011,8 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
2005 | } | 2011 | } |
2006 | 2012 | ||
2007 | /* Remove ourselves from the LRU list if present. */ | 2013 | /* Remove ourselves from the LRU list if present. */ |
2008 | spin_lock(&dev_priv->mm.active_list_lock); | ||
2009 | if (!list_empty(&obj_priv->list)) | 2014 | if (!list_empty(&obj_priv->list)) |
2010 | list_del_init(&obj_priv->list); | 2015 | list_del_init(&obj_priv->list); |
2011 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
2012 | 2016 | ||
2013 | if (i915_gem_object_is_purgeable(obj_priv)) | 2017 | if (i915_gem_object_is_purgeable(obj_priv)) |
2014 | i915_gem_object_truncate(obj); | 2018 | i915_gem_object_truncate(obj); |
@@ -2023,40 +2027,33 @@ i915_gpu_idle(struct drm_device *dev) | |||
2023 | { | 2027 | { |
2024 | drm_i915_private_t *dev_priv = dev->dev_private; | 2028 | drm_i915_private_t *dev_priv = dev->dev_private; |
2025 | bool lists_empty; | 2029 | bool lists_empty; |
2026 | uint32_t seqno1, seqno2; | ||
2027 | int ret; | 2030 | int ret; |
2028 | 2031 | ||
2029 | spin_lock(&dev_priv->mm.active_list_lock); | ||
2030 | lists_empty = (list_empty(&dev_priv->mm.flushing_list) && | 2032 | lists_empty = (list_empty(&dev_priv->mm.flushing_list) && |
2031 | list_empty(&dev_priv->render_ring.active_list) && | 2033 | list_empty(&dev_priv->render_ring.active_list) && |
2032 | (!HAS_BSD(dev) || | 2034 | (!HAS_BSD(dev) || |
2033 | list_empty(&dev_priv->bsd_ring.active_list))); | 2035 | list_empty(&dev_priv->bsd_ring.active_list))); |
2034 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
2035 | |||
2036 | if (lists_empty) | 2036 | if (lists_empty) |
2037 | return 0; | 2037 | return 0; |
2038 | 2038 | ||
2039 | /* Flush everything onto the inactive list. */ | 2039 | /* Flush everything onto the inactive list. */ |
2040 | i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); | 2040 | i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); |
2041 | seqno1 = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS, | ||
2042 | &dev_priv->render_ring); | ||
2043 | if (seqno1 == 0) | ||
2044 | return -ENOMEM; | ||
2045 | ret = i915_wait_request(dev, seqno1, &dev_priv->render_ring); | ||
2046 | 2041 | ||
2047 | if (HAS_BSD(dev)) { | 2042 | ret = i915_wait_request(dev, |
2048 | seqno2 = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS, | 2043 | i915_gem_next_request_seqno(dev, &dev_priv->render_ring), |
2049 | &dev_priv->bsd_ring); | 2044 | &dev_priv->render_ring); |
2050 | if (seqno2 == 0) | 2045 | if (ret) |
2051 | return -ENOMEM; | 2046 | return ret; |
2052 | 2047 | ||
2053 | ret = i915_wait_request(dev, seqno2, &dev_priv->bsd_ring); | 2048 | if (HAS_BSD(dev)) { |
2049 | ret = i915_wait_request(dev, | ||
2050 | i915_gem_next_request_seqno(dev, &dev_priv->bsd_ring), | ||
2051 | &dev_priv->bsd_ring); | ||
2054 | if (ret) | 2052 | if (ret) |
2055 | return ret; | 2053 | return ret; |
2056 | } | 2054 | } |
2057 | 2055 | ||
2058 | 2056 | return 0; | |
2059 | return ret; | ||
2060 | } | 2057 | } |
2061 | 2058 | ||
2062 | int | 2059 | int |
@@ -2239,7 +2236,8 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) | |||
2239 | I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val); | 2236 | I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val); |
2240 | } | 2237 | } |
2241 | 2238 | ||
2242 | static int i915_find_fence_reg(struct drm_device *dev) | 2239 | static int i915_find_fence_reg(struct drm_device *dev, |
2240 | bool interruptible) | ||
2243 | { | 2241 | { |
2244 | struct drm_i915_fence_reg *reg = NULL; | 2242 | struct drm_i915_fence_reg *reg = NULL; |
2245 | struct drm_i915_gem_object *obj_priv = NULL; | 2243 | struct drm_i915_gem_object *obj_priv = NULL; |
@@ -2284,7 +2282,7 @@ static int i915_find_fence_reg(struct drm_device *dev) | |||
2284 | * private reference to obj like the other callers of put_fence_reg | 2282 | * private reference to obj like the other callers of put_fence_reg |
2285 | * (set_tiling ioctl) do. */ | 2283 | * (set_tiling ioctl) do. */ |
2286 | drm_gem_object_reference(obj); | 2284 | drm_gem_object_reference(obj); |
2287 | ret = i915_gem_object_put_fence_reg(obj); | 2285 | ret = i915_gem_object_put_fence_reg(obj, interruptible); |
2288 | drm_gem_object_unreference(obj); | 2286 | drm_gem_object_unreference(obj); |
2289 | if (ret != 0) | 2287 | if (ret != 0) |
2290 | return ret; | 2288 | return ret; |
@@ -2306,7 +2304,8 @@ static int i915_find_fence_reg(struct drm_device *dev) | |||
2306 | * and tiling format. | 2304 | * and tiling format. |
2307 | */ | 2305 | */ |
2308 | int | 2306 | int |
2309 | i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | 2307 | i915_gem_object_get_fence_reg(struct drm_gem_object *obj, |
2308 | bool interruptible) | ||
2310 | { | 2309 | { |
2311 | struct drm_device *dev = obj->dev; | 2310 | struct drm_device *dev = obj->dev; |
2312 | struct drm_i915_private *dev_priv = dev->dev_private; | 2311 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -2341,7 +2340,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2341 | break; | 2340 | break; |
2342 | } | 2341 | } |
2343 | 2342 | ||
2344 | ret = i915_find_fence_reg(dev); | 2343 | ret = i915_find_fence_reg(dev, interruptible); |
2345 | if (ret < 0) | 2344 | if (ret < 0) |
2346 | return ret; | 2345 | return ret; |
2347 | 2346 | ||
@@ -2419,12 +2418,14 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2419 | * i915_gem_object_put_fence_reg - waits on outstanding fenced access | 2418 | * i915_gem_object_put_fence_reg - waits on outstanding fenced access |
2420 | * to the buffer to finish, and then resets the fence register. | 2419 | * to the buffer to finish, and then resets the fence register. |
2421 | * @obj: tiled object holding a fence register. | 2420 | * @obj: tiled object holding a fence register. |
2421 | * @bool: whether the wait upon the fence is interruptible | ||
2422 | * | 2422 | * |
2423 | * Zeroes out the fence register itself and clears out the associated | 2423 | * Zeroes out the fence register itself and clears out the associated |
2424 | * data structures in dev_priv and obj_priv. | 2424 | * data structures in dev_priv and obj_priv. |
2425 | */ | 2425 | */ |
2426 | int | 2426 | int |
2427 | i915_gem_object_put_fence_reg(struct drm_gem_object *obj) | 2427 | i915_gem_object_put_fence_reg(struct drm_gem_object *obj, |
2428 | bool interruptible) | ||
2428 | { | 2429 | { |
2429 | struct drm_device *dev = obj->dev; | 2430 | struct drm_device *dev = obj->dev; |
2430 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2431 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
@@ -2445,17 +2446,17 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj) | |||
2445 | if (!IS_I965G(dev)) { | 2446 | if (!IS_I965G(dev)) { |
2446 | int ret; | 2447 | int ret; |
2447 | 2448 | ||
2448 | ret = i915_gem_object_flush_gpu_write_domain(obj); | 2449 | ret = i915_gem_object_flush_gpu_write_domain(obj, true); |
2449 | if (ret != 0) | 2450 | if (ret) |
2450 | return ret; | 2451 | return ret; |
2451 | 2452 | ||
2452 | ret = i915_gem_object_wait_rendering(obj); | 2453 | ret = i915_gem_object_wait_rendering(obj, interruptible); |
2453 | if (ret != 0) | 2454 | if (ret) |
2454 | return ret; | 2455 | return ret; |
2455 | } | 2456 | } |
2456 | 2457 | ||
2457 | i915_gem_object_flush_gtt_write_domain(obj); | 2458 | i915_gem_object_flush_gtt_write_domain(obj); |
2458 | i915_gem_clear_fence_reg (obj); | 2459 | i915_gem_clear_fence_reg(obj); |
2459 | 2460 | ||
2460 | return 0; | 2461 | return 0; |
2461 | } | 2462 | } |
@@ -2601,11 +2602,11 @@ i915_gem_clflush_object(struct drm_gem_object *obj) | |||
2601 | 2602 | ||
2602 | /** Flushes any GPU write domain for the object if it's dirty. */ | 2603 | /** Flushes any GPU write domain for the object if it's dirty. */ |
2603 | static int | 2604 | static int |
2604 | i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) | 2605 | i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, |
2606 | bool pipelined) | ||
2605 | { | 2607 | { |
2606 | struct drm_device *dev = obj->dev; | 2608 | struct drm_device *dev = obj->dev; |
2607 | uint32_t old_write_domain; | 2609 | uint32_t old_write_domain; |
2608 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
2609 | 2610 | ||
2610 | if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) | 2611 | if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) |
2611 | return 0; | 2612 | return 0; |
@@ -2613,13 +2614,16 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) | |||
2613 | /* Queue the GPU write cache flushing we need. */ | 2614 | /* Queue the GPU write cache flushing we need. */ |
2614 | old_write_domain = obj->write_domain; | 2615 | old_write_domain = obj->write_domain; |
2615 | i915_gem_flush(dev, 0, obj->write_domain); | 2616 | i915_gem_flush(dev, 0, obj->write_domain); |
2616 | if (i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring) == 0) | 2617 | BUG_ON(obj->write_domain); |
2617 | return -ENOMEM; | ||
2618 | 2618 | ||
2619 | trace_i915_gem_object_change_domain(obj, | 2619 | trace_i915_gem_object_change_domain(obj, |
2620 | obj->read_domains, | 2620 | obj->read_domains, |
2621 | old_write_domain); | 2621 | old_write_domain); |
2622 | return 0; | 2622 | |
2623 | if (pipelined) | ||
2624 | return 0; | ||
2625 | |||
2626 | return i915_gem_object_wait_rendering(obj, true); | ||
2623 | } | 2627 | } |
2624 | 2628 | ||
2625 | /** Flushes the GTT write domain for the object if it's dirty. */ | 2629 | /** Flushes the GTT write domain for the object if it's dirty. */ |
@@ -2663,26 +2667,6 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) | |||
2663 | old_write_domain); | 2667 | old_write_domain); |
2664 | } | 2668 | } |
2665 | 2669 | ||
2666 | int | ||
2667 | i915_gem_object_flush_write_domain(struct drm_gem_object *obj) | ||
2668 | { | ||
2669 | int ret = 0; | ||
2670 | |||
2671 | switch (obj->write_domain) { | ||
2672 | case I915_GEM_DOMAIN_GTT: | ||
2673 | i915_gem_object_flush_gtt_write_domain(obj); | ||
2674 | break; | ||
2675 | case I915_GEM_DOMAIN_CPU: | ||
2676 | i915_gem_object_flush_cpu_write_domain(obj); | ||
2677 | break; | ||
2678 | default: | ||
2679 | ret = i915_gem_object_flush_gpu_write_domain(obj); | ||
2680 | break; | ||
2681 | } | ||
2682 | |||
2683 | return ret; | ||
2684 | } | ||
2685 | |||
2686 | /** | 2670 | /** |
2687 | * Moves a single object to the GTT read, and possibly write domain. | 2671 | * Moves a single object to the GTT read, and possibly write domain. |
2688 | * | 2672 | * |
@@ -2700,32 +2684,28 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) | |||
2700 | if (obj_priv->gtt_space == NULL) | 2684 | if (obj_priv->gtt_space == NULL) |
2701 | return -EINVAL; | 2685 | return -EINVAL; |
2702 | 2686 | ||
2703 | ret = i915_gem_object_flush_gpu_write_domain(obj); | 2687 | ret = i915_gem_object_flush_gpu_write_domain(obj, false); |
2704 | if (ret != 0) | 2688 | if (ret != 0) |
2705 | return ret; | 2689 | return ret; |
2706 | 2690 | ||
2707 | /* Wait on any GPU rendering and flushing to occur. */ | 2691 | i915_gem_object_flush_cpu_write_domain(obj); |
2708 | ret = i915_gem_object_wait_rendering(obj); | 2692 | |
2709 | if (ret != 0) | 2693 | if (write) { |
2710 | return ret; | 2694 | ret = i915_gem_object_wait_rendering(obj, true); |
2695 | if (ret) | ||
2696 | return ret; | ||
2697 | } | ||
2711 | 2698 | ||
2712 | old_write_domain = obj->write_domain; | 2699 | old_write_domain = obj->write_domain; |
2713 | old_read_domains = obj->read_domains; | 2700 | old_read_domains = obj->read_domains; |
2714 | 2701 | ||
2715 | /* If we're writing through the GTT domain, then CPU and GPU caches | ||
2716 | * will need to be invalidated at next use. | ||
2717 | */ | ||
2718 | if (write) | ||
2719 | obj->read_domains &= I915_GEM_DOMAIN_GTT; | ||
2720 | |||
2721 | i915_gem_object_flush_cpu_write_domain(obj); | ||
2722 | |||
2723 | /* It should now be out of any other write domains, and we can update | 2702 | /* It should now be out of any other write domains, and we can update |
2724 | * the domain values for our changes. | 2703 | * the domain values for our changes. |
2725 | */ | 2704 | */ |
2726 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); | 2705 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); |
2727 | obj->read_domains |= I915_GEM_DOMAIN_GTT; | 2706 | obj->read_domains |= I915_GEM_DOMAIN_GTT; |
2728 | if (write) { | 2707 | if (write) { |
2708 | obj->read_domains = I915_GEM_DOMAIN_GTT; | ||
2729 | obj->write_domain = I915_GEM_DOMAIN_GTT; | 2709 | obj->write_domain = I915_GEM_DOMAIN_GTT; |
2730 | obj_priv->dirty = 1; | 2710 | obj_priv->dirty = 1; |
2731 | } | 2711 | } |
@@ -2742,51 +2722,29 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) | |||
2742 | * wait, as in modesetting process we're not supposed to be interrupted. | 2722 | * wait, as in modesetting process we're not supposed to be interrupted. |
2743 | */ | 2723 | */ |
2744 | int | 2724 | int |
2745 | i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) | 2725 | i915_gem_object_set_to_display_plane(struct drm_gem_object *obj, |
2726 | bool pipelined) | ||
2746 | { | 2727 | { |
2747 | struct drm_device *dev = obj->dev; | ||
2748 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2728 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2749 | uint32_t old_write_domain, old_read_domains; | 2729 | uint32_t old_read_domains; |
2750 | int ret; | 2730 | int ret; |
2751 | 2731 | ||
2752 | /* Not valid to be called on unbound objects. */ | 2732 | /* Not valid to be called on unbound objects. */ |
2753 | if (obj_priv->gtt_space == NULL) | 2733 | if (obj_priv->gtt_space == NULL) |
2754 | return -EINVAL; | 2734 | return -EINVAL; |
2755 | 2735 | ||
2756 | ret = i915_gem_object_flush_gpu_write_domain(obj); | 2736 | ret = i915_gem_object_flush_gpu_write_domain(obj, pipelined); |
2757 | if (ret) | 2737 | if (ret) |
2758 | return ret; | 2738 | return ret; |
2759 | 2739 | ||
2760 | /* Wait on any GPU rendering and flushing to occur. */ | ||
2761 | if (obj_priv->active) { | ||
2762 | #if WATCH_BUF | ||
2763 | DRM_INFO("%s: object %p wait for seqno %08x\n", | ||
2764 | __func__, obj, obj_priv->last_rendering_seqno); | ||
2765 | #endif | ||
2766 | ret = i915_do_wait_request(dev, | ||
2767 | obj_priv->last_rendering_seqno, | ||
2768 | 0, | ||
2769 | obj_priv->ring); | ||
2770 | if (ret != 0) | ||
2771 | return ret; | ||
2772 | } | ||
2773 | |||
2774 | i915_gem_object_flush_cpu_write_domain(obj); | 2740 | i915_gem_object_flush_cpu_write_domain(obj); |
2775 | 2741 | ||
2776 | old_write_domain = obj->write_domain; | ||
2777 | old_read_domains = obj->read_domains; | 2742 | old_read_domains = obj->read_domains; |
2778 | |||
2779 | /* It should now be out of any other write domains, and we can update | ||
2780 | * the domain values for our changes. | ||
2781 | */ | ||
2782 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); | ||
2783 | obj->read_domains = I915_GEM_DOMAIN_GTT; | 2743 | obj->read_domains = I915_GEM_DOMAIN_GTT; |
2784 | obj->write_domain = I915_GEM_DOMAIN_GTT; | ||
2785 | obj_priv->dirty = 1; | ||
2786 | 2744 | ||
2787 | trace_i915_gem_object_change_domain(obj, | 2745 | trace_i915_gem_object_change_domain(obj, |
2788 | old_read_domains, | 2746 | old_read_domains, |
2789 | old_write_domain); | 2747 | obj->write_domain); |
2790 | 2748 | ||
2791 | return 0; | 2749 | return 0; |
2792 | } | 2750 | } |
@@ -2803,12 +2761,7 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) | |||
2803 | uint32_t old_write_domain, old_read_domains; | 2761 | uint32_t old_write_domain, old_read_domains; |
2804 | int ret; | 2762 | int ret; |
2805 | 2763 | ||
2806 | ret = i915_gem_object_flush_gpu_write_domain(obj); | 2764 | ret = i915_gem_object_flush_gpu_write_domain(obj, false); |
2807 | if (ret) | ||
2808 | return ret; | ||
2809 | |||
2810 | /* Wait on any GPU rendering and flushing to occur. */ | ||
2811 | ret = i915_gem_object_wait_rendering(obj); | ||
2812 | if (ret != 0) | 2765 | if (ret != 0) |
2813 | return ret; | 2766 | return ret; |
2814 | 2767 | ||
@@ -2819,6 +2772,12 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) | |||
2819 | */ | 2772 | */ |
2820 | i915_gem_object_set_to_full_cpu_read_domain(obj); | 2773 | i915_gem_object_set_to_full_cpu_read_domain(obj); |
2821 | 2774 | ||
2775 | if (write) { | ||
2776 | ret = i915_gem_object_wait_rendering(obj, true); | ||
2777 | if (ret) | ||
2778 | return ret; | ||
2779 | } | ||
2780 | |||
2822 | old_write_domain = obj->write_domain; | 2781 | old_write_domain = obj->write_domain; |
2823 | old_read_domains = obj->read_domains; | 2782 | old_read_domains = obj->read_domains; |
2824 | 2783 | ||
@@ -2964,7 +2923,6 @@ static void | |||
2964 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | 2923 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) |
2965 | { | 2924 | { |
2966 | struct drm_device *dev = obj->dev; | 2925 | struct drm_device *dev = obj->dev; |
2967 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2968 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2926 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2969 | uint32_t invalidate_domains = 0; | 2927 | uint32_t invalidate_domains = 0; |
2970 | uint32_t flush_domains = 0; | 2928 | uint32_t flush_domains = 0; |
@@ -3027,13 +2985,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | |||
3027 | obj->pending_write_domain = obj->write_domain; | 2985 | obj->pending_write_domain = obj->write_domain; |
3028 | obj->read_domains = obj->pending_read_domains; | 2986 | obj->read_domains = obj->pending_read_domains; |
3029 | 2987 | ||
3030 | if (flush_domains & I915_GEM_GPU_DOMAINS) { | ||
3031 | if (obj_priv->ring == &dev_priv->render_ring) | ||
3032 | dev_priv->flush_rings |= FLUSH_RENDER_RING; | ||
3033 | else if (obj_priv->ring == &dev_priv->bsd_ring) | ||
3034 | dev_priv->flush_rings |= FLUSH_BSD_RING; | ||
3035 | } | ||
3036 | |||
3037 | dev->invalidate_domains |= invalidate_domains; | 2988 | dev->invalidate_domains |= invalidate_domains; |
3038 | dev->flush_domains |= flush_domains; | 2989 | dev->flush_domains |= flush_domains; |
3039 | #if WATCH_BUF | 2990 | #if WATCH_BUF |
@@ -3104,12 +3055,7 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, | |||
3104 | if (offset == 0 && size == obj->size) | 3055 | if (offset == 0 && size == obj->size) |
3105 | return i915_gem_object_set_to_cpu_domain(obj, 0); | 3056 | return i915_gem_object_set_to_cpu_domain(obj, 0); |
3106 | 3057 | ||
3107 | ret = i915_gem_object_flush_gpu_write_domain(obj); | 3058 | ret = i915_gem_object_flush_gpu_write_domain(obj, false); |
3108 | if (ret) | ||
3109 | return ret; | ||
3110 | |||
3111 | /* Wait on any GPU rendering and flushing to occur. */ | ||
3112 | ret = i915_gem_object_wait_rendering(obj); | ||
3113 | if (ret != 0) | 3059 | if (ret != 0) |
3114 | return ret; | 3060 | return ret; |
3115 | i915_gem_object_flush_gtt_write_domain(obj); | 3061 | i915_gem_object_flush_gtt_write_domain(obj); |
@@ -3196,7 +3142,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3196 | * properly handle blits to/from tiled surfaces. | 3142 | * properly handle blits to/from tiled surfaces. |
3197 | */ | 3143 | */ |
3198 | if (need_fence) { | 3144 | if (need_fence) { |
3199 | ret = i915_gem_object_get_fence_reg(obj); | 3145 | ret = i915_gem_object_get_fence_reg(obj, false); |
3200 | if (ret != 0) { | 3146 | if (ret != 0) { |
3201 | i915_gem_object_unpin(obj); | 3147 | i915_gem_object_unpin(obj); |
3202 | return ret; | 3148 | return ret; |
@@ -3539,8 +3485,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev, | |||
3539 | return ret; | 3485 | return ret; |
3540 | } | 3486 | } |
3541 | 3487 | ||
3542 | 3488 | static int | |
3543 | int | ||
3544 | i915_gem_do_execbuffer(struct drm_device *dev, void *data, | 3489 | i915_gem_do_execbuffer(struct drm_device *dev, void *data, |
3545 | struct drm_file *file_priv, | 3490 | struct drm_file *file_priv, |
3546 | struct drm_i915_gem_execbuffer2 *args, | 3491 | struct drm_i915_gem_execbuffer2 *args, |
@@ -3552,9 +3497,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3552 | struct drm_i915_gem_object *obj_priv; | 3497 | struct drm_i915_gem_object *obj_priv; |
3553 | struct drm_clip_rect *cliprects = NULL; | 3498 | struct drm_clip_rect *cliprects = NULL; |
3554 | struct drm_i915_gem_relocation_entry *relocs = NULL; | 3499 | struct drm_i915_gem_relocation_entry *relocs = NULL; |
3500 | struct drm_i915_gem_request *request = NULL; | ||
3555 | int ret = 0, ret2, i, pinned = 0; | 3501 | int ret = 0, ret2, i, pinned = 0; |
3556 | uint64_t exec_offset; | 3502 | uint64_t exec_offset; |
3557 | uint32_t seqno, flush_domains, reloc_index; | 3503 | uint32_t seqno, reloc_index; |
3558 | int pin_tries, flips; | 3504 | int pin_tries, flips; |
3559 | 3505 | ||
3560 | struct intel_ring_buffer *ring = NULL; | 3506 | struct intel_ring_buffer *ring = NULL; |
@@ -3605,6 +3551,12 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3605 | } | 3551 | } |
3606 | } | 3552 | } |
3607 | 3553 | ||
3554 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
3555 | if (request == NULL) { | ||
3556 | ret = -ENOMEM; | ||
3557 | goto pre_mutex_err; | ||
3558 | } | ||
3559 | |||
3608 | ret = i915_gem_get_relocs_from_user(exec_list, args->buffer_count, | 3560 | ret = i915_gem_get_relocs_from_user(exec_list, args->buffer_count, |
3609 | &relocs); | 3561 | &relocs); |
3610 | if (ret != 0) | 3562 | if (ret != 0) |
@@ -3747,7 +3699,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3747 | */ | 3699 | */ |
3748 | dev->invalidate_domains = 0; | 3700 | dev->invalidate_domains = 0; |
3749 | dev->flush_domains = 0; | 3701 | dev->flush_domains = 0; |
3750 | dev_priv->flush_rings = 0; | ||
3751 | 3702 | ||
3752 | for (i = 0; i < args->buffer_count; i++) { | 3703 | for (i = 0; i < args->buffer_count; i++) { |
3753 | struct drm_gem_object *obj = object_list[i]; | 3704 | struct drm_gem_object *obj = object_list[i]; |
@@ -3768,14 +3719,15 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3768 | i915_gem_flush(dev, | 3719 | i915_gem_flush(dev, |
3769 | dev->invalidate_domains, | 3720 | dev->invalidate_domains, |
3770 | dev->flush_domains); | 3721 | dev->flush_domains); |
3771 | if (dev_priv->flush_rings & FLUSH_RENDER_RING) | 3722 | } |
3772 | (void)i915_add_request(dev, file_priv, | 3723 | |
3773 | dev->flush_domains, | 3724 | if (dev_priv->render_ring.outstanding_lazy_request) { |
3774 | &dev_priv->render_ring); | 3725 | (void)i915_add_request(dev, file_priv, NULL, &dev_priv->render_ring); |
3775 | if (dev_priv->flush_rings & FLUSH_BSD_RING) | 3726 | dev_priv->render_ring.outstanding_lazy_request = false; |
3776 | (void)i915_add_request(dev, file_priv, | 3727 | } |
3777 | dev->flush_domains, | 3728 | if (dev_priv->bsd_ring.outstanding_lazy_request) { |
3778 | &dev_priv->bsd_ring); | 3729 | (void)i915_add_request(dev, file_priv, NULL, &dev_priv->bsd_ring); |
3730 | dev_priv->bsd_ring.outstanding_lazy_request = false; | ||
3779 | } | 3731 | } |
3780 | 3732 | ||
3781 | for (i = 0; i < args->buffer_count; i++) { | 3733 | for (i = 0; i < args->buffer_count; i++) { |
@@ -3823,28 +3775,30 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3823 | * Ensure that the commands in the batch buffer are | 3775 | * Ensure that the commands in the batch buffer are |
3824 | * finished before the interrupt fires | 3776 | * finished before the interrupt fires |
3825 | */ | 3777 | */ |
3826 | flush_domains = i915_retire_commands(dev, ring); | 3778 | i915_retire_commands(dev, ring); |
3827 | 3779 | ||
3828 | i915_verify_inactive(dev, __FILE__, __LINE__); | 3780 | i915_verify_inactive(dev, __FILE__, __LINE__); |
3829 | 3781 | ||
3830 | /* | ||
3831 | * Get a seqno representing the execution of the current buffer, | ||
3832 | * which we can wait on. We would like to mitigate these interrupts, | ||
3833 | * likely by only creating seqnos occasionally (so that we have | ||
3834 | * *some* interrupts representing completion of buffers that we can | ||
3835 | * wait on when trying to clear up gtt space). | ||
3836 | */ | ||
3837 | seqno = i915_add_request(dev, file_priv, flush_domains, ring); | ||
3838 | BUG_ON(seqno == 0); | ||
3839 | for (i = 0; i < args->buffer_count; i++) { | 3782 | for (i = 0; i < args->buffer_count; i++) { |
3840 | struct drm_gem_object *obj = object_list[i]; | 3783 | struct drm_gem_object *obj = object_list[i]; |
3841 | obj_priv = to_intel_bo(obj); | 3784 | obj_priv = to_intel_bo(obj); |
3842 | 3785 | ||
3843 | i915_gem_object_move_to_active(obj, seqno, ring); | 3786 | i915_gem_object_move_to_active(obj, ring); |
3844 | #if WATCH_LRU | 3787 | #if WATCH_LRU |
3845 | DRM_INFO("%s: move to exec list %p\n", __func__, obj); | 3788 | DRM_INFO("%s: move to exec list %p\n", __func__, obj); |
3846 | #endif | 3789 | #endif |
3847 | } | 3790 | } |
3791 | |||
3792 | /* | ||
3793 | * Get a seqno representing the execution of the current buffer, | ||
3794 | * which we can wait on. We would like to mitigate these interrupts, | ||
3795 | * likely by only creating seqnos occasionally (so that we have | ||
3796 | * *some* interrupts representing completion of buffers that we can | ||
3797 | * wait on when trying to clear up gtt space). | ||
3798 | */ | ||
3799 | seqno = i915_add_request(dev, file_priv, request, ring); | ||
3800 | request = NULL; | ||
3801 | |||
3848 | #if WATCH_LRU | 3802 | #if WATCH_LRU |
3849 | i915_dump_lru(dev, __func__); | 3803 | i915_dump_lru(dev, __func__); |
3850 | #endif | 3804 | #endif |
@@ -3882,6 +3836,7 @@ pre_mutex_err: | |||
3882 | 3836 | ||
3883 | drm_free_large(object_list); | 3837 | drm_free_large(object_list); |
3884 | kfree(cliprects); | 3838 | kfree(cliprects); |
3839 | kfree(request); | ||
3885 | 3840 | ||
3886 | return ret; | 3841 | return ret; |
3887 | } | 3842 | } |
@@ -4232,7 +4187,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
4232 | */ | 4187 | */ |
4233 | if (obj->write_domain) { | 4188 | if (obj->write_domain) { |
4234 | i915_gem_flush(dev, 0, obj->write_domain); | 4189 | i915_gem_flush(dev, 0, obj->write_domain); |
4235 | (void)i915_add_request(dev, file_priv, obj->write_domain, obj_priv->ring); | 4190 | (void)i915_add_request(dev, file_priv, NULL, obj_priv->ring); |
4236 | } | 4191 | } |
4237 | 4192 | ||
4238 | /* Update the active list for the hardware's current position. | 4193 | /* Update the active list for the hardware's current position. |
@@ -4419,7 +4374,7 @@ i915_gem_idle(struct drm_device *dev) | |||
4419 | * And not confound mm.suspended! | 4374 | * And not confound mm.suspended! |
4420 | */ | 4375 | */ |
4421 | dev_priv->mm.suspended = 1; | 4376 | dev_priv->mm.suspended = 1; |
4422 | del_timer(&dev_priv->hangcheck_timer); | 4377 | del_timer_sync(&dev_priv->hangcheck_timer); |
4423 | 4378 | ||
4424 | i915_kernel_lost_context(dev); | 4379 | i915_kernel_lost_context(dev); |
4425 | i915_gem_cleanup_ringbuffer(dev); | 4380 | i915_gem_cleanup_ringbuffer(dev); |
@@ -4573,11 +4528,8 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, | |||
4573 | return ret; | 4528 | return ret; |
4574 | } | 4529 | } |
4575 | 4530 | ||
4576 | spin_lock(&dev_priv->mm.active_list_lock); | ||
4577 | BUG_ON(!list_empty(&dev_priv->render_ring.active_list)); | 4531 | BUG_ON(!list_empty(&dev_priv->render_ring.active_list)); |
4578 | BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.active_list)); | 4532 | BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.active_list)); |
4579 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
4580 | |||
4581 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | 4533 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); |
4582 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); | 4534 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); |
4583 | BUG_ON(!list_empty(&dev_priv->render_ring.request_list)); | 4535 | BUG_ON(!list_empty(&dev_priv->render_ring.request_list)); |
@@ -4629,7 +4581,6 @@ i915_gem_load(struct drm_device *dev) | |||
4629 | int i; | 4581 | int i; |
4630 | drm_i915_private_t *dev_priv = dev->dev_private; | 4582 | drm_i915_private_t *dev_priv = dev->dev_private; |
4631 | 4583 | ||
4632 | spin_lock_init(&dev_priv->mm.active_list_lock); | ||
4633 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); | 4584 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); |
4634 | INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); | 4585 | INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); |
4635 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); | 4586 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); |
@@ -4687,8 +4638,8 @@ i915_gem_load(struct drm_device *dev) | |||
4687 | * Create a physically contiguous memory object for this object | 4638 | * Create a physically contiguous memory object for this object |
4688 | * e.g. for cursor + overlay regs | 4639 | * e.g. for cursor + overlay regs |
4689 | */ | 4640 | */ |
4690 | int i915_gem_init_phys_object(struct drm_device *dev, | 4641 | static int i915_gem_init_phys_object(struct drm_device *dev, |
4691 | int id, int size, int align) | 4642 | int id, int size, int align) |
4692 | { | 4643 | { |
4693 | drm_i915_private_t *dev_priv = dev->dev_private; | 4644 | drm_i915_private_t *dev_priv = dev->dev_private; |
4694 | struct drm_i915_gem_phys_object *phys_obj; | 4645 | struct drm_i915_gem_phys_object *phys_obj; |
@@ -4720,7 +4671,7 @@ kfree_obj: | |||
4720 | return ret; | 4671 | return ret; |
4721 | } | 4672 | } |
4722 | 4673 | ||
4723 | void i915_gem_free_phys_object(struct drm_device *dev, int id) | 4674 | static void i915_gem_free_phys_object(struct drm_device *dev, int id) |
4724 | { | 4675 | { |
4725 | drm_i915_private_t *dev_priv = dev->dev_private; | 4676 | drm_i915_private_t *dev_priv = dev->dev_private; |
4726 | struct drm_i915_gem_phys_object *phys_obj; | 4677 | struct drm_i915_gem_phys_object *phys_obj; |
@@ -4885,12 +4836,10 @@ i915_gpu_is_active(struct drm_device *dev) | |||
4885 | drm_i915_private_t *dev_priv = dev->dev_private; | 4836 | drm_i915_private_t *dev_priv = dev->dev_private; |
4886 | int lists_empty; | 4837 | int lists_empty; |
4887 | 4838 | ||
4888 | spin_lock(&dev_priv->mm.active_list_lock); | ||
4889 | lists_empty = list_empty(&dev_priv->mm.flushing_list) && | 4839 | lists_empty = list_empty(&dev_priv->mm.flushing_list) && |
4890 | list_empty(&dev_priv->render_ring.active_list); | 4840 | list_empty(&dev_priv->render_ring.active_list); |
4891 | if (HAS_BSD(dev)) | 4841 | if (HAS_BSD(dev)) |
4892 | lists_empty &= list_empty(&dev_priv->bsd_ring.active_list); | 4842 | lists_empty &= list_empty(&dev_priv->bsd_ring.active_list); |
4893 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
4894 | 4843 | ||
4895 | return !lists_empty; | 4844 | return !lists_empty; |
4896 | } | 4845 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index e85246ef691c..63ac3d2ba52c 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -217,14 +217,11 @@ i915_gem_evict_everything(struct drm_device *dev) | |||
217 | int ret; | 217 | int ret; |
218 | bool lists_empty; | 218 | bool lists_empty; |
219 | 219 | ||
220 | spin_lock(&dev_priv->mm.active_list_lock); | ||
221 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | 220 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && |
222 | list_empty(&dev_priv->mm.flushing_list) && | 221 | list_empty(&dev_priv->mm.flushing_list) && |
223 | list_empty(&dev_priv->render_ring.active_list) && | 222 | list_empty(&dev_priv->render_ring.active_list) && |
224 | (!HAS_BSD(dev) | 223 | (!HAS_BSD(dev) |
225 | || list_empty(&dev_priv->bsd_ring.active_list))); | 224 | || list_empty(&dev_priv->bsd_ring.active_list))); |
226 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
227 | |||
228 | if (lists_empty) | 225 | if (lists_empty) |
229 | return -ENOSPC; | 226 | return -ENOSPC; |
230 | 227 | ||
@@ -239,13 +236,11 @@ i915_gem_evict_everything(struct drm_device *dev) | |||
239 | if (ret) | 236 | if (ret) |
240 | return ret; | 237 | return ret; |
241 | 238 | ||
242 | spin_lock(&dev_priv->mm.active_list_lock); | ||
243 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | 239 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && |
244 | list_empty(&dev_priv->mm.flushing_list) && | 240 | list_empty(&dev_priv->mm.flushing_list) && |
245 | list_empty(&dev_priv->render_ring.active_list) && | 241 | list_empty(&dev_priv->render_ring.active_list) && |
246 | (!HAS_BSD(dev) | 242 | (!HAS_BSD(dev) |
247 | || list_empty(&dev_priv->bsd_ring.active_list))); | 243 | || list_empty(&dev_priv->bsd_ring.active_list))); |
248 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
249 | BUG_ON(!lists_empty); | 244 | BUG_ON(!lists_empty); |
250 | 245 | ||
251 | return 0; | 246 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 710eca70b323..caef7ff2aa39 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -328,7 +328,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
328 | if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode)) | 328 | if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode)) |
329 | ret = i915_gem_object_unbind(obj); | 329 | ret = i915_gem_object_unbind(obj); |
330 | else if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 330 | else if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
331 | ret = i915_gem_object_put_fence_reg(obj); | 331 | ret = i915_gem_object_put_fence_reg(obj, true); |
332 | else | 332 | else |
333 | i915_gem_release_mmap(obj); | 333 | i915_gem_release_mmap(obj); |
334 | 334 | ||
@@ -399,16 +399,14 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, | |||
399 | * bit 17 of its physical address and therefore being interpreted differently | 399 | * bit 17 of its physical address and therefore being interpreted differently |
400 | * by the GPU. | 400 | * by the GPU. |
401 | */ | 401 | */ |
402 | static int | 402 | static void |
403 | i915_gem_swizzle_page(struct page *page) | 403 | i915_gem_swizzle_page(struct page *page) |
404 | { | 404 | { |
405 | char temp[64]; | ||
405 | char *vaddr; | 406 | char *vaddr; |
406 | int i; | 407 | int i; |
407 | char temp[64]; | ||
408 | 408 | ||
409 | vaddr = kmap(page); | 409 | vaddr = kmap(page); |
410 | if (vaddr == NULL) | ||
411 | return -ENOMEM; | ||
412 | 410 | ||
413 | for (i = 0; i < PAGE_SIZE; i += 128) { | 411 | for (i = 0; i < PAGE_SIZE; i += 128) { |
414 | memcpy(temp, &vaddr[i], 64); | 412 | memcpy(temp, &vaddr[i], 64); |
@@ -417,8 +415,6 @@ i915_gem_swizzle_page(struct page *page) | |||
417 | } | 415 | } |
418 | 416 | ||
419 | kunmap(page); | 417 | kunmap(page); |
420 | |||
421 | return 0; | ||
422 | } | 418 | } |
423 | 419 | ||
424 | void | 420 | void |
@@ -440,11 +436,7 @@ i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj) | |||
440 | char new_bit_17 = page_to_phys(obj_priv->pages[i]) >> 17; | 436 | char new_bit_17 = page_to_phys(obj_priv->pages[i]) >> 17; |
441 | if ((new_bit_17 & 0x1) != | 437 | if ((new_bit_17 & 0x1) != |
442 | (test_bit(i, obj_priv->bit_17) != 0)) { | 438 | (test_bit(i, obj_priv->bit_17) != 0)) { |
443 | int ret = i915_gem_swizzle_page(obj_priv->pages[i]); | 439 | i915_gem_swizzle_page(obj_priv->pages[i]); |
444 | if (ret != 0) { | ||
445 | DRM_ERROR("Failed to swizzle page\n"); | ||
446 | return; | ||
447 | } | ||
448 | set_page_dirty(obj_priv->pages[i]); | 440 | set_page_dirty(obj_priv->pages[i]); |
449 | } | 441 | } |
450 | } | 442 | } |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 744225ebb4b2..e64b8eaa0b9d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -85,7 +85,7 @@ ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) | |||
85 | } | 85 | } |
86 | 86 | ||
87 | /* For display hotplug interrupt */ | 87 | /* For display hotplug interrupt */ |
88 | void | 88 | static void |
89 | ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) | 89 | ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) |
90 | { | 90 | { |
91 | if ((dev_priv->irq_mask_reg & mask) != 0) { | 91 | if ((dev_priv->irq_mask_reg & mask) != 0) { |
@@ -191,12 +191,7 @@ static int | |||
191 | i915_pipe_enabled(struct drm_device *dev, int pipe) | 191 | i915_pipe_enabled(struct drm_device *dev, int pipe) |
192 | { | 192 | { |
193 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 193 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
194 | unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF; | 194 | return I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE; |
195 | |||
196 | if (I915_READ(pipeconf) & PIPEACONF_ENABLE) | ||
197 | return 1; | ||
198 | |||
199 | return 0; | ||
200 | } | 195 | } |
201 | 196 | ||
202 | /* Called from drm generic code, passed a 'crtc', which | 197 | /* Called from drm generic code, passed a 'crtc', which |
@@ -207,10 +202,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | |||
207 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 202 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
208 | unsigned long high_frame; | 203 | unsigned long high_frame; |
209 | unsigned long low_frame; | 204 | unsigned long low_frame; |
210 | u32 high1, high2, low, count; | 205 | u32 high1, high2, low; |
211 | |||
212 | high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH; | ||
213 | low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; | ||
214 | 206 | ||
215 | if (!i915_pipe_enabled(dev, pipe)) { | 207 | if (!i915_pipe_enabled(dev, pipe)) { |
216 | DRM_DEBUG_DRIVER("trying to get vblank count for disabled " | 208 | DRM_DEBUG_DRIVER("trying to get vblank count for disabled " |
@@ -218,23 +210,23 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | |||
218 | return 0; | 210 | return 0; |
219 | } | 211 | } |
220 | 212 | ||
213 | high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH; | ||
214 | low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; | ||
215 | |||
221 | /* | 216 | /* |
222 | * High & low register fields aren't synchronized, so make sure | 217 | * High & low register fields aren't synchronized, so make sure |
223 | * we get a low value that's stable across two reads of the high | 218 | * we get a low value that's stable across two reads of the high |
224 | * register. | 219 | * register. |
225 | */ | 220 | */ |
226 | do { | 221 | do { |
227 | high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> | 222 | high1 = I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK; |
228 | PIPE_FRAME_HIGH_SHIFT); | 223 | low = I915_READ(low_frame) & PIPE_FRAME_LOW_MASK; |
229 | low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >> | 224 | high2 = I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK; |
230 | PIPE_FRAME_LOW_SHIFT); | ||
231 | high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> | ||
232 | PIPE_FRAME_HIGH_SHIFT); | ||
233 | } while (high1 != high2); | 225 | } while (high1 != high2); |
234 | 226 | ||
235 | count = (high1 << 8) | low; | 227 | high1 >>= PIPE_FRAME_HIGH_SHIFT; |
236 | 228 | low >>= PIPE_FRAME_LOW_SHIFT; | |
237 | return count; | 229 | return (high1 << 8) | low; |
238 | } | 230 | } |
239 | 231 | ||
240 | u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) | 232 | u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) |
@@ -260,16 +252,12 @@ static void i915_hotplug_work_func(struct work_struct *work) | |||
260 | hotplug_work); | 252 | hotplug_work); |
261 | struct drm_device *dev = dev_priv->dev; | 253 | struct drm_device *dev = dev_priv->dev; |
262 | struct drm_mode_config *mode_config = &dev->mode_config; | 254 | struct drm_mode_config *mode_config = &dev->mode_config; |
263 | struct drm_encoder *encoder; | 255 | struct intel_encoder *encoder; |
264 | 256 | ||
265 | if (mode_config->num_encoder) { | 257 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) |
266 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 258 | if (encoder->hot_plug) |
267 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 259 | encoder->hot_plug(encoder); |
268 | 260 | ||
269 | if (intel_encoder->hot_plug) | ||
270 | (*intel_encoder->hot_plug) (intel_encoder); | ||
271 | } | ||
272 | } | ||
273 | /* Just fire off a uevent and let userspace tell us what to do */ | 261 | /* Just fire off a uevent and let userspace tell us what to do */ |
274 | drm_helper_hpd_irq_event(dev); | 262 | drm_helper_hpd_irq_event(dev); |
275 | } | 263 | } |
@@ -305,7 +293,7 @@ static void i915_handle_rps_change(struct drm_device *dev) | |||
305 | return; | 293 | return; |
306 | } | 294 | } |
307 | 295 | ||
308 | irqreturn_t ironlake_irq_handler(struct drm_device *dev) | 296 | static irqreturn_t ironlake_irq_handler(struct drm_device *dev) |
309 | { | 297 | { |
310 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 298 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
311 | int ret = IRQ_NONE; | 299 | int ret = IRQ_NONE; |
@@ -340,23 +328,24 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
340 | trace_i915_gem_request_complete(dev, seqno); | 328 | trace_i915_gem_request_complete(dev, seqno); |
341 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); | 329 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); |
342 | dev_priv->hangcheck_count = 0; | 330 | dev_priv->hangcheck_count = 0; |
343 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); | 331 | mod_timer(&dev_priv->hangcheck_timer, |
332 | jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); | ||
344 | } | 333 | } |
345 | if (gt_iir & GT_BSD_USER_INTERRUPT) | 334 | if (gt_iir & GT_BSD_USER_INTERRUPT) |
346 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | 335 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); |
347 | 336 | ||
348 | 337 | ||
349 | if (de_iir & DE_GSE) | 338 | if (de_iir & DE_GSE) |
350 | ironlake_opregion_gse_intr(dev); | 339 | intel_opregion_gse_intr(dev); |
351 | 340 | ||
352 | if (de_iir & DE_PLANEA_FLIP_DONE) { | 341 | if (de_iir & DE_PLANEA_FLIP_DONE) { |
353 | intel_prepare_page_flip(dev, 0); | 342 | intel_prepare_page_flip(dev, 0); |
354 | intel_finish_page_flip(dev, 0); | 343 | intel_finish_page_flip_plane(dev, 0); |
355 | } | 344 | } |
356 | 345 | ||
357 | if (de_iir & DE_PLANEB_FLIP_DONE) { | 346 | if (de_iir & DE_PLANEB_FLIP_DONE) { |
358 | intel_prepare_page_flip(dev, 1); | 347 | intel_prepare_page_flip(dev, 1); |
359 | intel_finish_page_flip(dev, 1); | 348 | intel_finish_page_flip_plane(dev, 1); |
360 | } | 349 | } |
361 | 350 | ||
362 | if (de_iir & DE_PIPEA_VBLANK) | 351 | if (de_iir & DE_PIPEA_VBLANK) |
@@ -421,6 +410,7 @@ static void i915_error_work_func(struct work_struct *work) | |||
421 | } | 410 | } |
422 | } | 411 | } |
423 | 412 | ||
413 | #ifdef CONFIG_DEBUG_FS | ||
424 | static struct drm_i915_error_object * | 414 | static struct drm_i915_error_object * |
425 | i915_error_object_create(struct drm_device *dev, | 415 | i915_error_object_create(struct drm_device *dev, |
426 | struct drm_gem_object *src) | 416 | struct drm_gem_object *src) |
@@ -744,6 +734,9 @@ void i915_destroy_error_state(struct drm_device *dev) | |||
744 | if (error) | 734 | if (error) |
745 | i915_error_state_free(dev, error); | 735 | i915_error_state_free(dev, error); |
746 | } | 736 | } |
737 | #else | ||
738 | #define i915_capture_error_state(x) | ||
739 | #endif | ||
747 | 740 | ||
748 | static void i915_report_and_clear_eir(struct drm_device *dev) | 741 | static void i915_report_and_clear_eir(struct drm_device *dev) |
749 | { | 742 | { |
@@ -1026,7 +1019,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
1026 | trace_i915_gem_request_complete(dev, seqno); | 1019 | trace_i915_gem_request_complete(dev, seqno); |
1027 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); | 1020 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); |
1028 | dev_priv->hangcheck_count = 0; | 1021 | dev_priv->hangcheck_count = 0; |
1029 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); | 1022 | mod_timer(&dev_priv->hangcheck_timer, |
1023 | jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); | ||
1030 | } | 1024 | } |
1031 | 1025 | ||
1032 | if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) | 1026 | if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) |
@@ -1065,7 +1059,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
1065 | if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || | 1059 | if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || |
1066 | (pipeb_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || | 1060 | (pipeb_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || |
1067 | (iir & I915_ASLE_INTERRUPT)) | 1061 | (iir & I915_ASLE_INTERRUPT)) |
1068 | opregion_asle_intr(dev); | 1062 | intel_opregion_asle_intr(dev); |
1069 | 1063 | ||
1070 | /* With MSI, interrupts are only generated when iir | 1064 | /* With MSI, interrupts are only generated when iir |
1071 | * transitions from zero to nonzero. If another bit got | 1065 | * transitions from zero to nonzero. If another bit got |
@@ -1207,11 +1201,8 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) | |||
1207 | { | 1201 | { |
1208 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1202 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1209 | unsigned long irqflags; | 1203 | unsigned long irqflags; |
1210 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; | ||
1211 | u32 pipeconf; | ||
1212 | 1204 | ||
1213 | pipeconf = I915_READ(pipeconf_reg); | 1205 | if (!i915_pipe_enabled(dev, pipe)) |
1214 | if (!(pipeconf & PIPEACONF_ENABLE)) | ||
1215 | return -EINVAL; | 1206 | return -EINVAL; |
1216 | 1207 | ||
1217 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1208 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); |
@@ -1252,7 +1243,7 @@ void i915_enable_interrupt (struct drm_device *dev) | |||
1252 | struct drm_i915_private *dev_priv = dev->dev_private; | 1243 | struct drm_i915_private *dev_priv = dev->dev_private; |
1253 | 1244 | ||
1254 | if (!HAS_PCH_SPLIT(dev)) | 1245 | if (!HAS_PCH_SPLIT(dev)) |
1255 | opregion_enable_asle(dev); | 1246 | intel_opregion_enable_asle(dev); |
1256 | dev_priv->irq_enabled = 1; | 1247 | dev_priv->irq_enabled = 1; |
1257 | } | 1248 | } |
1258 | 1249 | ||
@@ -1311,7 +1302,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
1311 | return -EINVAL; | 1302 | return -EINVAL; |
1312 | } | 1303 | } |
1313 | 1304 | ||
1314 | struct drm_i915_gem_request * | 1305 | static struct drm_i915_gem_request * |
1315 | i915_get_tail_request(struct drm_device *dev) | 1306 | i915_get_tail_request(struct drm_device *dev) |
1316 | { | 1307 | { |
1317 | drm_i915_private_t *dev_priv = dev->dev_private; | 1308 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -1377,6 +1368,21 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1377 | dev_priv->last_instdone1 == instdone1) { | 1368 | dev_priv->last_instdone1 == instdone1) { |
1378 | if (dev_priv->hangcheck_count++ > 1) { | 1369 | if (dev_priv->hangcheck_count++ > 1) { |
1379 | DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); | 1370 | DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); |
1371 | |||
1372 | if (!IS_GEN2(dev)) { | ||
1373 | /* Is the chip hanging on a WAIT_FOR_EVENT? | ||
1374 | * If so we can simply poke the RB_WAIT bit | ||
1375 | * and break the hang. This should work on | ||
1376 | * all but the second generation chipsets. | ||
1377 | */ | ||
1378 | u32 tmp = I915_READ(PRB0_CTL); | ||
1379 | if (tmp & RING_WAIT) { | ||
1380 | I915_WRITE(PRB0_CTL, tmp); | ||
1381 | POSTING_READ(PRB0_CTL); | ||
1382 | goto out; | ||
1383 | } | ||
1384 | } | ||
1385 | |||
1380 | i915_handle_error(dev, true); | 1386 | i915_handle_error(dev, true); |
1381 | return; | 1387 | return; |
1382 | } | 1388 | } |
@@ -1388,8 +1394,10 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1388 | dev_priv->last_instdone1 = instdone1; | 1394 | dev_priv->last_instdone1 = instdone1; |
1389 | } | 1395 | } |
1390 | 1396 | ||
1397 | out: | ||
1391 | /* Reset timer case chip hangs without another request being added */ | 1398 | /* Reset timer case chip hangs without another request being added */ |
1392 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); | 1399 | mod_timer(&dev_priv->hangcheck_timer, |
1400 | jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); | ||
1393 | } | 1401 | } |
1394 | 1402 | ||
1395 | /* drm_dma.h hooks | 1403 | /* drm_dma.h hooks |
@@ -1578,7 +1586,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
1578 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | 1586 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
1579 | } | 1587 | } |
1580 | 1588 | ||
1581 | opregion_enable_asle(dev); | 1589 | intel_opregion_enable_asle(dev); |
1582 | 1590 | ||
1583 | return 0; | 1591 | return 0; |
1584 | } | 1592 | } |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 4f5e15577e89..18e3749fbd11 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -25,6 +25,8 @@ | |||
25 | #ifndef _I915_REG_H_ | 25 | #ifndef _I915_REG_H_ |
26 | #define _I915_REG_H_ | 26 | #define _I915_REG_H_ |
27 | 27 | ||
28 | #define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a))) | ||
29 | |||
28 | /* | 30 | /* |
29 | * The Bridge device's PCI config space has information about the | 31 | * The Bridge device's PCI config space has information about the |
30 | * fb aperture size and the amount of pre-reserved memory. | 32 | * fb aperture size and the amount of pre-reserved memory. |
@@ -295,6 +297,8 @@ | |||
295 | #define RING_VALID_MASK 0x00000001 | 297 | #define RING_VALID_MASK 0x00000001 |
296 | #define RING_VALID 0x00000001 | 298 | #define RING_VALID 0x00000001 |
297 | #define RING_INVALID 0x00000000 | 299 | #define RING_INVALID 0x00000000 |
300 | #define RING_WAIT_I8XX (1<<0) /* gen2, PRBx_HEAD */ | ||
301 | #define RING_WAIT (1<<11) /* gen3+, PRBx_CTL */ | ||
298 | #define PRB1_TAIL 0x02040 /* 915+ only */ | 302 | #define PRB1_TAIL 0x02040 /* 915+ only */ |
299 | #define PRB1_HEAD 0x02044 /* 915+ only */ | 303 | #define PRB1_HEAD 0x02044 /* 915+ only */ |
300 | #define PRB1_START 0x02048 /* 915+ only */ | 304 | #define PRB1_START 0x02048 /* 915+ only */ |
@@ -579,12 +583,51 @@ | |||
579 | # define GPIO_DATA_VAL_IN (1 << 12) | 583 | # define GPIO_DATA_VAL_IN (1 << 12) |
580 | # define GPIO_DATA_PULLUP_DISABLE (1 << 13) | 584 | # define GPIO_DATA_PULLUP_DISABLE (1 << 13) |
581 | 585 | ||
582 | #define GMBUS0 0x5100 | 586 | #define GMBUS0 0x5100 /* clock/port select */ |
583 | #define GMBUS1 0x5104 | 587 | #define GMBUS_RATE_100KHZ (0<<8) |
584 | #define GMBUS2 0x5108 | 588 | #define GMBUS_RATE_50KHZ (1<<8) |
585 | #define GMBUS3 0x510c | 589 | #define GMBUS_RATE_400KHZ (2<<8) /* reserved on Pineview */ |
586 | #define GMBUS4 0x5110 | 590 | #define GMBUS_RATE_1MHZ (3<<8) /* reserved on Pineview */ |
587 | #define GMBUS5 0x5120 | 591 | #define GMBUS_HOLD_EXT (1<<7) /* 300ns hold time, rsvd on Pineview */ |
592 | #define GMBUS_PORT_DISABLED 0 | ||
593 | #define GMBUS_PORT_SSC 1 | ||
594 | #define GMBUS_PORT_VGADDC 2 | ||
595 | #define GMBUS_PORT_PANEL 3 | ||
596 | #define GMBUS_PORT_DPC 4 /* HDMIC */ | ||
597 | #define GMBUS_PORT_DPB 5 /* SDVO, HDMIB */ | ||
598 | /* 6 reserved */ | ||
599 | #define GMBUS_PORT_DPD 7 /* HDMID */ | ||
600 | #define GMBUS_NUM_PORTS 8 | ||
601 | #define GMBUS1 0x5104 /* command/status */ | ||
602 | #define GMBUS_SW_CLR_INT (1<<31) | ||
603 | #define GMBUS_SW_RDY (1<<30) | ||
604 | #define GMBUS_ENT (1<<29) /* enable timeout */ | ||
605 | #define GMBUS_CYCLE_NONE (0<<25) | ||
606 | #define GMBUS_CYCLE_WAIT (1<<25) | ||
607 | #define GMBUS_CYCLE_INDEX (2<<25) | ||
608 | #define GMBUS_CYCLE_STOP (4<<25) | ||
609 | #define GMBUS_BYTE_COUNT_SHIFT 16 | ||
610 | #define GMBUS_SLAVE_INDEX_SHIFT 8 | ||
611 | #define GMBUS_SLAVE_ADDR_SHIFT 1 | ||
612 | #define GMBUS_SLAVE_READ (1<<0) | ||
613 | #define GMBUS_SLAVE_WRITE (0<<0) | ||
614 | #define GMBUS2 0x5108 /* status */ | ||
615 | #define GMBUS_INUSE (1<<15) | ||
616 | #define GMBUS_HW_WAIT_PHASE (1<<14) | ||
617 | #define GMBUS_STALL_TIMEOUT (1<<13) | ||
618 | #define GMBUS_INT (1<<12) | ||
619 | #define GMBUS_HW_RDY (1<<11) | ||
620 | #define GMBUS_SATOER (1<<10) | ||
621 | #define GMBUS_ACTIVE (1<<9) | ||
622 | #define GMBUS3 0x510c /* data buffer bytes 3-0 */ | ||
623 | #define GMBUS4 0x5110 /* interrupt mask (Pineview+) */ | ||
624 | #define GMBUS_SLAVE_TIMEOUT_EN (1<<4) | ||
625 | #define GMBUS_NAK_EN (1<<3) | ||
626 | #define GMBUS_IDLE_EN (1<<2) | ||
627 | #define GMBUS_HW_WAIT_EN (1<<1) | ||
628 | #define GMBUS_HW_RDY_EN (1<<0) | ||
629 | #define GMBUS5 0x5120 /* byte index */ | ||
630 | #define GMBUS_2BYTE_INDEX_EN (1<<31) | ||
588 | 631 | ||
589 | /* | 632 | /* |
590 | * Clock control & power management | 633 | * Clock control & power management |
@@ -603,6 +646,7 @@ | |||
603 | #define VGA1_PD_P1_MASK (0x1f << 8) | 646 | #define VGA1_PD_P1_MASK (0x1f << 8) |
604 | #define DPLL_A 0x06014 | 647 | #define DPLL_A 0x06014 |
605 | #define DPLL_B 0x06018 | 648 | #define DPLL_B 0x06018 |
649 | #define DPLL(pipe) _PIPE(pipe, DPLL_A, DPLL_B) | ||
606 | #define DPLL_VCO_ENABLE (1 << 31) | 650 | #define DPLL_VCO_ENABLE (1 << 31) |
607 | #define DPLL_DVO_HIGH_SPEED (1 << 30) | 651 | #define DPLL_DVO_HIGH_SPEED (1 << 30) |
608 | #define DPLL_SYNCLOCK_ENABLE (1 << 29) | 652 | #define DPLL_SYNCLOCK_ENABLE (1 << 29) |
@@ -736,10 +780,13 @@ | |||
736 | #define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f | 780 | #define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f |
737 | #define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 | 781 | #define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 |
738 | #define DPLL_B_MD 0x06020 /* 965+ only */ | 782 | #define DPLL_B_MD 0x06020 /* 965+ only */ |
783 | #define DPLL_MD(pipe) _PIPE(pipe, DPLL_A_MD, DPLL_B_MD) | ||
739 | #define FPA0 0x06040 | 784 | #define FPA0 0x06040 |
740 | #define FPA1 0x06044 | 785 | #define FPA1 0x06044 |
741 | #define FPB0 0x06048 | 786 | #define FPB0 0x06048 |
742 | #define FPB1 0x0604c | 787 | #define FPB1 0x0604c |
788 | #define FP0(pipe) _PIPE(pipe, FPA0, FPB0) | ||
789 | #define FP1(pipe) _PIPE(pipe, FPA1, FPB1) | ||
743 | #define FP_N_DIV_MASK 0x003f0000 | 790 | #define FP_N_DIV_MASK 0x003f0000 |
744 | #define FP_N_PINEVIEW_DIV_MASK 0x00ff0000 | 791 | #define FP_N_PINEVIEW_DIV_MASK 0x00ff0000 |
745 | #define FP_N_DIV_SHIFT 16 | 792 | #define FP_N_DIV_SHIFT 16 |
@@ -926,6 +973,8 @@ | |||
926 | #define CLKCFG_MEM_800 (3 << 4) | 973 | #define CLKCFG_MEM_800 (3 << 4) |
927 | #define CLKCFG_MEM_MASK (7 << 4) | 974 | #define CLKCFG_MEM_MASK (7 << 4) |
928 | 975 | ||
976 | #define TSC1 0x11001 | ||
977 | #define TSE (1<<0) | ||
929 | #define TR1 0x11006 | 978 | #define TR1 0x11006 |
930 | #define TSFS 0x11020 | 979 | #define TSFS 0x11020 |
931 | #define TSFS_SLOPE_MASK 0x0000ff00 | 980 | #define TSFS_SLOPE_MASK 0x0000ff00 |
@@ -1070,6 +1119,8 @@ | |||
1070 | #define MEMSTAT_SRC_CTL_STDBY 3 | 1119 | #define MEMSTAT_SRC_CTL_STDBY 3 |
1071 | #define RCPREVBSYTUPAVG 0x113b8 | 1120 | #define RCPREVBSYTUPAVG 0x113b8 |
1072 | #define RCPREVBSYTDNAVG 0x113bc | 1121 | #define RCPREVBSYTDNAVG 0x113bc |
1122 | #define PMMISC 0x11214 | ||
1123 | #define MCPPCE_EN (1<<0) /* enable PM_MSG from PCH->MPC */ | ||
1073 | #define SDEW 0x1124c | 1124 | #define SDEW 0x1124c |
1074 | #define CSIEW0 0x11250 | 1125 | #define CSIEW0 0x11250 |
1075 | #define CSIEW1 0x11254 | 1126 | #define CSIEW1 0x11254 |
@@ -1150,6 +1201,15 @@ | |||
1150 | #define PIPEBSRC 0x6101c | 1201 | #define PIPEBSRC 0x6101c |
1151 | #define BCLRPAT_B 0x61020 | 1202 | #define BCLRPAT_B 0x61020 |
1152 | 1203 | ||
1204 | #define HTOTAL(pipe) _PIPE(pipe, HTOTAL_A, HTOTAL_B) | ||
1205 | #define HBLANK(pipe) _PIPE(pipe, HBLANK_A, HBLANK_B) | ||
1206 | #define HSYNC(pipe) _PIPE(pipe, HSYNC_A, HSYNC_B) | ||
1207 | #define VTOTAL(pipe) _PIPE(pipe, VTOTAL_A, VTOTAL_B) | ||
1208 | #define VBLANK(pipe) _PIPE(pipe, VBLANK_A, VBLANK_B) | ||
1209 | #define VSYNC(pipe) _PIPE(pipe, VSYNC_A, VSYNC_B) | ||
1210 | #define PIPESRC(pipe) _PIPE(pipe, PIPEASRC, PIPEBSRC) | ||
1211 | #define BCLRPAT(pipe) _PIPE(pipe, BCLRPAT_A, BCLRPAT_B) | ||
1212 | |||
1153 | /* VGA port control */ | 1213 | /* VGA port control */ |
1154 | #define ADPA 0x61100 | 1214 | #define ADPA 0x61100 |
1155 | #define ADPA_DAC_ENABLE (1<<31) | 1215 | #define ADPA_DAC_ENABLE (1<<31) |
@@ -1481,6 +1541,7 @@ | |||
1481 | # define TV_TEST_MODE_MASK (7 << 0) | 1541 | # define TV_TEST_MODE_MASK (7 << 0) |
1482 | 1542 | ||
1483 | #define TV_DAC 0x68004 | 1543 | #define TV_DAC 0x68004 |
1544 | # define TV_DAC_SAVE 0x00ffff00 | ||
1484 | /** | 1545 | /** |
1485 | * Reports that DAC state change logic has reported change (RO). | 1546 | * Reports that DAC state change logic has reported change (RO). |
1486 | * | 1547 | * |
@@ -2075,29 +2136,35 @@ | |||
2075 | 2136 | ||
2076 | /* Display & cursor control */ | 2137 | /* Display & cursor control */ |
2077 | 2138 | ||
2078 | /* dithering flag on Ironlake */ | ||
2079 | #define PIPE_ENABLE_DITHER (1 << 4) | ||
2080 | #define PIPE_DITHER_TYPE_MASK (3 << 2) | ||
2081 | #define PIPE_DITHER_TYPE_SPATIAL (0 << 2) | ||
2082 | #define PIPE_DITHER_TYPE_ST01 (1 << 2) | ||
2083 | /* Pipe A */ | 2139 | /* Pipe A */ |
2084 | #define PIPEADSL 0x70000 | 2140 | #define PIPEADSL 0x70000 |
2085 | #define DSL_LINEMASK 0x00000fff | 2141 | #define DSL_LINEMASK 0x00000fff |
2086 | #define PIPEACONF 0x70008 | 2142 | #define PIPEACONF 0x70008 |
2087 | #define PIPEACONF_ENABLE (1<<31) | 2143 | #define PIPECONF_ENABLE (1<<31) |
2088 | #define PIPEACONF_DISABLE 0 | 2144 | #define PIPECONF_DISABLE 0 |
2089 | #define PIPEACONF_DOUBLE_WIDE (1<<30) | 2145 | #define PIPECONF_DOUBLE_WIDE (1<<30) |
2090 | #define I965_PIPECONF_ACTIVE (1<<30) | 2146 | #define I965_PIPECONF_ACTIVE (1<<30) |
2091 | #define PIPEACONF_SINGLE_WIDE 0 | 2147 | #define PIPECONF_SINGLE_WIDE 0 |
2092 | #define PIPEACONF_PIPE_UNLOCKED 0 | 2148 | #define PIPECONF_PIPE_UNLOCKED 0 |
2093 | #define PIPEACONF_PIPE_LOCKED (1<<25) | 2149 | #define PIPECONF_PIPE_LOCKED (1<<25) |
2094 | #define PIPEACONF_PALETTE 0 | 2150 | #define PIPECONF_PALETTE 0 |
2095 | #define PIPEACONF_GAMMA (1<<24) | 2151 | #define PIPECONF_GAMMA (1<<24) |
2096 | #define PIPECONF_FORCE_BORDER (1<<25) | 2152 | #define PIPECONF_FORCE_BORDER (1<<25) |
2097 | #define PIPECONF_PROGRESSIVE (0 << 21) | 2153 | #define PIPECONF_PROGRESSIVE (0 << 21) |
2098 | #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) | 2154 | #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) |
2099 | #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) | 2155 | #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) |
2100 | #define PIPECONF_CXSR_DOWNCLOCK (1<<16) | 2156 | #define PIPECONF_CXSR_DOWNCLOCK (1<<16) |
2157 | #define PIPECONF_BPP_MASK (0x000000e0) | ||
2158 | #define PIPECONF_BPP_8 (0<<5) | ||
2159 | #define PIPECONF_BPP_10 (1<<5) | ||
2160 | #define PIPECONF_BPP_6 (2<<5) | ||
2161 | #define PIPECONF_BPP_12 (3<<5) | ||
2162 | #define PIPECONF_DITHER_EN (1<<4) | ||
2163 | #define PIPECONF_DITHER_TYPE_MASK (0x0000000c) | ||
2164 | #define PIPECONF_DITHER_TYPE_SP (0<<2) | ||
2165 | #define PIPECONF_DITHER_TYPE_ST1 (1<<2) | ||
2166 | #define PIPECONF_DITHER_TYPE_ST2 (2<<2) | ||
2167 | #define PIPECONF_DITHER_TYPE_TEMP (3<<2) | ||
2101 | #define PIPEASTAT 0x70024 | 2168 | #define PIPEASTAT 0x70024 |
2102 | #define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) | 2169 | #define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) |
2103 | #define PIPE_CRC_ERROR_ENABLE (1UL<<29) | 2170 | #define PIPE_CRC_ERROR_ENABLE (1UL<<29) |
@@ -2134,6 +2201,8 @@ | |||
2134 | #define PIPE_6BPC (2 << 5) | 2201 | #define PIPE_6BPC (2 << 5) |
2135 | #define PIPE_12BPC (3 << 5) | 2202 | #define PIPE_12BPC (3 << 5) |
2136 | 2203 | ||
2204 | #define PIPECONF(pipe) _PIPE(pipe, PIPEACONF, PIPEBCONF) | ||
2205 | |||
2137 | #define DSPARB 0x70030 | 2206 | #define DSPARB 0x70030 |
2138 | #define DSPARB_CSTART_MASK (0x7f << 7) | 2207 | #define DSPARB_CSTART_MASK (0x7f << 7) |
2139 | #define DSPARB_CSTART_SHIFT 7 | 2208 | #define DSPARB_CSTART_SHIFT 7 |
@@ -2206,8 +2275,8 @@ | |||
2206 | #define WM1_LP_SR_EN (1<<31) | 2275 | #define WM1_LP_SR_EN (1<<31) |
2207 | #define WM1_LP_LATENCY_SHIFT 24 | 2276 | #define WM1_LP_LATENCY_SHIFT 24 |
2208 | #define WM1_LP_LATENCY_MASK (0x7f<<24) | 2277 | #define WM1_LP_LATENCY_MASK (0x7f<<24) |
2209 | #define WM1_LP_FBC_LP1_MASK (0xf<<20) | 2278 | #define WM1_LP_FBC_MASK (0xf<<20) |
2210 | #define WM1_LP_FBC_LP1_SHIFT 20 | 2279 | #define WM1_LP_FBC_SHIFT 20 |
2211 | #define WM1_LP_SR_MASK (0x1ff<<8) | 2280 | #define WM1_LP_SR_MASK (0x1ff<<8) |
2212 | #define WM1_LP_SR_SHIFT 8 | 2281 | #define WM1_LP_SR_SHIFT 8 |
2213 | #define WM1_LP_CURSOR_MASK (0x3f) | 2282 | #define WM1_LP_CURSOR_MASK (0x3f) |
@@ -2333,6 +2402,14 @@ | |||
2333 | #define DSPASURF 0x7019C /* 965+ only */ | 2402 | #define DSPASURF 0x7019C /* 965+ only */ |
2334 | #define DSPATILEOFF 0x701A4 /* 965+ only */ | 2403 | #define DSPATILEOFF 0x701A4 /* 965+ only */ |
2335 | 2404 | ||
2405 | #define DSPCNTR(plane) _PIPE(plane, DSPACNTR, DSPBCNTR) | ||
2406 | #define DSPADDR(plane) _PIPE(plane, DSPAADDR, DSPBADDR) | ||
2407 | #define DSPSTRIDE(plane) _PIPE(plane, DSPASTRIDE, DSPBSTRIDE) | ||
2408 | #define DSPPOS(plane) _PIPE(plane, DSPAPOS, DSPBPOS) | ||
2409 | #define DSPSIZE(plane) _PIPE(plane, DSPASIZE, DSPBSIZE) | ||
2410 | #define DSPSURF(plane) _PIPE(plane, DSPASURF, DSPBSURF) | ||
2411 | #define DSPTILEOFF(plane) _PIPE(plane, DSPATILEOFF, DSPBTILEOFF) | ||
2412 | |||
2336 | /* VBIOS flags */ | 2413 | /* VBIOS flags */ |
2337 | #define SWF00 0x71410 | 2414 | #define SWF00 0x71410 |
2338 | #define SWF01 0x71414 | 2415 | #define SWF01 0x71414 |
@@ -2397,6 +2474,7 @@ | |||
2397 | #define RR_HW_HIGH_POWER_FRAMES_MASK 0xff00 | 2474 | #define RR_HW_HIGH_POWER_FRAMES_MASK 0xff00 |
2398 | 2475 | ||
2399 | #define FDI_PLL_BIOS_0 0x46000 | 2476 | #define FDI_PLL_BIOS_0 0x46000 |
2477 | #define FDI_PLL_FB_CLOCK_MASK 0xff | ||
2400 | #define FDI_PLL_BIOS_1 0x46004 | 2478 | #define FDI_PLL_BIOS_1 0x46004 |
2401 | #define FDI_PLL_BIOS_2 0x46008 | 2479 | #define FDI_PLL_BIOS_2 0x46008 |
2402 | #define DISPLAY_PORT_PLL_BIOS_0 0x4600c | 2480 | #define DISPLAY_PORT_PLL_BIOS_0 0x4600c |
@@ -2420,46 +2498,47 @@ | |||
2420 | #define PIPEA_DATA_M1 0x60030 | 2498 | #define PIPEA_DATA_M1 0x60030 |
2421 | #define TU_SIZE(x) (((x)-1) << 25) /* default size 64 */ | 2499 | #define TU_SIZE(x) (((x)-1) << 25) /* default size 64 */ |
2422 | #define TU_SIZE_MASK 0x7e000000 | 2500 | #define TU_SIZE_MASK 0x7e000000 |
2423 | #define PIPEA_DATA_M1_OFFSET 0 | 2501 | #define PIPE_DATA_M1_OFFSET 0 |
2424 | #define PIPEA_DATA_N1 0x60034 | 2502 | #define PIPEA_DATA_N1 0x60034 |
2425 | #define PIPEA_DATA_N1_OFFSET 0 | 2503 | #define PIPE_DATA_N1_OFFSET 0 |
2426 | 2504 | ||
2427 | #define PIPEA_DATA_M2 0x60038 | 2505 | #define PIPEA_DATA_M2 0x60038 |
2428 | #define PIPEA_DATA_M2_OFFSET 0 | 2506 | #define PIPE_DATA_M2_OFFSET 0 |
2429 | #define PIPEA_DATA_N2 0x6003c | 2507 | #define PIPEA_DATA_N2 0x6003c |
2430 | #define PIPEA_DATA_N2_OFFSET 0 | 2508 | #define PIPE_DATA_N2_OFFSET 0 |
2431 | 2509 | ||
2432 | #define PIPEA_LINK_M1 0x60040 | 2510 | #define PIPEA_LINK_M1 0x60040 |
2433 | #define PIPEA_LINK_M1_OFFSET 0 | 2511 | #define PIPE_LINK_M1_OFFSET 0 |
2434 | #define PIPEA_LINK_N1 0x60044 | 2512 | #define PIPEA_LINK_N1 0x60044 |
2435 | #define PIPEA_LINK_N1_OFFSET 0 | 2513 | #define PIPE_LINK_N1_OFFSET 0 |
2436 | 2514 | ||
2437 | #define PIPEA_LINK_M2 0x60048 | 2515 | #define PIPEA_LINK_M2 0x60048 |
2438 | #define PIPEA_LINK_M2_OFFSET 0 | 2516 | #define PIPE_LINK_M2_OFFSET 0 |
2439 | #define PIPEA_LINK_N2 0x6004c | 2517 | #define PIPEA_LINK_N2 0x6004c |
2440 | #define PIPEA_LINK_N2_OFFSET 0 | 2518 | #define PIPE_LINK_N2_OFFSET 0 |
2441 | 2519 | ||
2442 | /* PIPEB timing regs are same start from 0x61000 */ | 2520 | /* PIPEB timing regs are same start from 0x61000 */ |
2443 | 2521 | ||
2444 | #define PIPEB_DATA_M1 0x61030 | 2522 | #define PIPEB_DATA_M1 0x61030 |
2445 | #define PIPEB_DATA_M1_OFFSET 0 | ||
2446 | #define PIPEB_DATA_N1 0x61034 | 2523 | #define PIPEB_DATA_N1 0x61034 |
2447 | #define PIPEB_DATA_N1_OFFSET 0 | ||
2448 | 2524 | ||
2449 | #define PIPEB_DATA_M2 0x61038 | 2525 | #define PIPEB_DATA_M2 0x61038 |
2450 | #define PIPEB_DATA_M2_OFFSET 0 | ||
2451 | #define PIPEB_DATA_N2 0x6103c | 2526 | #define PIPEB_DATA_N2 0x6103c |
2452 | #define PIPEB_DATA_N2_OFFSET 0 | ||
2453 | 2527 | ||
2454 | #define PIPEB_LINK_M1 0x61040 | 2528 | #define PIPEB_LINK_M1 0x61040 |
2455 | #define PIPEB_LINK_M1_OFFSET 0 | ||
2456 | #define PIPEB_LINK_N1 0x61044 | 2529 | #define PIPEB_LINK_N1 0x61044 |
2457 | #define PIPEB_LINK_N1_OFFSET 0 | ||
2458 | 2530 | ||
2459 | #define PIPEB_LINK_M2 0x61048 | 2531 | #define PIPEB_LINK_M2 0x61048 |
2460 | #define PIPEB_LINK_M2_OFFSET 0 | ||
2461 | #define PIPEB_LINK_N2 0x6104c | 2532 | #define PIPEB_LINK_N2 0x6104c |
2462 | #define PIPEB_LINK_N2_OFFSET 0 | 2533 | |
2534 | #define PIPE_DATA_M1(pipe) _PIPE(pipe, PIPEA_DATA_M1, PIPEB_DATA_M1) | ||
2535 | #define PIPE_DATA_N1(pipe) _PIPE(pipe, PIPEA_DATA_N1, PIPEB_DATA_N1) | ||
2536 | #define PIPE_DATA_M2(pipe) _PIPE(pipe, PIPEA_DATA_M2, PIPEB_DATA_M2) | ||
2537 | #define PIPE_DATA_N2(pipe) _PIPE(pipe, PIPEA_DATA_N2, PIPEB_DATA_N2) | ||
2538 | #define PIPE_LINK_M1(pipe) _PIPE(pipe, PIPEA_LINK_M1, PIPEB_LINK_M1) | ||
2539 | #define PIPE_LINK_N1(pipe) _PIPE(pipe, PIPEA_LINK_N1, PIPEB_LINK_N1) | ||
2540 | #define PIPE_LINK_M2(pipe) _PIPE(pipe, PIPEA_LINK_M2, PIPEB_LINK_M2) | ||
2541 | #define PIPE_LINK_N2(pipe) _PIPE(pipe, PIPEA_LINK_N2, PIPEB_LINK_N2) | ||
2463 | 2542 | ||
2464 | /* CPU panel fitter */ | 2543 | /* CPU panel fitter */ |
2465 | #define PFA_CTL_1 0x68080 | 2544 | #define PFA_CTL_1 0x68080 |
@@ -2600,11 +2679,14 @@ | |||
2600 | 2679 | ||
2601 | #define PCH_DPLL_A 0xc6014 | 2680 | #define PCH_DPLL_A 0xc6014 |
2602 | #define PCH_DPLL_B 0xc6018 | 2681 | #define PCH_DPLL_B 0xc6018 |
2682 | #define PCH_DPLL(pipe) _PIPE(pipe, PCH_DPLL_A, PCH_DPLL_B) | ||
2603 | 2683 | ||
2604 | #define PCH_FPA0 0xc6040 | 2684 | #define PCH_FPA0 0xc6040 |
2605 | #define PCH_FPA1 0xc6044 | 2685 | #define PCH_FPA1 0xc6044 |
2606 | #define PCH_FPB0 0xc6048 | 2686 | #define PCH_FPB0 0xc6048 |
2607 | #define PCH_FPB1 0xc604c | 2687 | #define PCH_FPB1 0xc604c |
2688 | #define PCH_FP0(pipe) _PIPE(pipe, PCH_FPA0, PCH_FPB0) | ||
2689 | #define PCH_FP1(pipe) _PIPE(pipe, PCH_FPA1, PCH_FPB1) | ||
2608 | 2690 | ||
2609 | #define PCH_DPLL_TEST 0xc606c | 2691 | #define PCH_DPLL_TEST 0xc606c |
2610 | 2692 | ||
@@ -2690,6 +2772,13 @@ | |||
2690 | #define TRANS_VBLANK_B 0xe1010 | 2772 | #define TRANS_VBLANK_B 0xe1010 |
2691 | #define TRANS_VSYNC_B 0xe1014 | 2773 | #define TRANS_VSYNC_B 0xe1014 |
2692 | 2774 | ||
2775 | #define TRANS_HTOTAL(pipe) _PIPE(pipe, TRANS_HTOTAL_A, TRANS_HTOTAL_B) | ||
2776 | #define TRANS_HBLANK(pipe) _PIPE(pipe, TRANS_HBLANK_A, TRANS_HBLANK_B) | ||
2777 | #define TRANS_HSYNC(pipe) _PIPE(pipe, TRANS_HSYNC_A, TRANS_HSYNC_B) | ||
2778 | #define TRANS_VTOTAL(pipe) _PIPE(pipe, TRANS_VTOTAL_A, TRANS_VTOTAL_B) | ||
2779 | #define TRANS_VBLANK(pipe) _PIPE(pipe, TRANS_VBLANK_A, TRANS_VBLANK_B) | ||
2780 | #define TRANS_VSYNC(pipe) _PIPE(pipe, TRANS_VSYNC_A, TRANS_VSYNC_B) | ||
2781 | |||
2693 | #define TRANSB_DATA_M1 0xe1030 | 2782 | #define TRANSB_DATA_M1 0xe1030 |
2694 | #define TRANSB_DATA_N1 0xe1034 | 2783 | #define TRANSB_DATA_N1 0xe1034 |
2695 | #define TRANSB_DATA_M2 0xe1038 | 2784 | #define TRANSB_DATA_M2 0xe1038 |
@@ -2701,6 +2790,7 @@ | |||
2701 | 2790 | ||
2702 | #define TRANSACONF 0xf0008 | 2791 | #define TRANSACONF 0xf0008 |
2703 | #define TRANSBCONF 0xf1008 | 2792 | #define TRANSBCONF 0xf1008 |
2793 | #define TRANSCONF(plane) _PIPE(plane, TRANSACONF, TRANSBCONF) | ||
2704 | #define TRANS_DISABLE (0<<31) | 2794 | #define TRANS_DISABLE (0<<31) |
2705 | #define TRANS_ENABLE (1<<31) | 2795 | #define TRANS_ENABLE (1<<31) |
2706 | #define TRANS_STATE_MASK (1<<30) | 2796 | #define TRANS_STATE_MASK (1<<30) |
@@ -2725,6 +2815,7 @@ | |||
2725 | /* CPU: FDI_TX */ | 2815 | /* CPU: FDI_TX */ |
2726 | #define FDI_TXA_CTL 0x60100 | 2816 | #define FDI_TXA_CTL 0x60100 |
2727 | #define FDI_TXB_CTL 0x61100 | 2817 | #define FDI_TXB_CTL 0x61100 |
2818 | #define FDI_TX_CTL(pipe) _PIPE(pipe, FDI_TXA_CTL, FDI_TXB_CTL) | ||
2728 | #define FDI_TX_DISABLE (0<<31) | 2819 | #define FDI_TX_DISABLE (0<<31) |
2729 | #define FDI_TX_ENABLE (1<<31) | 2820 | #define FDI_TX_ENABLE (1<<31) |
2730 | #define FDI_LINK_TRAIN_PATTERN_1 (0<<28) | 2821 | #define FDI_LINK_TRAIN_PATTERN_1 (0<<28) |
@@ -2766,8 +2857,8 @@ | |||
2766 | /* FDI_RX, FDI_X is hard-wired to Transcoder_X */ | 2857 | /* FDI_RX, FDI_X is hard-wired to Transcoder_X */ |
2767 | #define FDI_RXA_CTL 0xf000c | 2858 | #define FDI_RXA_CTL 0xf000c |
2768 | #define FDI_RXB_CTL 0xf100c | 2859 | #define FDI_RXB_CTL 0xf100c |
2860 | #define FDI_RX_CTL(pipe) _PIPE(pipe, FDI_RXA_CTL, FDI_RXB_CTL) | ||
2769 | #define FDI_RX_ENABLE (1<<31) | 2861 | #define FDI_RX_ENABLE (1<<31) |
2770 | #define FDI_RX_DISABLE (0<<31) | ||
2771 | /* train, dp width same as FDI_TX */ | 2862 | /* train, dp width same as FDI_TX */ |
2772 | #define FDI_DP_PORT_WIDTH_X8 (7<<19) | 2863 | #define FDI_DP_PORT_WIDTH_X8 (7<<19) |
2773 | #define FDI_8BPC (0<<16) | 2864 | #define FDI_8BPC (0<<16) |
@@ -2782,8 +2873,7 @@ | |||
2782 | #define FDI_FS_ERR_REPORT_ENABLE (1<<9) | 2873 | #define FDI_FS_ERR_REPORT_ENABLE (1<<9) |
2783 | #define FDI_FE_ERR_REPORT_ENABLE (1<<8) | 2874 | #define FDI_FE_ERR_REPORT_ENABLE (1<<8) |
2784 | #define FDI_RX_ENHANCE_FRAME_ENABLE (1<<6) | 2875 | #define FDI_RX_ENHANCE_FRAME_ENABLE (1<<6) |
2785 | #define FDI_SEL_RAWCLK (0<<4) | 2876 | #define FDI_PCDCLK (1<<4) |
2786 | #define FDI_SEL_PCDCLK (1<<4) | ||
2787 | /* CPT */ | 2877 | /* CPT */ |
2788 | #define FDI_AUTO_TRAINING (1<<10) | 2878 | #define FDI_AUTO_TRAINING (1<<10) |
2789 | #define FDI_LINK_TRAIN_PATTERN_1_CPT (0<<8) | 2879 | #define FDI_LINK_TRAIN_PATTERN_1_CPT (0<<8) |
@@ -2798,6 +2888,9 @@ | |||
2798 | #define FDI_RXA_TUSIZE2 0xf0038 | 2888 | #define FDI_RXA_TUSIZE2 0xf0038 |
2799 | #define FDI_RXB_TUSIZE1 0xf1030 | 2889 | #define FDI_RXB_TUSIZE1 0xf1030 |
2800 | #define FDI_RXB_TUSIZE2 0xf1038 | 2890 | #define FDI_RXB_TUSIZE2 0xf1038 |
2891 | #define FDI_RX_MISC(pipe) _PIPE(pipe, FDI_RXA_MISC, FDI_RXB_MISC) | ||
2892 | #define FDI_RX_TUSIZE1(pipe) _PIPE(pipe, FDI_RXA_TUSIZE1, FDI_RXB_TUSIZE1) | ||
2893 | #define FDI_RX_TUSIZE2(pipe) _PIPE(pipe, FDI_RXA_TUSIZE2, FDI_RXB_TUSIZE2) | ||
2801 | 2894 | ||
2802 | /* FDI_RX interrupt register format */ | 2895 | /* FDI_RX interrupt register format */ |
2803 | #define FDI_RX_INTER_LANE_ALIGN (1<<10) | 2896 | #define FDI_RX_INTER_LANE_ALIGN (1<<10) |
@@ -2816,6 +2909,8 @@ | |||
2816 | #define FDI_RXA_IMR 0xf0018 | 2909 | #define FDI_RXA_IMR 0xf0018 |
2817 | #define FDI_RXB_IIR 0xf1014 | 2910 | #define FDI_RXB_IIR 0xf1014 |
2818 | #define FDI_RXB_IMR 0xf1018 | 2911 | #define FDI_RXB_IMR 0xf1018 |
2912 | #define FDI_RX_IIR(pipe) _PIPE(pipe, FDI_RXA_IIR, FDI_RXB_IIR) | ||
2913 | #define FDI_RX_IMR(pipe) _PIPE(pipe, FDI_RXA_IMR, FDI_RXB_IMR) | ||
2819 | 2914 | ||
2820 | #define FDI_PLL_CTL_1 0xfe000 | 2915 | #define FDI_PLL_CTL_1 0xfe000 |
2821 | #define FDI_PLL_CTL_2 0xfe004 | 2916 | #define FDI_PLL_CTL_2 0xfe004 |
@@ -2935,6 +3030,7 @@ | |||
2935 | #define TRANS_DP_CTL_A 0xe0300 | 3030 | #define TRANS_DP_CTL_A 0xe0300 |
2936 | #define TRANS_DP_CTL_B 0xe1300 | 3031 | #define TRANS_DP_CTL_B 0xe1300 |
2937 | #define TRANS_DP_CTL_C 0xe2300 | 3032 | #define TRANS_DP_CTL_C 0xe2300 |
3033 | #define TRANS_DP_CTL(pipe) (TRANS_DP_CTL_A + (pipe) * 0x01000) | ||
2938 | #define TRANS_DP_OUTPUT_ENABLE (1<<31) | 3034 | #define TRANS_DP_OUTPUT_ENABLE (1<<31) |
2939 | #define TRANS_DP_PORT_SEL_B (0<<29) | 3035 | #define TRANS_DP_PORT_SEL_B (0<<29) |
2940 | #define TRANS_DP_PORT_SEL_C (1<<29) | 3036 | #define TRANS_DP_PORT_SEL_C (1<<29) |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 31f08581e93a..967dcde312b2 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -878,9 +878,7 @@ int i915_restore_state(struct drm_device *dev) | |||
878 | for (i = 0; i < 3; i++) | 878 | for (i = 0; i < 3; i++) |
879 | I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); | 879 | I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); |
880 | 880 | ||
881 | /* I2C state */ | 881 | intel_i2c_reset(dev); |
882 | intel_i2c_reset_gmbus(dev); | ||
883 | 882 | ||
884 | return 0; | 883 | return 0; |
885 | } | 884 | } |
886 | |||
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 96f75d7f6633..d11bbcad4fea 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -169,6 +169,8 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
169 | ((unsigned char *)entry + dvo_timing_offset); | 169 | ((unsigned char *)entry + dvo_timing_offset); |
170 | 170 | ||
171 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); | 171 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); |
172 | if (!panel_fixed_mode) | ||
173 | return; | ||
172 | 174 | ||
173 | fill_detail_timing_data(panel_fixed_mode, dvo_timing); | 175 | fill_detail_timing_data(panel_fixed_mode, dvo_timing); |
174 | 176 | ||
@@ -289,14 +291,6 @@ parse_general_definitions(struct drm_i915_private *dev_priv, | |||
289 | struct bdb_header *bdb) | 291 | struct bdb_header *bdb) |
290 | { | 292 | { |
291 | struct bdb_general_definitions *general; | 293 | struct bdb_general_definitions *general; |
292 | const int crt_bus_map_table[] = { | ||
293 | GPIOB, | ||
294 | GPIOA, | ||
295 | GPIOC, | ||
296 | GPIOD, | ||
297 | GPIOE, | ||
298 | GPIOF, | ||
299 | }; | ||
300 | 294 | ||
301 | general = find_section(bdb, BDB_GENERAL_DEFINITIONS); | 295 | general = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
302 | if (general) { | 296 | if (general) { |
@@ -304,10 +298,8 @@ parse_general_definitions(struct drm_i915_private *dev_priv, | |||
304 | if (block_size >= sizeof(*general)) { | 298 | if (block_size >= sizeof(*general)) { |
305 | int bus_pin = general->crt_ddc_gmbus_pin; | 299 | int bus_pin = general->crt_ddc_gmbus_pin; |
306 | DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin); | 300 | DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin); |
307 | if ((bus_pin >= 1) && (bus_pin <= 6)) { | 301 | if (bus_pin >= 1 && bus_pin <= 6) |
308 | dev_priv->crt_ddc_bus = | 302 | dev_priv->crt_ddc_pin = bus_pin - 1; |
309 | crt_bus_map_table[bus_pin-1]; | ||
310 | } | ||
311 | } else { | 303 | } else { |
312 | DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n", | 304 | DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n", |
313 | block_size); | 305 | block_size); |
@@ -317,7 +309,7 @@ parse_general_definitions(struct drm_i915_private *dev_priv, | |||
317 | 309 | ||
318 | static void | 310 | static void |
319 | parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | 311 | parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, |
320 | struct bdb_header *bdb) | 312 | struct bdb_header *bdb) |
321 | { | 313 | { |
322 | struct sdvo_device_mapping *p_mapping; | 314 | struct sdvo_device_mapping *p_mapping; |
323 | struct bdb_general_definitions *p_defs; | 315 | struct bdb_general_definitions *p_defs; |
@@ -327,7 +319,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
327 | 319 | ||
328 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | 320 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
329 | if (!p_defs) { | 321 | if (!p_defs) { |
330 | DRM_DEBUG_KMS("No general definition block is found\n"); | 322 | DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n"); |
331 | return; | 323 | return; |
332 | } | 324 | } |
333 | /* judge whether the size of child device meets the requirements. | 325 | /* judge whether the size of child device meets the requirements. |
@@ -460,7 +452,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, | |||
460 | 452 | ||
461 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | 453 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
462 | if (!p_defs) { | 454 | if (!p_defs) { |
463 | DRM_DEBUG_KMS("No general definition block is found\n"); | 455 | DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); |
464 | return; | 456 | return; |
465 | } | 457 | } |
466 | /* judge whether the size of child device meets the requirements. | 458 | /* judge whether the size of child device meets the requirements. |
@@ -513,6 +505,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, | |||
513 | } | 505 | } |
514 | return; | 506 | return; |
515 | } | 507 | } |
508 | |||
516 | /** | 509 | /** |
517 | * intel_init_bios - initialize VBIOS settings & find VBT | 510 | * intel_init_bios - initialize VBIOS settings & find VBT |
518 | * @dev: DRM device | 511 | * @dev: DRM device |
@@ -520,11 +513,6 @@ parse_device_mapping(struct drm_i915_private *dev_priv, | |||
520 | * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers | 513 | * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers |
521 | * to appropriate values. | 514 | * to appropriate values. |
522 | * | 515 | * |
523 | * VBT existence is a sanity check that is relied on by other i830_bios.c code. | ||
524 | * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may | ||
525 | * feed an updated VBT back through that, compared to what we'll fetch using | ||
526 | * this method of groping around in the BIOS data. | ||
527 | * | ||
528 | * Returns 0 on success, nonzero on failure. | 516 | * Returns 0 on success, nonzero on failure. |
529 | */ | 517 | */ |
530 | bool | 518 | bool |
@@ -532,31 +520,47 @@ intel_init_bios(struct drm_device *dev) | |||
532 | { | 520 | { |
533 | struct drm_i915_private *dev_priv = dev->dev_private; | 521 | struct drm_i915_private *dev_priv = dev->dev_private; |
534 | struct pci_dev *pdev = dev->pdev; | 522 | struct pci_dev *pdev = dev->pdev; |
535 | struct vbt_header *vbt = NULL; | 523 | struct bdb_header *bdb = NULL; |
536 | struct bdb_header *bdb; | 524 | u8 __iomem *bios = NULL; |
537 | u8 __iomem *bios; | 525 | |
538 | size_t size; | 526 | dev_priv->crt_ddc_pin = GMBUS_PORT_VGADDC; |
539 | int i; | 527 | |
540 | 528 | /* XXX Should this validation be moved to intel_opregion.c? */ | |
541 | bios = pci_map_rom(pdev, &size); | 529 | if (dev_priv->opregion.vbt) { |
542 | if (!bios) | 530 | struct vbt_header *vbt = dev_priv->opregion.vbt; |
543 | return -1; | 531 | if (memcmp(vbt->signature, "$VBT", 4) == 0) { |
544 | 532 | DRM_DEBUG_DRIVER("Using VBT from OpRegion: %20s\n", | |
545 | /* Scour memory looking for the VBT signature */ | 533 | vbt->signature); |
546 | for (i = 0; i + 4 < size; i++) { | 534 | bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset); |
547 | if (!memcmp(bios + i, "$VBT", 4)) { | 535 | } else |
548 | vbt = (struct vbt_header *)(bios + i); | 536 | dev_priv->opregion.vbt = NULL; |
549 | break; | ||
550 | } | ||
551 | } | 537 | } |
552 | 538 | ||
553 | if (!vbt) { | 539 | if (bdb == NULL) { |
554 | DRM_ERROR("VBT signature missing\n"); | 540 | struct vbt_header *vbt = NULL; |
555 | pci_unmap_rom(pdev, bios); | 541 | size_t size; |
556 | return -1; | 542 | int i; |
557 | } | ||
558 | 543 | ||
559 | bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); | 544 | bios = pci_map_rom(pdev, &size); |
545 | if (!bios) | ||
546 | return -1; | ||
547 | |||
548 | /* Scour memory looking for the VBT signature */ | ||
549 | for (i = 0; i + 4 < size; i++) { | ||
550 | if (!memcmp(bios + i, "$VBT", 4)) { | ||
551 | vbt = (struct vbt_header *)(bios + i); | ||
552 | break; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | if (!vbt) { | ||
557 | DRM_ERROR("VBT signature missing\n"); | ||
558 | pci_unmap_rom(pdev, bios); | ||
559 | return -1; | ||
560 | } | ||
561 | |||
562 | bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); | ||
563 | } | ||
560 | 564 | ||
561 | /* Grab useful general definitions */ | 565 | /* Grab useful general definitions */ |
562 | parse_general_features(dev_priv, bdb); | 566 | parse_general_features(dev_priv, bdb); |
@@ -568,7 +572,8 @@ intel_init_bios(struct drm_device *dev) | |||
568 | parse_driver_features(dev_priv, bdb); | 572 | parse_driver_features(dev_priv, bdb); |
569 | parse_edp(dev_priv, bdb); | 573 | parse_edp(dev_priv, bdb); |
570 | 574 | ||
571 | pci_unmap_rom(pdev, bios); | 575 | if (bios) |
576 | pci_unmap_rom(pdev, bios); | ||
572 | 577 | ||
573 | return 0; | 578 | return 0; |
574 | } | 579 | } |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 197d4f32585a..6d3385511663 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -187,7 +187,7 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
187 | I915_WRITE(PCH_ADPA, adpa); | 187 | I915_WRITE(PCH_ADPA, adpa); |
188 | 188 | ||
189 | if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, | 189 | if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
190 | 1000, 1)) | 190 | 1000)) |
191 | DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); | 191 | DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); |
192 | 192 | ||
193 | if (turn_off_dac) { | 193 | if (turn_off_dac) { |
@@ -244,7 +244,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
244 | /* wait for FORCE_DETECT to go off */ | 244 | /* wait for FORCE_DETECT to go off */ |
245 | if (wait_for((I915_READ(PORT_HOTPLUG_EN) & | 245 | if (wait_for((I915_READ(PORT_HOTPLUG_EN) & |
246 | CRT_HOTPLUG_FORCE_DETECT) == 0, | 246 | CRT_HOTPLUG_FORCE_DETECT) == 0, |
247 | 1000, 1)) | 247 | 1000)) |
248 | DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off"); | 248 | DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off"); |
249 | } | 249 | } |
250 | 250 | ||
@@ -263,19 +263,20 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
263 | 263 | ||
264 | static bool intel_crt_detect_ddc(struct drm_encoder *encoder) | 264 | static bool intel_crt_detect_ddc(struct drm_encoder *encoder) |
265 | { | 265 | { |
266 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 266 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
267 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | ||
267 | 268 | ||
268 | /* CRT should always be at 0, but check anyway */ | 269 | /* CRT should always be at 0, but check anyway */ |
269 | if (intel_encoder->type != INTEL_OUTPUT_ANALOG) | 270 | if (intel_encoder->type != INTEL_OUTPUT_ANALOG) |
270 | return false; | 271 | return false; |
271 | 272 | ||
272 | return intel_ddc_probe(intel_encoder); | 273 | return intel_ddc_probe(intel_encoder, dev_priv->crt_ddc_pin); |
273 | } | 274 | } |
274 | 275 | ||
275 | static enum drm_connector_status | 276 | static enum drm_connector_status |
276 | intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder) | 277 | intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder) |
277 | { | 278 | { |
278 | struct drm_encoder *encoder = &intel_encoder->enc; | 279 | struct drm_encoder *encoder = &intel_encoder->base; |
279 | struct drm_device *dev = encoder->dev; | 280 | struct drm_device *dev = encoder->dev; |
280 | struct drm_i915_private *dev_priv = dev->dev_private; | 281 | struct drm_i915_private *dev_priv = dev->dev_private; |
281 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 282 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
@@ -327,6 +328,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
327 | if (IS_I9XX(dev)) { | 328 | if (IS_I9XX(dev)) { |
328 | uint32_t pipeconf = I915_READ(pipeconf_reg); | 329 | uint32_t pipeconf = I915_READ(pipeconf_reg); |
329 | I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); | 330 | I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); |
331 | POSTING_READ(pipeconf_reg); | ||
330 | /* Wait for next Vblank to substitue | 332 | /* Wait for next Vblank to substitue |
331 | * border color for Color info */ | 333 | * border color for Color info */ |
332 | intel_wait_for_vblank(dev, pipe); | 334 | intel_wait_for_vblank(dev, pipe); |
@@ -404,8 +406,7 @@ static enum drm_connector_status | |||
404 | intel_crt_detect(struct drm_connector *connector, bool force) | 406 | intel_crt_detect(struct drm_connector *connector, bool force) |
405 | { | 407 | { |
406 | struct drm_device *dev = connector->dev; | 408 | struct drm_device *dev = connector->dev; |
407 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 409 | struct intel_encoder *encoder = intel_attached_encoder(connector); |
408 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
409 | struct drm_crtc *crtc; | 410 | struct drm_crtc *crtc; |
410 | int dpms_mode; | 411 | int dpms_mode; |
411 | enum drm_connector_status status; | 412 | enum drm_connector_status status; |
@@ -417,21 +418,21 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
417 | return connector_status_disconnected; | 418 | return connector_status_disconnected; |
418 | } | 419 | } |
419 | 420 | ||
420 | if (intel_crt_detect_ddc(encoder)) | 421 | if (intel_crt_detect_ddc(&encoder->base)) |
421 | return connector_status_connected; | 422 | return connector_status_connected; |
422 | 423 | ||
423 | if (!force) | 424 | if (!force) |
424 | return connector->status; | 425 | return connector->status; |
425 | 426 | ||
426 | /* for pre-945g platforms use load detect */ | 427 | /* for pre-945g platforms use load detect */ |
427 | if (encoder->crtc && encoder->crtc->enabled) { | 428 | if (encoder->base.crtc && encoder->base.crtc->enabled) { |
428 | status = intel_crt_load_detect(encoder->crtc, intel_encoder); | 429 | status = intel_crt_load_detect(encoder->base.crtc, encoder); |
429 | } else { | 430 | } else { |
430 | crtc = intel_get_load_detect_pipe(intel_encoder, connector, | 431 | crtc = intel_get_load_detect_pipe(encoder, connector, |
431 | NULL, &dpms_mode); | 432 | NULL, &dpms_mode); |
432 | if (crtc) { | 433 | if (crtc) { |
433 | status = intel_crt_load_detect(crtc, intel_encoder); | 434 | status = intel_crt_load_detect(crtc, encoder); |
434 | intel_release_load_detect_pipe(intel_encoder, | 435 | intel_release_load_detect_pipe(encoder, |
435 | connector, dpms_mode); | 436 | connector, dpms_mode); |
436 | } else | 437 | } else |
437 | status = connector_status_unknown; | 438 | status = connector_status_unknown; |
@@ -449,32 +450,18 @@ static void intel_crt_destroy(struct drm_connector *connector) | |||
449 | 450 | ||
450 | static int intel_crt_get_modes(struct drm_connector *connector) | 451 | static int intel_crt_get_modes(struct drm_connector *connector) |
451 | { | 452 | { |
452 | int ret; | ||
453 | struct drm_encoder *encoder = intel_attached_encoder(connector); | ||
454 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
455 | struct i2c_adapter *ddc_bus; | ||
456 | struct drm_device *dev = connector->dev; | 453 | struct drm_device *dev = connector->dev; |
454 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
455 | int ret; | ||
457 | 456 | ||
458 | 457 | ret = intel_ddc_get_modes(connector, | |
459 | ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 458 | &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); |
460 | if (ret || !IS_G4X(dev)) | 459 | if (ret || !IS_G4X(dev)) |
461 | goto end; | 460 | return ret; |
462 | 461 | ||
463 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ | 462 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ |
464 | ddc_bus = intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); | 463 | return intel_ddc_get_modes(connector, |
465 | 464 | &dev_priv->gmbus[GMBUS_PORT_DPB].adapter); | |
466 | if (!ddc_bus) { | ||
467 | dev_printk(KERN_ERR, &connector->dev->pdev->dev, | ||
468 | "DDC bus registration failed for CRTDDC_D.\n"); | ||
469 | goto end; | ||
470 | } | ||
471 | /* Try to get modes by GPIOD port */ | ||
472 | ret = intel_ddc_get_modes(connector, ddc_bus); | ||
473 | intel_i2c_destroy(ddc_bus); | ||
474 | |||
475 | end: | ||
476 | return ret; | ||
477 | |||
478 | } | 465 | } |
479 | 466 | ||
480 | static int intel_crt_set_property(struct drm_connector *connector, | 467 | static int intel_crt_set_property(struct drm_connector *connector, |
@@ -507,7 +494,7 @@ static const struct drm_connector_funcs intel_crt_connector_funcs = { | |||
507 | static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = { | 494 | static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = { |
508 | .mode_valid = intel_crt_mode_valid, | 495 | .mode_valid = intel_crt_mode_valid, |
509 | .get_modes = intel_crt_get_modes, | 496 | .get_modes = intel_crt_get_modes, |
510 | .best_encoder = intel_attached_encoder, | 497 | .best_encoder = intel_best_encoder, |
511 | }; | 498 | }; |
512 | 499 | ||
513 | static const struct drm_encoder_funcs intel_crt_enc_funcs = { | 500 | static const struct drm_encoder_funcs intel_crt_enc_funcs = { |
@@ -520,7 +507,6 @@ void intel_crt_init(struct drm_device *dev) | |||
520 | struct intel_encoder *intel_encoder; | 507 | struct intel_encoder *intel_encoder; |
521 | struct intel_connector *intel_connector; | 508 | struct intel_connector *intel_connector; |
522 | struct drm_i915_private *dev_priv = dev->dev_private; | 509 | struct drm_i915_private *dev_priv = dev->dev_private; |
523 | u32 i2c_reg; | ||
524 | 510 | ||
525 | intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL); | 511 | intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL); |
526 | if (!intel_encoder) | 512 | if (!intel_encoder) |
@@ -536,27 +522,10 @@ void intel_crt_init(struct drm_device *dev) | |||
536 | drm_connector_init(dev, &intel_connector->base, | 522 | drm_connector_init(dev, &intel_connector->base, |
537 | &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); | 523 | &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); |
538 | 524 | ||
539 | drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs, | 525 | drm_encoder_init(dev, &intel_encoder->base, &intel_crt_enc_funcs, |
540 | DRM_MODE_ENCODER_DAC); | 526 | DRM_MODE_ENCODER_DAC); |
541 | 527 | ||
542 | drm_mode_connector_attach_encoder(&intel_connector->base, | 528 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
543 | &intel_encoder->enc); | ||
544 | |||
545 | /* Set up the DDC bus. */ | ||
546 | if (HAS_PCH_SPLIT(dev)) | ||
547 | i2c_reg = PCH_GPIOA; | ||
548 | else { | ||
549 | i2c_reg = GPIOA; | ||
550 | /* Use VBT information for CRT DDC if available */ | ||
551 | if (dev_priv->crt_ddc_bus != 0) | ||
552 | i2c_reg = dev_priv->crt_ddc_bus; | ||
553 | } | ||
554 | intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); | ||
555 | if (!intel_encoder->ddc_bus) { | ||
556 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " | ||
557 | "failed.\n"); | ||
558 | return; | ||
559 | } | ||
560 | 529 | ||
561 | intel_encoder->type = INTEL_OUTPUT_ANALOG; | 530 | intel_encoder->type = INTEL_OUTPUT_ANALOG; |
562 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 531 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
@@ -566,7 +535,7 @@ void intel_crt_init(struct drm_device *dev) | |||
566 | connector->interlace_allowed = 1; | 535 | connector->interlace_allowed = 1; |
567 | connector->doublescan_allowed = 0; | 536 | connector->doublescan_allowed = 0; |
568 | 537 | ||
569 | drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs); | 538 | drm_encoder_helper_add(&intel_encoder->base, &intel_crt_helper_funcs); |
570 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); | 539 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); |
571 | 540 | ||
572 | drm_sysfs_connector_add(connector); | 541 | drm_sysfs_connector_add(connector); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b5bf51a4502d..1b5d878be975 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -43,8 +43,8 @@ | |||
43 | 43 | ||
44 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); | 44 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); |
45 | static void intel_update_watermarks(struct drm_device *dev); | 45 | static void intel_update_watermarks(struct drm_device *dev); |
46 | static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule); | 46 | static void intel_increase_pllclock(struct drm_crtc *crtc); |
47 | static void intel_crtc_update_cursor(struct drm_crtc *crtc); | 47 | static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); |
48 | 48 | ||
49 | typedef struct { | 49 | typedef struct { |
50 | /* given values */ | 50 | /* given values */ |
@@ -342,6 +342,13 @@ static bool | |||
342 | intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, | 342 | intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, |
343 | int target, int refclk, intel_clock_t *best_clock); | 343 | int target, int refclk, intel_clock_t *best_clock); |
344 | 344 | ||
345 | static inline u32 /* units of 100MHz */ | ||
346 | intel_fdi_link_freq(struct drm_device *dev) | ||
347 | { | ||
348 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
349 | return (I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2; | ||
350 | } | ||
351 | |||
345 | static const intel_limit_t intel_limits_i8xx_dvo = { | 352 | static const intel_limit_t intel_limits_i8xx_dvo = { |
346 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, | 353 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, |
347 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, | 354 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, |
@@ -744,20 +751,17 @@ static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock | |||
744 | /** | 751 | /** |
745 | * Returns whether any output on the specified pipe is of the specified type | 752 | * Returns whether any output on the specified pipe is of the specified type |
746 | */ | 753 | */ |
747 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type) | 754 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type) |
748 | { | 755 | { |
749 | struct drm_device *dev = crtc->dev; | 756 | struct drm_device *dev = crtc->dev; |
750 | struct drm_mode_config *mode_config = &dev->mode_config; | 757 | struct drm_mode_config *mode_config = &dev->mode_config; |
751 | struct drm_encoder *l_entry; | 758 | struct intel_encoder *encoder; |
752 | 759 | ||
753 | list_for_each_entry(l_entry, &mode_config->encoder_list, head) { | 760 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) |
754 | if (l_entry && l_entry->crtc == crtc) { | 761 | if (encoder->base.crtc == crtc && encoder->type == type) |
755 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(l_entry); | 762 | return true; |
756 | if (intel_encoder->type == type) | 763 | |
757 | return true; | 764 | return false; |
758 | } | ||
759 | } | ||
760 | return false; | ||
761 | } | 765 | } |
762 | 766 | ||
763 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) | 767 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) |
@@ -955,26 +959,26 @@ static bool | |||
955 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | 959 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, |
956 | int target, int refclk, intel_clock_t *best_clock) | 960 | int target, int refclk, intel_clock_t *best_clock) |
957 | { | 961 | { |
958 | intel_clock_t clock; | 962 | intel_clock_t clock; |
959 | if (target < 200000) { | 963 | if (target < 200000) { |
960 | clock.p1 = 2; | 964 | clock.p1 = 2; |
961 | clock.p2 = 10; | 965 | clock.p2 = 10; |
962 | clock.n = 2; | 966 | clock.n = 2; |
963 | clock.m1 = 23; | 967 | clock.m1 = 23; |
964 | clock.m2 = 8; | 968 | clock.m2 = 8; |
965 | } else { | 969 | } else { |
966 | clock.p1 = 1; | 970 | clock.p1 = 1; |
967 | clock.p2 = 10; | 971 | clock.p2 = 10; |
968 | clock.n = 1; | 972 | clock.n = 1; |
969 | clock.m1 = 14; | 973 | clock.m1 = 14; |
970 | clock.m2 = 2; | 974 | clock.m2 = 2; |
971 | } | 975 | } |
972 | clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); | 976 | clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); |
973 | clock.p = (clock.p1 * clock.p2); | 977 | clock.p = (clock.p1 * clock.p2); |
974 | clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; | 978 | clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; |
975 | clock.vco = 0; | 979 | clock.vco = 0; |
976 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | 980 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); |
977 | return true; | 981 | return true; |
978 | } | 982 | } |
979 | 983 | ||
980 | /** | 984 | /** |
@@ -1007,9 +1011,9 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe) | |||
1007 | I915_READ(pipestat_reg) | PIPE_VBLANK_INTERRUPT_STATUS); | 1011 | I915_READ(pipestat_reg) | PIPE_VBLANK_INTERRUPT_STATUS); |
1008 | 1012 | ||
1009 | /* Wait for vblank interrupt bit to set */ | 1013 | /* Wait for vblank interrupt bit to set */ |
1010 | if (wait_for((I915_READ(pipestat_reg) & | 1014 | if (wait_for(I915_READ(pipestat_reg) & |
1011 | PIPE_VBLANK_INTERRUPT_STATUS), | 1015 | PIPE_VBLANK_INTERRUPT_STATUS, |
1012 | 50, 0)) | 1016 | 50)) |
1013 | DRM_DEBUG_KMS("vblank wait timed out\n"); | 1017 | DRM_DEBUG_KMS("vblank wait timed out\n"); |
1014 | } | 1018 | } |
1015 | 1019 | ||
@@ -1030,20 +1034,20 @@ void intel_wait_for_vblank_off(struct drm_device *dev, int pipe) | |||
1030 | struct drm_i915_private *dev_priv = dev->dev_private; | 1034 | struct drm_i915_private *dev_priv = dev->dev_private; |
1031 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); | 1035 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); |
1032 | unsigned long timeout = jiffies + msecs_to_jiffies(100); | 1036 | unsigned long timeout = jiffies + msecs_to_jiffies(100); |
1033 | u32 last_line; | 1037 | u32 last_line, line; |
1034 | 1038 | ||
1035 | /* Wait for the display line to settle */ | 1039 | /* Wait for the display line to settle */ |
1040 | line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | ||
1036 | do { | 1041 | do { |
1037 | last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | 1042 | last_line = line; |
1038 | mdelay(5); | 1043 | MSLEEP(5); |
1039 | } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && | 1044 | line = I915_READ(pipedsl_reg) & DSL_LINEMASK; |
1040 | time_after(timeout, jiffies)); | 1045 | } while (line != last_line && time_after(timeout, jiffies)); |
1041 | 1046 | ||
1042 | if (time_after(jiffies, timeout)) | 1047 | if (line != last_line) |
1043 | DRM_DEBUG_KMS("vblank wait timed out\n"); | 1048 | DRM_DEBUG_KMS("vblank wait timed out\n"); |
1044 | } | 1049 | } |
1045 | 1050 | ||
1046 | /* Parameters have changed, update FBC info */ | ||
1047 | static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | 1051 | static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) |
1048 | { | 1052 | { |
1049 | struct drm_device *dev = crtc->dev; | 1053 | struct drm_device *dev = crtc->dev; |
@@ -1055,6 +1059,14 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1055 | int plane, i; | 1059 | int plane, i; |
1056 | u32 fbc_ctl, fbc_ctl2; | 1060 | u32 fbc_ctl, fbc_ctl2; |
1057 | 1061 | ||
1062 | if (fb->pitch == dev_priv->cfb_pitch && | ||
1063 | obj_priv->fence_reg == dev_priv->cfb_fence && | ||
1064 | intel_crtc->plane == dev_priv->cfb_plane && | ||
1065 | I915_READ(FBC_CONTROL) & FBC_CTL_EN) | ||
1066 | return; | ||
1067 | |||
1068 | i8xx_disable_fbc(dev); | ||
1069 | |||
1058 | dev_priv->cfb_pitch = dev_priv->cfb_size / FBC_LL_SIZE; | 1070 | dev_priv->cfb_pitch = dev_priv->cfb_size / FBC_LL_SIZE; |
1059 | 1071 | ||
1060 | if (fb->pitch < dev_priv->cfb_pitch) | 1072 | if (fb->pitch < dev_priv->cfb_pitch) |
@@ -1088,7 +1100,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1088 | I915_WRITE(FBC_CONTROL, fbc_ctl); | 1100 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
1089 | 1101 | ||
1090 | DRM_DEBUG_KMS("enabled FBC, pitch %ld, yoff %d, plane %d, ", | 1102 | DRM_DEBUG_KMS("enabled FBC, pitch %ld, yoff %d, plane %d, ", |
1091 | dev_priv->cfb_pitch, crtc->y, dev_priv->cfb_plane); | 1103 | dev_priv->cfb_pitch, crtc->y, dev_priv->cfb_plane); |
1092 | } | 1104 | } |
1093 | 1105 | ||
1094 | void i8xx_disable_fbc(struct drm_device *dev) | 1106 | void i8xx_disable_fbc(struct drm_device *dev) |
@@ -1096,19 +1108,13 @@ void i8xx_disable_fbc(struct drm_device *dev) | |||
1096 | struct drm_i915_private *dev_priv = dev->dev_private; | 1108 | struct drm_i915_private *dev_priv = dev->dev_private; |
1097 | u32 fbc_ctl; | 1109 | u32 fbc_ctl; |
1098 | 1110 | ||
1099 | if (!I915_HAS_FBC(dev)) | ||
1100 | return; | ||
1101 | |||
1102 | if (!(I915_READ(FBC_CONTROL) & FBC_CTL_EN)) | ||
1103 | return; /* Already off, just return */ | ||
1104 | |||
1105 | /* Disable compression */ | 1111 | /* Disable compression */ |
1106 | fbc_ctl = I915_READ(FBC_CONTROL); | 1112 | fbc_ctl = I915_READ(FBC_CONTROL); |
1107 | fbc_ctl &= ~FBC_CTL_EN; | 1113 | fbc_ctl &= ~FBC_CTL_EN; |
1108 | I915_WRITE(FBC_CONTROL, fbc_ctl); | 1114 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
1109 | 1115 | ||
1110 | /* Wait for compressing bit to clear */ | 1116 | /* Wait for compressing bit to clear */ |
1111 | if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10, 0)) { | 1117 | if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) { |
1112 | DRM_DEBUG_KMS("FBC idle timed out\n"); | 1118 | DRM_DEBUG_KMS("FBC idle timed out\n"); |
1113 | return; | 1119 | return; |
1114 | } | 1120 | } |
@@ -1131,14 +1137,27 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1131 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | 1137 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
1132 | struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); | 1138 | struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); |
1133 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1139 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1134 | int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : | 1140 | int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; |
1135 | DPFC_CTL_PLANEB); | ||
1136 | unsigned long stall_watermark = 200; | 1141 | unsigned long stall_watermark = 200; |
1137 | u32 dpfc_ctl; | 1142 | u32 dpfc_ctl; |
1138 | 1143 | ||
1144 | dpfc_ctl = I915_READ(DPFC_CONTROL); | ||
1145 | if (dpfc_ctl & DPFC_CTL_EN) { | ||
1146 | if (dev_priv->cfb_pitch == dev_priv->cfb_pitch / 64 - 1 && | ||
1147 | dev_priv->cfb_fence == obj_priv->fence_reg && | ||
1148 | dev_priv->cfb_plane == intel_crtc->plane && | ||
1149 | dev_priv->cfb_y == crtc->y) | ||
1150 | return; | ||
1151 | |||
1152 | I915_WRITE(DPFC_CONTROL, dpfc_ctl & ~DPFC_CTL_EN); | ||
1153 | POSTING_READ(DPFC_CONTROL); | ||
1154 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
1155 | } | ||
1156 | |||
1139 | dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; | 1157 | dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; |
1140 | dev_priv->cfb_fence = obj_priv->fence_reg; | 1158 | dev_priv->cfb_fence = obj_priv->fence_reg; |
1141 | dev_priv->cfb_plane = intel_crtc->plane; | 1159 | dev_priv->cfb_plane = intel_crtc->plane; |
1160 | dev_priv->cfb_y = crtc->y; | ||
1142 | 1161 | ||
1143 | dpfc_ctl = plane | DPFC_SR_EN | DPFC_CTL_LIMIT_1X; | 1162 | dpfc_ctl = plane | DPFC_SR_EN | DPFC_CTL_LIMIT_1X; |
1144 | if (obj_priv->tiling_mode != I915_TILING_NONE) { | 1163 | if (obj_priv->tiling_mode != I915_TILING_NONE) { |
@@ -1148,7 +1167,6 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1148 | I915_WRITE(DPFC_CHICKEN, ~DPFC_HT_MODIFY); | 1167 | I915_WRITE(DPFC_CHICKEN, ~DPFC_HT_MODIFY); |
1149 | } | 1168 | } |
1150 | 1169 | ||
1151 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); | ||
1152 | I915_WRITE(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | | 1170 | I915_WRITE(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | |
1153 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | | 1171 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | |
1154 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); | 1172 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); |
@@ -1167,10 +1185,12 @@ void g4x_disable_fbc(struct drm_device *dev) | |||
1167 | 1185 | ||
1168 | /* Disable compression */ | 1186 | /* Disable compression */ |
1169 | dpfc_ctl = I915_READ(DPFC_CONTROL); | 1187 | dpfc_ctl = I915_READ(DPFC_CONTROL); |
1170 | dpfc_ctl &= ~DPFC_CTL_EN; | 1188 | if (dpfc_ctl & DPFC_CTL_EN) { |
1171 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); | 1189 | dpfc_ctl &= ~DPFC_CTL_EN; |
1190 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); | ||
1172 | 1191 | ||
1173 | DRM_DEBUG_KMS("disabled FBC\n"); | 1192 | DRM_DEBUG_KMS("disabled FBC\n"); |
1193 | } | ||
1174 | } | 1194 | } |
1175 | 1195 | ||
1176 | static bool g4x_fbc_enabled(struct drm_device *dev) | 1196 | static bool g4x_fbc_enabled(struct drm_device *dev) |
@@ -1188,16 +1208,30 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1188 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | 1208 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
1189 | struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); | 1209 | struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); |
1190 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1210 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1191 | int plane = (intel_crtc->plane == 0) ? DPFC_CTL_PLANEA : | 1211 | int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; |
1192 | DPFC_CTL_PLANEB; | ||
1193 | unsigned long stall_watermark = 200; | 1212 | unsigned long stall_watermark = 200; |
1194 | u32 dpfc_ctl; | 1213 | u32 dpfc_ctl; |
1195 | 1214 | ||
1215 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | ||
1216 | if (dpfc_ctl & DPFC_CTL_EN) { | ||
1217 | if (dev_priv->cfb_pitch == dev_priv->cfb_pitch / 64 - 1 && | ||
1218 | dev_priv->cfb_fence == obj_priv->fence_reg && | ||
1219 | dev_priv->cfb_plane == intel_crtc->plane && | ||
1220 | dev_priv->cfb_offset == obj_priv->gtt_offset && | ||
1221 | dev_priv->cfb_y == crtc->y) | ||
1222 | return; | ||
1223 | |||
1224 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl & ~DPFC_CTL_EN); | ||
1225 | POSTING_READ(ILK_DPFC_CONTROL); | ||
1226 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
1227 | } | ||
1228 | |||
1196 | dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; | 1229 | dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; |
1197 | dev_priv->cfb_fence = obj_priv->fence_reg; | 1230 | dev_priv->cfb_fence = obj_priv->fence_reg; |
1198 | dev_priv->cfb_plane = intel_crtc->plane; | 1231 | dev_priv->cfb_plane = intel_crtc->plane; |
1232 | dev_priv->cfb_offset = obj_priv->gtt_offset; | ||
1233 | dev_priv->cfb_y = crtc->y; | ||
1199 | 1234 | ||
1200 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | ||
1201 | dpfc_ctl &= DPFC_RESERVED; | 1235 | dpfc_ctl &= DPFC_RESERVED; |
1202 | dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X); | 1236 | dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X); |
1203 | if (obj_priv->tiling_mode != I915_TILING_NONE) { | 1237 | if (obj_priv->tiling_mode != I915_TILING_NONE) { |
@@ -1207,15 +1241,13 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1207 | I915_WRITE(ILK_DPFC_CHICKEN, ~DPFC_HT_MODIFY); | 1241 | I915_WRITE(ILK_DPFC_CHICKEN, ~DPFC_HT_MODIFY); |
1208 | } | 1242 | } |
1209 | 1243 | ||
1210 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); | ||
1211 | I915_WRITE(ILK_DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | | 1244 | I915_WRITE(ILK_DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | |
1212 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | | 1245 | (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | |
1213 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); | 1246 | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); |
1214 | I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); | 1247 | I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); |
1215 | I915_WRITE(ILK_FBC_RT_BASE, obj_priv->gtt_offset | ILK_FBC_RT_VALID); | 1248 | I915_WRITE(ILK_FBC_RT_BASE, obj_priv->gtt_offset | ILK_FBC_RT_VALID); |
1216 | /* enable it... */ | 1249 | /* enable it... */ |
1217 | I915_WRITE(ILK_DPFC_CONTROL, I915_READ(ILK_DPFC_CONTROL) | | 1250 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); |
1218 | DPFC_CTL_EN); | ||
1219 | 1251 | ||
1220 | DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); | 1252 | DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); |
1221 | } | 1253 | } |
@@ -1227,10 +1259,12 @@ void ironlake_disable_fbc(struct drm_device *dev) | |||
1227 | 1259 | ||
1228 | /* Disable compression */ | 1260 | /* Disable compression */ |
1229 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | 1261 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); |
1230 | dpfc_ctl &= ~DPFC_CTL_EN; | 1262 | if (dpfc_ctl & DPFC_CTL_EN) { |
1231 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); | 1263 | dpfc_ctl &= ~DPFC_CTL_EN; |
1264 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); | ||
1232 | 1265 | ||
1233 | DRM_DEBUG_KMS("disabled FBC\n"); | 1266 | DRM_DEBUG_KMS("disabled FBC\n"); |
1267 | } | ||
1234 | } | 1268 | } |
1235 | 1269 | ||
1236 | static bool ironlake_fbc_enabled(struct drm_device *dev) | 1270 | static bool ironlake_fbc_enabled(struct drm_device *dev) |
@@ -1272,8 +1306,7 @@ void intel_disable_fbc(struct drm_device *dev) | |||
1272 | 1306 | ||
1273 | /** | 1307 | /** |
1274 | * intel_update_fbc - enable/disable FBC as needed | 1308 | * intel_update_fbc - enable/disable FBC as needed |
1275 | * @crtc: CRTC to point the compressor at | 1309 | * @dev: the drm_device |
1276 | * @mode: mode in use | ||
1277 | * | 1310 | * |
1278 | * Set up the framebuffer compression hardware at mode set time. We | 1311 | * Set up the framebuffer compression hardware at mode set time. We |
1279 | * enable it if possible: | 1312 | * enable it if possible: |
@@ -1290,18 +1323,14 @@ void intel_disable_fbc(struct drm_device *dev) | |||
1290 | * | 1323 | * |
1291 | * We need to enable/disable FBC on a global basis. | 1324 | * We need to enable/disable FBC on a global basis. |
1292 | */ | 1325 | */ |
1293 | static void intel_update_fbc(struct drm_crtc *crtc, | 1326 | static void intel_update_fbc(struct drm_device *dev) |
1294 | struct drm_display_mode *mode) | ||
1295 | { | 1327 | { |
1296 | struct drm_device *dev = crtc->dev; | ||
1297 | struct drm_i915_private *dev_priv = dev->dev_private; | 1328 | struct drm_i915_private *dev_priv = dev->dev_private; |
1298 | struct drm_framebuffer *fb = crtc->fb; | 1329 | struct drm_crtc *crtc = NULL, *tmp_crtc; |
1330 | struct intel_crtc *intel_crtc; | ||
1331 | struct drm_framebuffer *fb; | ||
1299 | struct intel_framebuffer *intel_fb; | 1332 | struct intel_framebuffer *intel_fb; |
1300 | struct drm_i915_gem_object *obj_priv; | 1333 | struct drm_i915_gem_object *obj_priv; |
1301 | struct drm_crtc *tmp_crtc; | ||
1302 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
1303 | int plane = intel_crtc->plane; | ||
1304 | int crtcs_enabled = 0; | ||
1305 | 1334 | ||
1306 | DRM_DEBUG_KMS("\n"); | 1335 | DRM_DEBUG_KMS("\n"); |
1307 | 1336 | ||
@@ -1311,12 +1340,6 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1311 | if (!I915_HAS_FBC(dev)) | 1340 | if (!I915_HAS_FBC(dev)) |
1312 | return; | 1341 | return; |
1313 | 1342 | ||
1314 | if (!crtc->fb) | ||
1315 | return; | ||
1316 | |||
1317 | intel_fb = to_intel_framebuffer(fb); | ||
1318 | obj_priv = to_intel_bo(intel_fb->obj); | ||
1319 | |||
1320 | /* | 1343 | /* |
1321 | * If FBC is already on, we just have to verify that we can | 1344 | * If FBC is already on, we just have to verify that we can |
1322 | * keep it that way... | 1345 | * keep it that way... |
@@ -1327,35 +1350,47 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1327 | * - going to an unsupported config (interlace, pixel multiply, etc.) | 1350 | * - going to an unsupported config (interlace, pixel multiply, etc.) |
1328 | */ | 1351 | */ |
1329 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { | 1352 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { |
1330 | if (tmp_crtc->enabled) | 1353 | if (tmp_crtc->enabled) { |
1331 | crtcs_enabled++; | 1354 | if (crtc) { |
1355 | DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); | ||
1356 | dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; | ||
1357 | goto out_disable; | ||
1358 | } | ||
1359 | crtc = tmp_crtc; | ||
1360 | } | ||
1332 | } | 1361 | } |
1333 | DRM_DEBUG_KMS("%d pipes active\n", crtcs_enabled); | 1362 | |
1334 | if (crtcs_enabled > 1) { | 1363 | if (!crtc || crtc->fb == NULL) { |
1335 | DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); | 1364 | DRM_DEBUG_KMS("no output, disabling\n"); |
1336 | dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; | 1365 | dev_priv->no_fbc_reason = FBC_NO_OUTPUT; |
1337 | goto out_disable; | 1366 | goto out_disable; |
1338 | } | 1367 | } |
1368 | |||
1369 | intel_crtc = to_intel_crtc(crtc); | ||
1370 | fb = crtc->fb; | ||
1371 | intel_fb = to_intel_framebuffer(fb); | ||
1372 | obj_priv = to_intel_bo(intel_fb->obj); | ||
1373 | |||
1339 | if (intel_fb->obj->size > dev_priv->cfb_size) { | 1374 | if (intel_fb->obj->size > dev_priv->cfb_size) { |
1340 | DRM_DEBUG_KMS("framebuffer too large, disabling " | 1375 | DRM_DEBUG_KMS("framebuffer too large, disabling " |
1341 | "compression\n"); | 1376 | "compression\n"); |
1342 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; | 1377 | dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; |
1343 | goto out_disable; | 1378 | goto out_disable; |
1344 | } | 1379 | } |
1345 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) || | 1380 | if ((crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) || |
1346 | (mode->flags & DRM_MODE_FLAG_DBLSCAN)) { | 1381 | (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)) { |
1347 | DRM_DEBUG_KMS("mode incompatible with compression, " | 1382 | DRM_DEBUG_KMS("mode incompatible with compression, " |
1348 | "disabling\n"); | 1383 | "disabling\n"); |
1349 | dev_priv->no_fbc_reason = FBC_UNSUPPORTED_MODE; | 1384 | dev_priv->no_fbc_reason = FBC_UNSUPPORTED_MODE; |
1350 | goto out_disable; | 1385 | goto out_disable; |
1351 | } | 1386 | } |
1352 | if ((mode->hdisplay > 2048) || | 1387 | if ((crtc->mode.hdisplay > 2048) || |
1353 | (mode->vdisplay > 1536)) { | 1388 | (crtc->mode.vdisplay > 1536)) { |
1354 | DRM_DEBUG_KMS("mode too large for compression, disabling\n"); | 1389 | DRM_DEBUG_KMS("mode too large for compression, disabling\n"); |
1355 | dev_priv->no_fbc_reason = FBC_MODE_TOO_LARGE; | 1390 | dev_priv->no_fbc_reason = FBC_MODE_TOO_LARGE; |
1356 | goto out_disable; | 1391 | goto out_disable; |
1357 | } | 1392 | } |
1358 | if ((IS_I915GM(dev) || IS_I945GM(dev)) && plane != 0) { | 1393 | if ((IS_I915GM(dev) || IS_I945GM(dev)) && intel_crtc->plane != 0) { |
1359 | DRM_DEBUG_KMS("plane not 0, disabling compression\n"); | 1394 | DRM_DEBUG_KMS("plane not 0, disabling compression\n"); |
1360 | dev_priv->no_fbc_reason = FBC_BAD_PLANE; | 1395 | dev_priv->no_fbc_reason = FBC_BAD_PLANE; |
1361 | goto out_disable; | 1396 | goto out_disable; |
@@ -1370,18 +1405,7 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1370 | if (in_dbg_master()) | 1405 | if (in_dbg_master()) |
1371 | goto out_disable; | 1406 | goto out_disable; |
1372 | 1407 | ||
1373 | if (intel_fbc_enabled(dev)) { | 1408 | intel_enable_fbc(crtc, 500); |
1374 | /* We can re-enable it in this case, but need to update pitch */ | ||
1375 | if ((fb->pitch > dev_priv->cfb_pitch) || | ||
1376 | (obj_priv->fence_reg != dev_priv->cfb_fence) || | ||
1377 | (plane != dev_priv->cfb_plane)) | ||
1378 | intel_disable_fbc(dev); | ||
1379 | } | ||
1380 | |||
1381 | /* Now try to turn it back on if possible */ | ||
1382 | if (!intel_fbc_enabled(dev)) | ||
1383 | intel_enable_fbc(crtc, 500); | ||
1384 | |||
1385 | return; | 1409 | return; |
1386 | 1410 | ||
1387 | out_disable: | 1411 | out_disable: |
@@ -1393,7 +1417,9 @@ out_disable: | |||
1393 | } | 1417 | } |
1394 | 1418 | ||
1395 | int | 1419 | int |
1396 | intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) | 1420 | intel_pin_and_fence_fb_obj(struct drm_device *dev, |
1421 | struct drm_gem_object *obj, | ||
1422 | bool pipelined) | ||
1397 | { | 1423 | { |
1398 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1424 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1399 | u32 alignment; | 1425 | u32 alignment; |
@@ -1421,9 +1447,13 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) | |||
1421 | } | 1447 | } |
1422 | 1448 | ||
1423 | ret = i915_gem_object_pin(obj, alignment); | 1449 | ret = i915_gem_object_pin(obj, alignment); |
1424 | if (ret != 0) | 1450 | if (ret) |
1425 | return ret; | 1451 | return ret; |
1426 | 1452 | ||
1453 | ret = i915_gem_object_set_to_display_plane(obj, pipelined); | ||
1454 | if (ret) | ||
1455 | goto err_unpin; | ||
1456 | |||
1427 | /* Install a fence for tiled scan-out. Pre-i965 always needs a | 1457 | /* Install a fence for tiled scan-out. Pre-i965 always needs a |
1428 | * fence, whereas 965+ only requires a fence if using | 1458 | * fence, whereas 965+ only requires a fence if using |
1429 | * framebuffer compression. For simplicity, we always install | 1459 | * framebuffer compression. For simplicity, we always install |
@@ -1431,14 +1461,16 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) | |||
1431 | */ | 1461 | */ |
1432 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE && | 1462 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE && |
1433 | obj_priv->tiling_mode != I915_TILING_NONE) { | 1463 | obj_priv->tiling_mode != I915_TILING_NONE) { |
1434 | ret = i915_gem_object_get_fence_reg(obj); | 1464 | ret = i915_gem_object_get_fence_reg(obj, false); |
1435 | if (ret != 0) { | 1465 | if (ret) |
1436 | i915_gem_object_unpin(obj); | 1466 | goto err_unpin; |
1437 | return ret; | ||
1438 | } | ||
1439 | } | 1467 | } |
1440 | 1468 | ||
1441 | return 0; | 1469 | return 0; |
1470 | |||
1471 | err_unpin: | ||
1472 | i915_gem_object_unpin(obj); | ||
1473 | return ret; | ||
1442 | } | 1474 | } |
1443 | 1475 | ||
1444 | /* Assume fb object is pinned & idle & fenced and just update base pointers */ | 1476 | /* Assume fb object is pinned & idle & fenced and just update base pointers */ |
@@ -1454,12 +1486,8 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1454 | struct drm_gem_object *obj; | 1486 | struct drm_gem_object *obj; |
1455 | int plane = intel_crtc->plane; | 1487 | int plane = intel_crtc->plane; |
1456 | unsigned long Start, Offset; | 1488 | unsigned long Start, Offset; |
1457 | int dspbase = (plane == 0 ? DSPAADDR : DSPBADDR); | ||
1458 | int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF); | ||
1459 | int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE; | ||
1460 | int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF); | ||
1461 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; | ||
1462 | u32 dspcntr; | 1489 | u32 dspcntr; |
1490 | u32 reg; | ||
1463 | 1491 | ||
1464 | switch (plane) { | 1492 | switch (plane) { |
1465 | case 0: | 1493 | case 0: |
@@ -1474,7 +1502,8 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1474 | obj = intel_fb->obj; | 1502 | obj = intel_fb->obj; |
1475 | obj_priv = to_intel_bo(obj); | 1503 | obj_priv = to_intel_bo(obj); |
1476 | 1504 | ||
1477 | dspcntr = I915_READ(dspcntr_reg); | 1505 | reg = DSPCNTR(plane); |
1506 | dspcntr = I915_READ(reg); | ||
1478 | /* Mask out pixel format bits in case we change it */ | 1507 | /* Mask out pixel format bits in case we change it */ |
1479 | dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; | 1508 | dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; |
1480 | switch (fb->bits_per_pixel) { | 1509 | switch (fb->bits_per_pixel) { |
@@ -1506,28 +1535,24 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1506 | /* must disable */ | 1535 | /* must disable */ |
1507 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; | 1536 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; |
1508 | 1537 | ||
1509 | I915_WRITE(dspcntr_reg, dspcntr); | 1538 | I915_WRITE(reg, dspcntr); |
1510 | 1539 | ||
1511 | Start = obj_priv->gtt_offset; | 1540 | Start = obj_priv->gtt_offset; |
1512 | Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8); | 1541 | Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8); |
1513 | 1542 | ||
1514 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", | 1543 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", |
1515 | Start, Offset, x, y, fb->pitch); | 1544 | Start, Offset, x, y, fb->pitch); |
1516 | I915_WRITE(dspstride, fb->pitch); | 1545 | I915_WRITE(DSPSTRIDE(plane), fb->pitch); |
1517 | if (IS_I965G(dev)) { | 1546 | if (IS_I965G(dev)) { |
1518 | I915_WRITE(dspsurf, Start); | 1547 | I915_WRITE(DSPSURF(plane), Start); |
1519 | I915_WRITE(dsptileoff, (y << 16) | x); | 1548 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); |
1520 | I915_WRITE(dspbase, Offset); | 1549 | I915_WRITE(DSPADDR(plane), Offset); |
1521 | } else { | 1550 | } else |
1522 | I915_WRITE(dspbase, Start + Offset); | 1551 | I915_WRITE(DSPADDR(plane), Start + Offset); |
1523 | } | 1552 | POSTING_READ(reg); |
1524 | POSTING_READ(dspbase); | ||
1525 | |||
1526 | if (IS_I965G(dev) || plane == 0) | ||
1527 | intel_update_fbc(crtc, &crtc->mode); | ||
1528 | 1553 | ||
1529 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1554 | intel_update_fbc(dev); |
1530 | intel_increase_pllclock(crtc, true); | 1555 | intel_increase_pllclock(crtc); |
1531 | 1556 | ||
1532 | return 0; | 1557 | return 0; |
1533 | } | 1558 | } |
@@ -1566,19 +1591,12 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1566 | obj_priv = to_intel_bo(obj); | 1591 | obj_priv = to_intel_bo(obj); |
1567 | 1592 | ||
1568 | mutex_lock(&dev->struct_mutex); | 1593 | mutex_lock(&dev->struct_mutex); |
1569 | ret = intel_pin_and_fence_fb_obj(dev, obj); | 1594 | ret = intel_pin_and_fence_fb_obj(dev, obj, false); |
1570 | if (ret != 0) { | 1595 | if (ret != 0) { |
1571 | mutex_unlock(&dev->struct_mutex); | 1596 | mutex_unlock(&dev->struct_mutex); |
1572 | return ret; | 1597 | return ret; |
1573 | } | 1598 | } |
1574 | 1599 | ||
1575 | ret = i915_gem_object_set_to_display_plane(obj); | ||
1576 | if (ret != 0) { | ||
1577 | i915_gem_object_unpin(obj); | ||
1578 | mutex_unlock(&dev->struct_mutex); | ||
1579 | return ret; | ||
1580 | } | ||
1581 | |||
1582 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y); | 1600 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y); |
1583 | if (ret) { | 1601 | if (ret) { |
1584 | i915_gem_object_unpin(obj); | 1602 | i915_gem_object_unpin(obj); |
@@ -1612,7 +1630,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1612 | return 0; | 1630 | return 0; |
1613 | } | 1631 | } |
1614 | 1632 | ||
1615 | static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) | 1633 | static void ironlake_set_pll_edp(struct drm_crtc *crtc, int clock) |
1616 | { | 1634 | { |
1617 | struct drm_device *dev = crtc->dev; | 1635 | struct drm_device *dev = crtc->dev; |
1618 | struct drm_i915_private *dev_priv = dev->dev_private; | 1636 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -1645,6 +1663,7 @@ static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) | |||
1645 | } | 1663 | } |
1646 | I915_WRITE(DP_A, dpa_ctl); | 1664 | I915_WRITE(DP_A, dpa_ctl); |
1647 | 1665 | ||
1666 | POSTING_READ(DP_A); | ||
1648 | udelay(500); | 1667 | udelay(500); |
1649 | } | 1668 | } |
1650 | 1669 | ||
@@ -1655,84 +1674,84 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) | |||
1655 | struct drm_i915_private *dev_priv = dev->dev_private; | 1674 | struct drm_i915_private *dev_priv = dev->dev_private; |
1656 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1675 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1657 | int pipe = intel_crtc->pipe; | 1676 | int pipe = intel_crtc->pipe; |
1658 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; | 1677 | u32 reg, temp, tries; |
1659 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; | ||
1660 | int fdi_rx_iir_reg = (pipe == 0) ? FDI_RXA_IIR : FDI_RXB_IIR; | ||
1661 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; | ||
1662 | u32 temp, tries = 0; | ||
1663 | 1678 | ||
1664 | /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit | 1679 | /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit |
1665 | for train result */ | 1680 | for train result */ |
1666 | temp = I915_READ(fdi_rx_imr_reg); | 1681 | reg = FDI_RX_IMR(pipe); |
1682 | temp = I915_READ(reg); | ||
1667 | temp &= ~FDI_RX_SYMBOL_LOCK; | 1683 | temp &= ~FDI_RX_SYMBOL_LOCK; |
1668 | temp &= ~FDI_RX_BIT_LOCK; | 1684 | temp &= ~FDI_RX_BIT_LOCK; |
1669 | I915_WRITE(fdi_rx_imr_reg, temp); | 1685 | I915_WRITE(reg, temp); |
1670 | I915_READ(fdi_rx_imr_reg); | 1686 | I915_READ(reg); |
1671 | udelay(150); | 1687 | udelay(150); |
1672 | 1688 | ||
1673 | /* enable CPU FDI TX and PCH FDI RX */ | 1689 | /* enable CPU FDI TX and PCH FDI RX */ |
1674 | temp = I915_READ(fdi_tx_reg); | 1690 | reg = FDI_TX_CTL(pipe); |
1675 | temp |= FDI_TX_ENABLE; | 1691 | temp = I915_READ(reg); |
1676 | temp &= ~(7 << 19); | 1692 | temp &= ~(7 << 19); |
1677 | temp |= (intel_crtc->fdi_lanes - 1) << 19; | 1693 | temp |= (intel_crtc->fdi_lanes - 1) << 19; |
1678 | temp &= ~FDI_LINK_TRAIN_NONE; | 1694 | temp &= ~FDI_LINK_TRAIN_NONE; |
1679 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1695 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1680 | I915_WRITE(fdi_tx_reg, temp); | 1696 | I915_WRITE(reg, temp | FDI_TX_ENABLE); |
1681 | I915_READ(fdi_tx_reg); | ||
1682 | 1697 | ||
1683 | temp = I915_READ(fdi_rx_reg); | 1698 | reg = FDI_RX_CTL(pipe); |
1699 | temp = I915_READ(reg); | ||
1684 | temp &= ~FDI_LINK_TRAIN_NONE; | 1700 | temp &= ~FDI_LINK_TRAIN_NONE; |
1685 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1701 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1686 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); | 1702 | I915_WRITE(reg, temp | FDI_RX_ENABLE); |
1687 | I915_READ(fdi_rx_reg); | 1703 | |
1704 | POSTING_READ(reg); | ||
1688 | udelay(150); | 1705 | udelay(150); |
1689 | 1706 | ||
1707 | reg = FDI_RX_IIR(pipe); | ||
1690 | for (tries = 0; tries < 5; tries++) { | 1708 | for (tries = 0; tries < 5; tries++) { |
1691 | temp = I915_READ(fdi_rx_iir_reg); | 1709 | temp = I915_READ(reg); |
1692 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); | 1710 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); |
1693 | 1711 | ||
1694 | if ((temp & FDI_RX_BIT_LOCK)) { | 1712 | if ((temp & FDI_RX_BIT_LOCK)) { |
1695 | DRM_DEBUG_KMS("FDI train 1 done.\n"); | 1713 | DRM_DEBUG_KMS("FDI train 1 done.\n"); |
1696 | I915_WRITE(fdi_rx_iir_reg, | 1714 | I915_WRITE(reg, temp | FDI_RX_BIT_LOCK); |
1697 | temp | FDI_RX_BIT_LOCK); | ||
1698 | break; | 1715 | break; |
1699 | } | 1716 | } |
1700 | } | 1717 | } |
1701 | if (tries == 5) | 1718 | if (tries == 5) |
1702 | DRM_DEBUG_KMS("FDI train 1 fail!\n"); | 1719 | DRM_ERROR("FDI train 1 fail!\n"); |
1703 | 1720 | ||
1704 | /* Train 2 */ | 1721 | /* Train 2 */ |
1705 | temp = I915_READ(fdi_tx_reg); | 1722 | reg = FDI_TX_CTL(pipe); |
1723 | temp = I915_READ(reg); | ||
1706 | temp &= ~FDI_LINK_TRAIN_NONE; | 1724 | temp &= ~FDI_LINK_TRAIN_NONE; |
1707 | temp |= FDI_LINK_TRAIN_PATTERN_2; | 1725 | temp |= FDI_LINK_TRAIN_PATTERN_2; |
1708 | I915_WRITE(fdi_tx_reg, temp); | 1726 | I915_WRITE(reg, temp); |
1709 | 1727 | ||
1710 | temp = I915_READ(fdi_rx_reg); | 1728 | reg = FDI_RX_CTL(pipe); |
1729 | temp = I915_READ(reg); | ||
1711 | temp &= ~FDI_LINK_TRAIN_NONE; | 1730 | temp &= ~FDI_LINK_TRAIN_NONE; |
1712 | temp |= FDI_LINK_TRAIN_PATTERN_2; | 1731 | temp |= FDI_LINK_TRAIN_PATTERN_2; |
1713 | I915_WRITE(fdi_rx_reg, temp); | 1732 | I915_WRITE(reg, temp); |
1714 | udelay(150); | ||
1715 | 1733 | ||
1716 | tries = 0; | 1734 | POSTING_READ(reg); |
1735 | udelay(150); | ||
1717 | 1736 | ||
1737 | reg = FDI_RX_IIR(pipe); | ||
1718 | for (tries = 0; tries < 5; tries++) { | 1738 | for (tries = 0; tries < 5; tries++) { |
1719 | temp = I915_READ(fdi_rx_iir_reg); | 1739 | temp = I915_READ(reg); |
1720 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); | 1740 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); |
1721 | 1741 | ||
1722 | if (temp & FDI_RX_SYMBOL_LOCK) { | 1742 | if (temp & FDI_RX_SYMBOL_LOCK) { |
1723 | I915_WRITE(fdi_rx_iir_reg, | 1743 | I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK); |
1724 | temp | FDI_RX_SYMBOL_LOCK); | ||
1725 | DRM_DEBUG_KMS("FDI train 2 done.\n"); | 1744 | DRM_DEBUG_KMS("FDI train 2 done.\n"); |
1726 | break; | 1745 | break; |
1727 | } | 1746 | } |
1728 | } | 1747 | } |
1729 | if (tries == 5) | 1748 | if (tries == 5) |
1730 | DRM_DEBUG_KMS("FDI train 2 fail!\n"); | 1749 | DRM_ERROR("FDI train 2 fail!\n"); |
1731 | 1750 | ||
1732 | DRM_DEBUG_KMS("FDI train done\n"); | 1751 | DRM_DEBUG_KMS("FDI train done\n"); |
1733 | } | 1752 | } |
1734 | 1753 | ||
1735 | static int snb_b_fdi_train_param [] = { | 1754 | static const int const snb_b_fdi_train_param [] = { |
1736 | FDI_LINK_TRAIN_400MV_0DB_SNB_B, | 1755 | FDI_LINK_TRAIN_400MV_0DB_SNB_B, |
1737 | FDI_LINK_TRAIN_400MV_6DB_SNB_B, | 1756 | FDI_LINK_TRAIN_400MV_6DB_SNB_B, |
1738 | FDI_LINK_TRAIN_600MV_3_5DB_SNB_B, | 1757 | FDI_LINK_TRAIN_600MV_3_5DB_SNB_B, |
@@ -1746,24 +1765,22 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) | |||
1746 | struct drm_i915_private *dev_priv = dev->dev_private; | 1765 | struct drm_i915_private *dev_priv = dev->dev_private; |
1747 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1766 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1748 | int pipe = intel_crtc->pipe; | 1767 | int pipe = intel_crtc->pipe; |
1749 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; | 1768 | u32 reg, temp, i; |
1750 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; | ||
1751 | int fdi_rx_iir_reg = (pipe == 0) ? FDI_RXA_IIR : FDI_RXB_IIR; | ||
1752 | int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; | ||
1753 | u32 temp, i; | ||
1754 | 1769 | ||
1755 | /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit | 1770 | /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit |
1756 | for train result */ | 1771 | for train result */ |
1757 | temp = I915_READ(fdi_rx_imr_reg); | 1772 | reg = FDI_RX_IMR(pipe); |
1773 | temp = I915_READ(reg); | ||
1758 | temp &= ~FDI_RX_SYMBOL_LOCK; | 1774 | temp &= ~FDI_RX_SYMBOL_LOCK; |
1759 | temp &= ~FDI_RX_BIT_LOCK; | 1775 | temp &= ~FDI_RX_BIT_LOCK; |
1760 | I915_WRITE(fdi_rx_imr_reg, temp); | 1776 | I915_WRITE(reg, temp); |
1761 | I915_READ(fdi_rx_imr_reg); | 1777 | |
1778 | POSTING_READ(reg); | ||
1762 | udelay(150); | 1779 | udelay(150); |
1763 | 1780 | ||
1764 | /* enable CPU FDI TX and PCH FDI RX */ | 1781 | /* enable CPU FDI TX and PCH FDI RX */ |
1765 | temp = I915_READ(fdi_tx_reg); | 1782 | reg = FDI_TX_CTL(pipe); |
1766 | temp |= FDI_TX_ENABLE; | 1783 | temp = I915_READ(reg); |
1767 | temp &= ~(7 << 19); | 1784 | temp &= ~(7 << 19); |
1768 | temp |= (intel_crtc->fdi_lanes - 1) << 19; | 1785 | temp |= (intel_crtc->fdi_lanes - 1) << 19; |
1769 | temp &= ~FDI_LINK_TRAIN_NONE; | 1786 | temp &= ~FDI_LINK_TRAIN_NONE; |
@@ -1771,10 +1788,10 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) | |||
1771 | temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; | 1788 | temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; |
1772 | /* SNB-B */ | 1789 | /* SNB-B */ |
1773 | temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; | 1790 | temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; |
1774 | I915_WRITE(fdi_tx_reg, temp); | 1791 | I915_WRITE(reg, temp | FDI_TX_ENABLE); |
1775 | I915_READ(fdi_tx_reg); | ||
1776 | 1792 | ||
1777 | temp = I915_READ(fdi_rx_reg); | 1793 | reg = FDI_RX_CTL(pipe); |
1794 | temp = I915_READ(reg); | ||
1778 | if (HAS_PCH_CPT(dev)) { | 1795 | if (HAS_PCH_CPT(dev)) { |
1779 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; | 1796 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; |
1780 | temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; | 1797 | temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; |
@@ -1782,32 +1799,37 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) | |||
1782 | temp &= ~FDI_LINK_TRAIN_NONE; | 1799 | temp &= ~FDI_LINK_TRAIN_NONE; |
1783 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 1800 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
1784 | } | 1801 | } |
1785 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENABLE); | 1802 | I915_WRITE(reg, temp | FDI_RX_ENABLE); |
1786 | I915_READ(fdi_rx_reg); | 1803 | |
1804 | POSTING_READ(reg); | ||
1787 | udelay(150); | 1805 | udelay(150); |
1788 | 1806 | ||
1789 | for (i = 0; i < 4; i++ ) { | 1807 | for (i = 0; i < 4; i++ ) { |
1790 | temp = I915_READ(fdi_tx_reg); | 1808 | reg = FDI_TX_CTL(pipe); |
1809 | temp = I915_READ(reg); | ||
1791 | temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; | 1810 | temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; |
1792 | temp |= snb_b_fdi_train_param[i]; | 1811 | temp |= snb_b_fdi_train_param[i]; |
1793 | I915_WRITE(fdi_tx_reg, temp); | 1812 | I915_WRITE(reg, temp); |
1813 | |||
1814 | POSTING_READ(reg); | ||
1794 | udelay(500); | 1815 | udelay(500); |
1795 | 1816 | ||
1796 | temp = I915_READ(fdi_rx_iir_reg); | 1817 | reg = FDI_RX_IIR(pipe); |
1818 | temp = I915_READ(reg); | ||
1797 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); | 1819 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); |
1798 | 1820 | ||
1799 | if (temp & FDI_RX_BIT_LOCK) { | 1821 | if (temp & FDI_RX_BIT_LOCK) { |
1800 | I915_WRITE(fdi_rx_iir_reg, | 1822 | I915_WRITE(reg, temp | FDI_RX_BIT_LOCK); |
1801 | temp | FDI_RX_BIT_LOCK); | ||
1802 | DRM_DEBUG_KMS("FDI train 1 done.\n"); | 1823 | DRM_DEBUG_KMS("FDI train 1 done.\n"); |
1803 | break; | 1824 | break; |
1804 | } | 1825 | } |
1805 | } | 1826 | } |
1806 | if (i == 4) | 1827 | if (i == 4) |
1807 | DRM_DEBUG_KMS("FDI train 1 fail!\n"); | 1828 | DRM_ERROR("FDI train 1 fail!\n"); |
1808 | 1829 | ||
1809 | /* Train 2 */ | 1830 | /* Train 2 */ |
1810 | temp = I915_READ(fdi_tx_reg); | 1831 | reg = FDI_TX_CTL(pipe); |
1832 | temp = I915_READ(reg); | ||
1811 | temp &= ~FDI_LINK_TRAIN_NONE; | 1833 | temp &= ~FDI_LINK_TRAIN_NONE; |
1812 | temp |= FDI_LINK_TRAIN_PATTERN_2; | 1834 | temp |= FDI_LINK_TRAIN_PATTERN_2; |
1813 | if (IS_GEN6(dev)) { | 1835 | if (IS_GEN6(dev)) { |
@@ -1815,9 +1837,10 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) | |||
1815 | /* SNB-B */ | 1837 | /* SNB-B */ |
1816 | temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; | 1838 | temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; |
1817 | } | 1839 | } |
1818 | I915_WRITE(fdi_tx_reg, temp); | 1840 | I915_WRITE(reg, temp); |
1819 | 1841 | ||
1820 | temp = I915_READ(fdi_rx_reg); | 1842 | reg = FDI_RX_CTL(pipe); |
1843 | temp = I915_READ(reg); | ||
1821 | if (HAS_PCH_CPT(dev)) { | 1844 | if (HAS_PCH_CPT(dev)) { |
1822 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; | 1845 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; |
1823 | temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; | 1846 | temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; |
@@ -1825,535 +1848,595 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) | |||
1825 | temp &= ~FDI_LINK_TRAIN_NONE; | 1848 | temp &= ~FDI_LINK_TRAIN_NONE; |
1826 | temp |= FDI_LINK_TRAIN_PATTERN_2; | 1849 | temp |= FDI_LINK_TRAIN_PATTERN_2; |
1827 | } | 1850 | } |
1828 | I915_WRITE(fdi_rx_reg, temp); | 1851 | I915_WRITE(reg, temp); |
1852 | |||
1853 | POSTING_READ(reg); | ||
1829 | udelay(150); | 1854 | udelay(150); |
1830 | 1855 | ||
1831 | for (i = 0; i < 4; i++ ) { | 1856 | for (i = 0; i < 4; i++ ) { |
1832 | temp = I915_READ(fdi_tx_reg); | 1857 | reg = FDI_TX_CTL(pipe); |
1858 | temp = I915_READ(reg); | ||
1833 | temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; | 1859 | temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; |
1834 | temp |= snb_b_fdi_train_param[i]; | 1860 | temp |= snb_b_fdi_train_param[i]; |
1835 | I915_WRITE(fdi_tx_reg, temp); | 1861 | I915_WRITE(reg, temp); |
1862 | |||
1863 | POSTING_READ(reg); | ||
1836 | udelay(500); | 1864 | udelay(500); |
1837 | 1865 | ||
1838 | temp = I915_READ(fdi_rx_iir_reg); | 1866 | reg = FDI_RX_IIR(pipe); |
1867 | temp = I915_READ(reg); | ||
1839 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); | 1868 | DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); |
1840 | 1869 | ||
1841 | if (temp & FDI_RX_SYMBOL_LOCK) { | 1870 | if (temp & FDI_RX_SYMBOL_LOCK) { |
1842 | I915_WRITE(fdi_rx_iir_reg, | 1871 | I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK); |
1843 | temp | FDI_RX_SYMBOL_LOCK); | ||
1844 | DRM_DEBUG_KMS("FDI train 2 done.\n"); | 1872 | DRM_DEBUG_KMS("FDI train 2 done.\n"); |
1845 | break; | 1873 | break; |
1846 | } | 1874 | } |
1847 | } | 1875 | } |
1848 | if (i == 4) | 1876 | if (i == 4) |
1849 | DRM_DEBUG_KMS("FDI train 2 fail!\n"); | 1877 | DRM_ERROR("FDI train 2 fail!\n"); |
1850 | 1878 | ||
1851 | DRM_DEBUG_KMS("FDI train done.\n"); | 1879 | DRM_DEBUG_KMS("FDI train done.\n"); |
1852 | } | 1880 | } |
1853 | 1881 | ||
1854 | static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | 1882 | static void ironlake_fdi_enable(struct drm_crtc *crtc) |
1855 | { | 1883 | { |
1856 | struct drm_device *dev = crtc->dev; | 1884 | struct drm_device *dev = crtc->dev; |
1857 | struct drm_i915_private *dev_priv = dev->dev_private; | 1885 | struct drm_i915_private *dev_priv = dev->dev_private; |
1858 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1886 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1859 | int pipe = intel_crtc->pipe; | 1887 | int pipe = intel_crtc->pipe; |
1860 | int plane = intel_crtc->plane; | 1888 | u32 reg, temp; |
1861 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; | ||
1862 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; | ||
1863 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; | ||
1864 | int dspbase_reg = (plane == 0) ? DSPAADDR : DSPBADDR; | ||
1865 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; | ||
1866 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; | ||
1867 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; | ||
1868 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; | ||
1869 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; | ||
1870 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; | ||
1871 | int cpu_vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; | ||
1872 | int cpu_vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; | ||
1873 | int cpu_vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; | ||
1874 | int trans_htot_reg = (pipe == 0) ? TRANS_HTOTAL_A : TRANS_HTOTAL_B; | ||
1875 | int trans_hblank_reg = (pipe == 0) ? TRANS_HBLANK_A : TRANS_HBLANK_B; | ||
1876 | int trans_hsync_reg = (pipe == 0) ? TRANS_HSYNC_A : TRANS_HSYNC_B; | ||
1877 | int trans_vtot_reg = (pipe == 0) ? TRANS_VTOTAL_A : TRANS_VTOTAL_B; | ||
1878 | int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B; | ||
1879 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; | ||
1880 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; | ||
1881 | u32 temp; | ||
1882 | u32 pipe_bpc; | ||
1883 | |||
1884 | temp = I915_READ(pipeconf_reg); | ||
1885 | pipe_bpc = temp & PIPE_BPC_MASK; | ||
1886 | 1889 | ||
1887 | /* XXX: When our outputs are all unaware of DPMS modes other than off | 1890 | /* Write the TU size bits so error detection works */ |
1888 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. | 1891 | I915_WRITE(FDI_RX_TUSIZE1(pipe), |
1889 | */ | 1892 | I915_READ(PIPE_DATA_M1(pipe)) & TU_SIZE_MASK); |
1890 | switch (mode) { | ||
1891 | case DRM_MODE_DPMS_ON: | ||
1892 | case DRM_MODE_DPMS_STANDBY: | ||
1893 | case DRM_MODE_DPMS_SUSPEND: | ||
1894 | DRM_DEBUG_KMS("crtc %d/%d dpms on\n", pipe, plane); | ||
1895 | 1893 | ||
1896 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 1894 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
1897 | temp = I915_READ(PCH_LVDS); | 1895 | reg = FDI_RX_CTL(pipe); |
1898 | if ((temp & LVDS_PORT_EN) == 0) { | 1896 | temp = I915_READ(reg); |
1899 | I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN); | 1897 | temp &= ~((0x7 << 19) | (0x7 << 16)); |
1900 | POSTING_READ(PCH_LVDS); | 1898 | temp |= (intel_crtc->fdi_lanes - 1) << 19; |
1901 | } | 1899 | temp |= (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) << 11; |
1902 | } | 1900 | I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE); |
1903 | 1901 | ||
1904 | if (!HAS_eDP) { | 1902 | POSTING_READ(reg); |
1903 | udelay(200); | ||
1905 | 1904 | ||
1906 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1905 | /* Switch from Rawclk to PCDclk */ |
1907 | temp = I915_READ(fdi_rx_reg); | 1906 | temp = I915_READ(reg); |
1908 | /* | 1907 | I915_WRITE(reg, temp | FDI_PCDCLK); |
1909 | * make the BPC in FDI Rx be consistent with that in | ||
1910 | * pipeconf reg. | ||
1911 | */ | ||
1912 | temp &= ~(0x7 << 16); | ||
1913 | temp |= (pipe_bpc << 11); | ||
1914 | temp &= ~(7 << 19); | ||
1915 | temp |= (intel_crtc->fdi_lanes - 1) << 19; | ||
1916 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); | ||
1917 | I915_READ(fdi_rx_reg); | ||
1918 | udelay(200); | ||
1919 | 1908 | ||
1920 | /* Switch from Rawclk to PCDclk */ | 1909 | POSTING_READ(reg); |
1921 | temp = I915_READ(fdi_rx_reg); | 1910 | udelay(200); |
1922 | I915_WRITE(fdi_rx_reg, temp | FDI_SEL_PCDCLK); | ||
1923 | I915_READ(fdi_rx_reg); | ||
1924 | udelay(200); | ||
1925 | 1911 | ||
1926 | /* Enable CPU FDI TX PLL, always on for Ironlake */ | 1912 | /* Enable CPU FDI TX PLL, always on for Ironlake */ |
1927 | temp = I915_READ(fdi_tx_reg); | 1913 | reg = FDI_TX_CTL(pipe); |
1928 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { | 1914 | temp = I915_READ(reg); |
1929 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); | 1915 | if ((temp & FDI_TX_PLL_ENABLE) == 0) { |
1930 | I915_READ(fdi_tx_reg); | 1916 | I915_WRITE(reg, temp | FDI_TX_PLL_ENABLE); |
1931 | udelay(100); | ||
1932 | } | ||
1933 | } | ||
1934 | 1917 | ||
1935 | /* Enable panel fitting for LVDS */ | 1918 | POSTING_READ(reg); |
1936 | if (dev_priv->pch_pf_size && | 1919 | udelay(100); |
1937 | (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) | 1920 | } |
1938 | || HAS_eDP || intel_pch_has_edp(crtc))) { | 1921 | } |
1939 | /* Force use of hard-coded filter coefficients | ||
1940 | * as some pre-programmed values are broken, | ||
1941 | * e.g. x201. | ||
1942 | */ | ||
1943 | I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, | ||
1944 | PF_ENABLE | PF_FILTER_MED_3x3); | ||
1945 | I915_WRITE(pipe ? PFB_WIN_POS : PFA_WIN_POS, | ||
1946 | dev_priv->pch_pf_pos); | ||
1947 | I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ, | ||
1948 | dev_priv->pch_pf_size); | ||
1949 | } | ||
1950 | 1922 | ||
1951 | /* Enable CPU pipe */ | 1923 | static void intel_flush_display_plane(struct drm_device *dev, |
1952 | temp = I915_READ(pipeconf_reg); | 1924 | int plane) |
1953 | if ((temp & PIPEACONF_ENABLE) == 0) { | 1925 | { |
1954 | I915_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); | 1926 | struct drm_i915_private *dev_priv = dev->dev_private; |
1955 | I915_READ(pipeconf_reg); | 1927 | u32 reg = DSPADDR(plane); |
1956 | udelay(100); | 1928 | I915_WRITE(reg, I915_READ(reg)); |
1957 | } | 1929 | } |
1958 | 1930 | ||
1959 | /* configure and enable CPU plane */ | 1931 | /* |
1960 | temp = I915_READ(dspcntr_reg); | 1932 | * When we disable a pipe, we need to clear any pending scanline wait events |
1961 | if ((temp & DISPLAY_PLANE_ENABLE) == 0) { | 1933 | * to avoid hanging the ring, which we assume we are waiting on. |
1962 | I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE); | 1934 | */ |
1963 | /* Flush the plane changes */ | 1935 | static void intel_clear_scanline_wait(struct drm_device *dev) |
1964 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); | 1936 | { |
1965 | } | 1937 | struct drm_i915_private *dev_priv = dev->dev_private; |
1938 | u32 tmp; | ||
1966 | 1939 | ||
1967 | if (!HAS_eDP) { | 1940 | if (IS_GEN2(dev)) |
1968 | /* For PCH output, training FDI link */ | 1941 | /* Can't break the hang on i8xx */ |
1969 | if (IS_GEN6(dev)) | 1942 | return; |
1970 | gen6_fdi_link_train(crtc); | ||
1971 | else | ||
1972 | ironlake_fdi_link_train(crtc); | ||
1973 | 1943 | ||
1974 | /* enable PCH DPLL */ | 1944 | tmp = I915_READ(PRB0_CTL); |
1975 | temp = I915_READ(pch_dpll_reg); | 1945 | if (tmp & RING_WAIT) { |
1976 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 1946 | I915_WRITE(PRB0_CTL, tmp); |
1977 | I915_WRITE(pch_dpll_reg, temp | DPLL_VCO_ENABLE); | 1947 | POSTING_READ(PRB0_CTL); |
1978 | I915_READ(pch_dpll_reg); | 1948 | } |
1979 | } | 1949 | } |
1980 | udelay(200); | ||
1981 | 1950 | ||
1982 | if (HAS_PCH_CPT(dev)) { | 1951 | static void ironlake_crtc_enable(struct drm_crtc *crtc) |
1983 | /* Be sure PCH DPLL SEL is set */ | 1952 | { |
1984 | temp = I915_READ(PCH_DPLL_SEL); | 1953 | struct drm_device *dev = crtc->dev; |
1985 | if (trans_dpll_sel == 0 && | 1954 | struct drm_i915_private *dev_priv = dev->dev_private; |
1986 | (temp & TRANSA_DPLL_ENABLE) == 0) | 1955 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1987 | temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL); | 1956 | int pipe = intel_crtc->pipe; |
1988 | else if (trans_dpll_sel == 1 && | 1957 | int plane = intel_crtc->plane; |
1989 | (temp & TRANSB_DPLL_ENABLE) == 0) | 1958 | u32 reg, temp; |
1990 | temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); | ||
1991 | I915_WRITE(PCH_DPLL_SEL, temp); | ||
1992 | I915_READ(PCH_DPLL_SEL); | ||
1993 | } | ||
1994 | 1959 | ||
1995 | /* set transcoder timing */ | 1960 | if (intel_crtc->active) |
1996 | I915_WRITE(trans_htot_reg, I915_READ(cpu_htot_reg)); | 1961 | return; |
1997 | I915_WRITE(trans_hblank_reg, I915_READ(cpu_hblank_reg)); | ||
1998 | I915_WRITE(trans_hsync_reg, I915_READ(cpu_hsync_reg)); | ||
1999 | |||
2000 | I915_WRITE(trans_vtot_reg, I915_READ(cpu_vtot_reg)); | ||
2001 | I915_WRITE(trans_vblank_reg, I915_READ(cpu_vblank_reg)); | ||
2002 | I915_WRITE(trans_vsync_reg, I915_READ(cpu_vsync_reg)); | ||
2003 | |||
2004 | /* enable normal train */ | ||
2005 | temp = I915_READ(fdi_tx_reg); | ||
2006 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
2007 | I915_WRITE(fdi_tx_reg, temp | FDI_LINK_TRAIN_NONE | | ||
2008 | FDI_TX_ENHANCE_FRAME_ENABLE); | ||
2009 | I915_READ(fdi_tx_reg); | ||
2010 | |||
2011 | temp = I915_READ(fdi_rx_reg); | ||
2012 | if (HAS_PCH_CPT(dev)) { | ||
2013 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; | ||
2014 | temp |= FDI_LINK_TRAIN_NORMAL_CPT; | ||
2015 | } else { | ||
2016 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
2017 | temp |= FDI_LINK_TRAIN_NONE; | ||
2018 | } | ||
2019 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); | ||
2020 | I915_READ(fdi_rx_reg); | ||
2021 | 1962 | ||
2022 | /* wait one idle pattern time */ | 1963 | intel_crtc->active = true; |
2023 | udelay(100); | 1964 | intel_update_watermarks(dev); |
2024 | 1965 | ||
2025 | /* For PCH DP, enable TRANS_DP_CTL */ | 1966 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
2026 | if (HAS_PCH_CPT(dev) && | 1967 | temp = I915_READ(PCH_LVDS); |
2027 | intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { | 1968 | if ((temp & LVDS_PORT_EN) == 0) |
2028 | int trans_dp_ctl = (pipe == 0) ? TRANS_DP_CTL_A : TRANS_DP_CTL_B; | 1969 | I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN); |
2029 | int reg; | 1970 | } |
2030 | |||
2031 | reg = I915_READ(trans_dp_ctl); | ||
2032 | reg &= ~(TRANS_DP_PORT_SEL_MASK | | ||
2033 | TRANS_DP_SYNC_MASK); | ||
2034 | reg |= (TRANS_DP_OUTPUT_ENABLE | | ||
2035 | TRANS_DP_ENH_FRAMING); | ||
2036 | |||
2037 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | ||
2038 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; | ||
2039 | if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) | ||
2040 | reg |= TRANS_DP_VSYNC_ACTIVE_HIGH; | ||
2041 | |||
2042 | switch (intel_trans_dp_port_sel(crtc)) { | ||
2043 | case PCH_DP_B: | ||
2044 | reg |= TRANS_DP_PORT_SEL_B; | ||
2045 | break; | ||
2046 | case PCH_DP_C: | ||
2047 | reg |= TRANS_DP_PORT_SEL_C; | ||
2048 | break; | ||
2049 | case PCH_DP_D: | ||
2050 | reg |= TRANS_DP_PORT_SEL_D; | ||
2051 | break; | ||
2052 | default: | ||
2053 | DRM_DEBUG_KMS("Wrong PCH DP port return. Guess port B\n"); | ||
2054 | reg |= TRANS_DP_PORT_SEL_B; | ||
2055 | break; | ||
2056 | } | ||
2057 | 1971 | ||
2058 | I915_WRITE(trans_dp_ctl, reg); | 1972 | ironlake_fdi_enable(crtc); |
2059 | POSTING_READ(trans_dp_ctl); | ||
2060 | } | ||
2061 | 1973 | ||
2062 | /* enable PCH transcoder */ | 1974 | /* Enable panel fitting for LVDS */ |
2063 | temp = I915_READ(transconf_reg); | 1975 | if (dev_priv->pch_pf_size && |
2064 | /* | 1976 | (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) |
2065 | * make the BPC in transcoder be consistent with | 1977 | || HAS_eDP || intel_pch_has_edp(crtc))) { |
2066 | * that in pipeconf reg. | 1978 | /* Force use of hard-coded filter coefficients |
2067 | */ | 1979 | * as some pre-programmed values are broken, |
2068 | temp &= ~PIPE_BPC_MASK; | 1980 | * e.g. x201. |
2069 | temp |= pipe_bpc; | 1981 | */ |
2070 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | 1982 | I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, |
2071 | I915_READ(transconf_reg); | 1983 | PF_ENABLE | PF_FILTER_MED_3x3); |
1984 | I915_WRITE(pipe ? PFB_WIN_POS : PFA_WIN_POS, | ||
1985 | dev_priv->pch_pf_pos); | ||
1986 | I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ, | ||
1987 | dev_priv->pch_pf_size); | ||
1988 | } | ||
1989 | |||
1990 | /* Enable CPU pipe */ | ||
1991 | reg = PIPECONF(pipe); | ||
1992 | temp = I915_READ(reg); | ||
1993 | if ((temp & PIPECONF_ENABLE) == 0) { | ||
1994 | I915_WRITE(reg, temp | PIPECONF_ENABLE); | ||
1995 | POSTING_READ(reg); | ||
1996 | udelay(100); | ||
1997 | } | ||
2072 | 1998 | ||
2073 | if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 100, 1)) | 1999 | /* configure and enable CPU plane */ |
2074 | DRM_ERROR("failed to enable transcoder\n"); | 2000 | reg = DSPCNTR(plane); |
2075 | } | 2001 | temp = I915_READ(reg); |
2002 | if ((temp & DISPLAY_PLANE_ENABLE) == 0) { | ||
2003 | I915_WRITE(reg, temp | DISPLAY_PLANE_ENABLE); | ||
2004 | intel_flush_display_plane(dev, plane); | ||
2005 | } | ||
2076 | 2006 | ||
2077 | intel_crtc_load_lut(crtc); | 2007 | /* For PCH output, training FDI link */ |
2008 | if (IS_GEN6(dev)) | ||
2009 | gen6_fdi_link_train(crtc); | ||
2010 | else | ||
2011 | ironlake_fdi_link_train(crtc); | ||
2012 | |||
2013 | /* enable PCH DPLL */ | ||
2014 | reg = PCH_DPLL(pipe); | ||
2015 | temp = I915_READ(reg); | ||
2016 | if ((temp & DPLL_VCO_ENABLE) == 0) { | ||
2017 | I915_WRITE(reg, temp | DPLL_VCO_ENABLE); | ||
2018 | POSTING_READ(reg); | ||
2019 | udelay(200); | ||
2020 | } | ||
2078 | 2021 | ||
2079 | intel_update_fbc(crtc, &crtc->mode); | 2022 | if (HAS_PCH_CPT(dev)) { |
2080 | break; | 2023 | /* Be sure PCH DPLL SEL is set */ |
2024 | temp = I915_READ(PCH_DPLL_SEL); | ||
2025 | if (pipe == 0 && (temp & TRANSA_DPLL_ENABLE) == 0) | ||
2026 | temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL); | ||
2027 | else if (pipe == 1 && (temp & TRANSB_DPLL_ENABLE) == 0) | ||
2028 | temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); | ||
2029 | I915_WRITE(PCH_DPLL_SEL, temp); | ||
2030 | } | ||
2081 | 2031 | ||
2082 | case DRM_MODE_DPMS_OFF: | 2032 | /* set transcoder timing */ |
2083 | DRM_DEBUG_KMS("crtc %d/%d dpms off\n", pipe, plane); | 2033 | I915_WRITE(TRANS_HTOTAL(pipe), I915_READ(HTOTAL(pipe))); |
2034 | I915_WRITE(TRANS_HBLANK(pipe), I915_READ(HBLANK(pipe))); | ||
2035 | I915_WRITE(TRANS_HSYNC(pipe), I915_READ(HSYNC(pipe))); | ||
2036 | |||
2037 | I915_WRITE(TRANS_VTOTAL(pipe), I915_READ(VTOTAL(pipe))); | ||
2038 | I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe))); | ||
2039 | I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); | ||
2040 | |||
2041 | /* enable normal train */ | ||
2042 | reg = FDI_TX_CTL(pipe); | ||
2043 | temp = I915_READ(reg); | ||
2044 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
2045 | temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; | ||
2046 | I915_WRITE(reg, temp); | ||
2084 | 2047 | ||
2085 | drm_vblank_off(dev, pipe); | 2048 | reg = FDI_RX_CTL(pipe); |
2086 | /* Disable display plane */ | 2049 | temp = I915_READ(reg); |
2087 | temp = I915_READ(dspcntr_reg); | 2050 | if (HAS_PCH_CPT(dev)) { |
2088 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { | 2051 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; |
2089 | I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); | 2052 | temp |= FDI_LINK_TRAIN_NORMAL_CPT; |
2090 | /* Flush the plane changes */ | 2053 | } else { |
2091 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); | 2054 | temp &= ~FDI_LINK_TRAIN_NONE; |
2092 | I915_READ(dspbase_reg); | 2055 | temp |= FDI_LINK_TRAIN_NONE; |
2056 | } | ||
2057 | I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); | ||
2058 | |||
2059 | /* wait one idle pattern time */ | ||
2060 | POSTING_READ(reg); | ||
2061 | udelay(100); | ||
2062 | |||
2063 | /* For PCH DP, enable TRANS_DP_CTL */ | ||
2064 | if (HAS_PCH_CPT(dev) && | ||
2065 | intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { | ||
2066 | reg = TRANS_DP_CTL(pipe); | ||
2067 | temp = I915_READ(reg); | ||
2068 | temp &= ~(TRANS_DP_PORT_SEL_MASK | | ||
2069 | TRANS_DP_SYNC_MASK); | ||
2070 | temp |= (TRANS_DP_OUTPUT_ENABLE | | ||
2071 | TRANS_DP_ENH_FRAMING); | ||
2072 | |||
2073 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | ||
2074 | temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; | ||
2075 | if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) | ||
2076 | temp |= TRANS_DP_VSYNC_ACTIVE_HIGH; | ||
2077 | |||
2078 | switch (intel_trans_dp_port_sel(crtc)) { | ||
2079 | case PCH_DP_B: | ||
2080 | temp |= TRANS_DP_PORT_SEL_B; | ||
2081 | break; | ||
2082 | case PCH_DP_C: | ||
2083 | temp |= TRANS_DP_PORT_SEL_C; | ||
2084 | break; | ||
2085 | case PCH_DP_D: | ||
2086 | temp |= TRANS_DP_PORT_SEL_D; | ||
2087 | break; | ||
2088 | default: | ||
2089 | DRM_DEBUG_KMS("Wrong PCH DP port return. Guess port B\n"); | ||
2090 | temp |= TRANS_DP_PORT_SEL_B; | ||
2091 | break; | ||
2093 | } | 2092 | } |
2094 | 2093 | ||
2095 | if (dev_priv->cfb_plane == plane && | 2094 | I915_WRITE(reg, temp); |
2096 | dev_priv->display.disable_fbc) | 2095 | } |
2097 | dev_priv->display.disable_fbc(dev); | 2096 | |
2097 | /* enable PCH transcoder */ | ||
2098 | reg = TRANSCONF(pipe); | ||
2099 | temp = I915_READ(reg); | ||
2100 | /* | ||
2101 | * make the BPC in transcoder be consistent with | ||
2102 | * that in pipeconf reg. | ||
2103 | */ | ||
2104 | temp &= ~PIPE_BPC_MASK; | ||
2105 | temp |= I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK; | ||
2106 | I915_WRITE(reg, temp | TRANS_ENABLE); | ||
2107 | if (wait_for(I915_READ(reg) & TRANS_STATE_ENABLE, 100)) | ||
2108 | DRM_ERROR("failed to enable transcoder\n"); | ||
2098 | 2109 | ||
2099 | /* disable cpu pipe, disable after all planes disabled */ | 2110 | intel_crtc_load_lut(crtc); |
2100 | temp = I915_READ(pipeconf_reg); | 2111 | intel_update_fbc(dev); |
2101 | if ((temp & PIPEACONF_ENABLE) != 0) { | 2112 | intel_crtc_update_cursor(crtc, true); |
2102 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); | 2113 | } |
2103 | 2114 | ||
2104 | /* wait for cpu pipe off, pipe state */ | 2115 | static void ironlake_crtc_disable(struct drm_crtc *crtc) |
2105 | if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, 50, 1)) | 2116 | { |
2106 | DRM_ERROR("failed to turn off cpu pipe\n"); | 2117 | struct drm_device *dev = crtc->dev; |
2107 | } else | 2118 | struct drm_i915_private *dev_priv = dev->dev_private; |
2108 | DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); | 2119 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2120 | int pipe = intel_crtc->pipe; | ||
2121 | int plane = intel_crtc->plane; | ||
2122 | u32 reg, temp; | ||
2109 | 2123 | ||
2110 | udelay(100); | 2124 | if (!intel_crtc->active) |
2125 | return; | ||
2111 | 2126 | ||
2112 | /* Disable PF */ | 2127 | drm_vblank_off(dev, pipe); |
2113 | I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, 0); | 2128 | intel_crtc_update_cursor(crtc, false); |
2114 | I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ, 0); | ||
2115 | 2129 | ||
2116 | /* disable CPU FDI tx and PCH FDI rx */ | 2130 | /* Disable display plane */ |
2117 | temp = I915_READ(fdi_tx_reg); | 2131 | reg = DSPCNTR(plane); |
2118 | I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_ENABLE); | 2132 | temp = I915_READ(reg); |
2119 | I915_READ(fdi_tx_reg); | 2133 | if (temp & DISPLAY_PLANE_ENABLE) { |
2134 | I915_WRITE(reg, temp & ~DISPLAY_PLANE_ENABLE); | ||
2135 | intel_flush_display_plane(dev, plane); | ||
2136 | } | ||
2120 | 2137 | ||
2121 | temp = I915_READ(fdi_rx_reg); | 2138 | if (dev_priv->cfb_plane == plane && |
2122 | /* BPC in FDI rx is consistent with that in pipeconf */ | 2139 | dev_priv->display.disable_fbc) |
2123 | temp &= ~(0x07 << 16); | 2140 | dev_priv->display.disable_fbc(dev); |
2124 | temp |= (pipe_bpc << 11); | ||
2125 | I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); | ||
2126 | I915_READ(fdi_rx_reg); | ||
2127 | 2141 | ||
2128 | udelay(100); | 2142 | /* disable cpu pipe, disable after all planes disabled */ |
2143 | reg = PIPECONF(pipe); | ||
2144 | temp = I915_READ(reg); | ||
2145 | if (temp & PIPECONF_ENABLE) { | ||
2146 | I915_WRITE(reg, temp & ~PIPECONF_ENABLE); | ||
2147 | /* wait for cpu pipe off, pipe state */ | ||
2148 | if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0, 50)) | ||
2149 | DRM_ERROR("failed to turn off cpu pipe\n"); | ||
2150 | } | ||
2151 | |||
2152 | /* Disable PF */ | ||
2153 | I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, 0); | ||
2154 | I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ, 0); | ||
2155 | |||
2156 | /* disable CPU FDI tx and PCH FDI rx */ | ||
2157 | reg = FDI_TX_CTL(pipe); | ||
2158 | temp = I915_READ(reg); | ||
2159 | I915_WRITE(reg, temp & ~FDI_TX_ENABLE); | ||
2160 | POSTING_READ(reg); | ||
2161 | |||
2162 | reg = FDI_RX_CTL(pipe); | ||
2163 | temp = I915_READ(reg); | ||
2164 | temp &= ~(0x7 << 16); | ||
2165 | temp |= (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) << 11; | ||
2166 | I915_WRITE(reg, temp & ~FDI_RX_ENABLE); | ||
2167 | |||
2168 | POSTING_READ(reg); | ||
2169 | udelay(100); | ||
2170 | |||
2171 | /* still set train pattern 1 */ | ||
2172 | reg = FDI_TX_CTL(pipe); | ||
2173 | temp = I915_READ(reg); | ||
2174 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
2175 | temp |= FDI_LINK_TRAIN_PATTERN_1; | ||
2176 | I915_WRITE(reg, temp); | ||
2129 | 2177 | ||
2130 | /* still set train pattern 1 */ | 2178 | reg = FDI_RX_CTL(pipe); |
2131 | temp = I915_READ(fdi_tx_reg); | 2179 | temp = I915_READ(reg); |
2180 | if (HAS_PCH_CPT(dev)) { | ||
2181 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; | ||
2182 | temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; | ||
2183 | } else { | ||
2132 | temp &= ~FDI_LINK_TRAIN_NONE; | 2184 | temp &= ~FDI_LINK_TRAIN_NONE; |
2133 | temp |= FDI_LINK_TRAIN_PATTERN_1; | 2185 | temp |= FDI_LINK_TRAIN_PATTERN_1; |
2134 | I915_WRITE(fdi_tx_reg, temp); | 2186 | } |
2135 | POSTING_READ(fdi_tx_reg); | 2187 | /* BPC in FDI rx is consistent with that in PIPECONF */ |
2136 | 2188 | temp &= ~(0x07 << 16); | |
2137 | temp = I915_READ(fdi_rx_reg); | 2189 | temp |= (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) << 11; |
2138 | if (HAS_PCH_CPT(dev)) { | 2190 | I915_WRITE(reg, temp); |
2139 | temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; | ||
2140 | temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; | ||
2141 | } else { | ||
2142 | temp &= ~FDI_LINK_TRAIN_NONE; | ||
2143 | temp |= FDI_LINK_TRAIN_PATTERN_1; | ||
2144 | } | ||
2145 | I915_WRITE(fdi_rx_reg, temp); | ||
2146 | POSTING_READ(fdi_rx_reg); | ||
2147 | 2191 | ||
2148 | udelay(100); | 2192 | POSTING_READ(reg); |
2193 | udelay(100); | ||
2149 | 2194 | ||
2150 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 2195 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
2151 | temp = I915_READ(PCH_LVDS); | 2196 | temp = I915_READ(PCH_LVDS); |
2197 | if (temp & LVDS_PORT_EN) { | ||
2152 | I915_WRITE(PCH_LVDS, temp & ~LVDS_PORT_EN); | 2198 | I915_WRITE(PCH_LVDS, temp & ~LVDS_PORT_EN); |
2153 | I915_READ(PCH_LVDS); | 2199 | POSTING_READ(PCH_LVDS); |
2154 | udelay(100); | 2200 | udelay(100); |
2155 | } | 2201 | } |
2202 | } | ||
2156 | 2203 | ||
2157 | /* disable PCH transcoder */ | 2204 | /* disable PCH transcoder */ |
2158 | temp = I915_READ(transconf_reg); | 2205 | reg = TRANSCONF(plane); |
2159 | if ((temp & TRANS_ENABLE) != 0) { | 2206 | temp = I915_READ(reg); |
2160 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); | 2207 | if (temp & TRANS_ENABLE) { |
2208 | I915_WRITE(reg, temp & ~TRANS_ENABLE); | ||
2209 | /* wait for PCH transcoder off, transcoder state */ | ||
2210 | if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50)) | ||
2211 | DRM_ERROR("failed to disable transcoder\n"); | ||
2212 | } | ||
2161 | 2213 | ||
2162 | /* wait for PCH transcoder off, transcoder state */ | 2214 | if (HAS_PCH_CPT(dev)) { |
2163 | if (wait_for((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0, 50, 1)) | 2215 | /* disable TRANS_DP_CTL */ |
2164 | DRM_ERROR("failed to disable transcoder\n"); | 2216 | reg = TRANS_DP_CTL(pipe); |
2165 | } | 2217 | temp = I915_READ(reg); |
2218 | temp &= ~(TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK); | ||
2219 | I915_WRITE(reg, temp); | ||
2166 | 2220 | ||
2167 | temp = I915_READ(transconf_reg); | 2221 | /* disable DPLL_SEL */ |
2168 | /* BPC in transcoder is consistent with that in pipeconf */ | 2222 | temp = I915_READ(PCH_DPLL_SEL); |
2169 | temp &= ~PIPE_BPC_MASK; | 2223 | if (pipe == 0) |
2170 | temp |= pipe_bpc; | 2224 | temp &= ~(TRANSA_DPLL_ENABLE | TRANSA_DPLLB_SEL); |
2171 | I915_WRITE(transconf_reg, temp); | 2225 | else |
2172 | I915_READ(transconf_reg); | 2226 | temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); |
2173 | udelay(100); | 2227 | I915_WRITE(PCH_DPLL_SEL, temp); |
2228 | } | ||
2174 | 2229 | ||
2175 | if (HAS_PCH_CPT(dev)) { | 2230 | /* disable PCH DPLL */ |
2176 | /* disable TRANS_DP_CTL */ | 2231 | reg = PCH_DPLL(pipe); |
2177 | int trans_dp_ctl = (pipe == 0) ? TRANS_DP_CTL_A : TRANS_DP_CTL_B; | 2232 | temp = I915_READ(reg); |
2178 | int reg; | 2233 | I915_WRITE(reg, temp & ~DPLL_VCO_ENABLE); |
2179 | 2234 | ||
2180 | reg = I915_READ(trans_dp_ctl); | 2235 | /* Switch from PCDclk to Rawclk */ |
2181 | reg &= ~(TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK); | 2236 | reg = FDI_RX_CTL(pipe); |
2182 | I915_WRITE(trans_dp_ctl, reg); | 2237 | temp = I915_READ(reg); |
2183 | POSTING_READ(trans_dp_ctl); | 2238 | I915_WRITE(reg, temp & ~FDI_PCDCLK); |
2184 | 2239 | ||
2185 | /* disable DPLL_SEL */ | 2240 | /* Disable CPU FDI TX PLL */ |
2186 | temp = I915_READ(PCH_DPLL_SEL); | 2241 | reg = FDI_TX_CTL(pipe); |
2187 | if (trans_dpll_sel == 0) | 2242 | temp = I915_READ(reg); |
2188 | temp &= ~(TRANSA_DPLL_ENABLE | TRANSA_DPLLB_SEL); | 2243 | I915_WRITE(reg, temp & ~FDI_TX_PLL_ENABLE); |
2189 | else | ||
2190 | temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); | ||
2191 | I915_WRITE(PCH_DPLL_SEL, temp); | ||
2192 | I915_READ(PCH_DPLL_SEL); | ||
2193 | 2244 | ||
2194 | } | 2245 | POSTING_READ(reg); |
2246 | udelay(100); | ||
2195 | 2247 | ||
2196 | /* disable PCH DPLL */ | 2248 | reg = FDI_RX_CTL(pipe); |
2197 | temp = I915_READ(pch_dpll_reg); | 2249 | temp = I915_READ(reg); |
2198 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); | 2250 | I915_WRITE(reg, temp & ~FDI_RX_PLL_ENABLE); |
2199 | I915_READ(pch_dpll_reg); | ||
2200 | |||
2201 | /* Switch from PCDclk to Rawclk */ | ||
2202 | temp = I915_READ(fdi_rx_reg); | ||
2203 | temp &= ~FDI_SEL_PCDCLK; | ||
2204 | I915_WRITE(fdi_rx_reg, temp); | ||
2205 | I915_READ(fdi_rx_reg); | ||
2206 | |||
2207 | /* Disable CPU FDI TX PLL */ | ||
2208 | temp = I915_READ(fdi_tx_reg); | ||
2209 | I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_PLL_ENABLE); | ||
2210 | I915_READ(fdi_tx_reg); | ||
2211 | udelay(100); | ||
2212 | 2251 | ||
2213 | temp = I915_READ(fdi_rx_reg); | 2252 | /* Wait for the clocks to turn off. */ |
2214 | temp &= ~FDI_RX_PLL_ENABLE; | 2253 | POSTING_READ(reg); |
2215 | I915_WRITE(fdi_rx_reg, temp); | 2254 | udelay(100); |
2216 | I915_READ(fdi_rx_reg); | ||
2217 | 2255 | ||
2218 | /* Wait for the clocks to turn off. */ | 2256 | intel_crtc->active = false; |
2219 | udelay(100); | 2257 | intel_update_watermarks(dev); |
2258 | intel_update_fbc(dev); | ||
2259 | intel_clear_scanline_wait(dev); | ||
2260 | } | ||
2261 | |||
2262 | static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
2263 | { | ||
2264 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
2265 | int pipe = intel_crtc->pipe; | ||
2266 | int plane = intel_crtc->plane; | ||
2267 | |||
2268 | /* XXX: When our outputs are all unaware of DPMS modes other than off | ||
2269 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. | ||
2270 | */ | ||
2271 | switch (mode) { | ||
2272 | case DRM_MODE_DPMS_ON: | ||
2273 | case DRM_MODE_DPMS_STANDBY: | ||
2274 | case DRM_MODE_DPMS_SUSPEND: | ||
2275 | DRM_DEBUG_KMS("crtc %d/%d dpms on\n", pipe, plane); | ||
2276 | ironlake_crtc_enable(crtc); | ||
2277 | break; | ||
2278 | |||
2279 | case DRM_MODE_DPMS_OFF: | ||
2280 | DRM_DEBUG_KMS("crtc %d/%d dpms off\n", pipe, plane); | ||
2281 | ironlake_crtc_disable(crtc); | ||
2220 | break; | 2282 | break; |
2221 | } | 2283 | } |
2222 | } | 2284 | } |
2223 | 2285 | ||
2224 | static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) | 2286 | static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) |
2225 | { | 2287 | { |
2226 | struct intel_overlay *overlay; | ||
2227 | int ret; | ||
2228 | |||
2229 | if (!enable && intel_crtc->overlay) { | 2288 | if (!enable && intel_crtc->overlay) { |
2230 | overlay = intel_crtc->overlay; | 2289 | struct drm_device *dev = intel_crtc->base.dev; |
2231 | mutex_lock(&overlay->dev->struct_mutex); | ||
2232 | for (;;) { | ||
2233 | ret = intel_overlay_switch_off(overlay); | ||
2234 | if (ret == 0) | ||
2235 | break; | ||
2236 | 2290 | ||
2237 | ret = intel_overlay_recover_from_interrupt(overlay, 0); | 2291 | mutex_lock(&dev->struct_mutex); |
2238 | if (ret != 0) { | 2292 | (void) intel_overlay_switch_off(intel_crtc->overlay, false); |
2239 | /* overlay doesn't react anymore. Usually | 2293 | mutex_unlock(&dev->struct_mutex); |
2240 | * results in a black screen and an unkillable | ||
2241 | * X server. */ | ||
2242 | BUG(); | ||
2243 | overlay->hw_wedged = HW_WEDGED; | ||
2244 | break; | ||
2245 | } | ||
2246 | } | ||
2247 | mutex_unlock(&overlay->dev->struct_mutex); | ||
2248 | } | 2294 | } |
2249 | /* Let userspace switch the overlay on again. In most cases userspace | ||
2250 | * has to recompute where to put it anyway. */ | ||
2251 | 2295 | ||
2252 | return; | 2296 | /* Let userspace switch the overlay on again. In most cases userspace |
2297 | * has to recompute where to put it anyway. | ||
2298 | */ | ||
2253 | } | 2299 | } |
2254 | 2300 | ||
2255 | static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | 2301 | static void i9xx_crtc_enable(struct drm_crtc *crtc) |
2256 | { | 2302 | { |
2257 | struct drm_device *dev = crtc->dev; | 2303 | struct drm_device *dev = crtc->dev; |
2258 | struct drm_i915_private *dev_priv = dev->dev_private; | 2304 | struct drm_i915_private *dev_priv = dev->dev_private; |
2259 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 2305 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2260 | int pipe = intel_crtc->pipe; | 2306 | int pipe = intel_crtc->pipe; |
2261 | int plane = intel_crtc->plane; | 2307 | int plane = intel_crtc->plane; |
2262 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | 2308 | u32 reg, temp; |
2263 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; | ||
2264 | int dspbase_reg = (plane == 0) ? DSPAADDR : DSPBADDR; | ||
2265 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; | ||
2266 | u32 temp; | ||
2267 | 2309 | ||
2268 | /* XXX: When our outputs are all unaware of DPMS modes other than off | 2310 | if (intel_crtc->active) |
2269 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. | 2311 | return; |
2270 | */ | ||
2271 | switch (mode) { | ||
2272 | case DRM_MODE_DPMS_ON: | ||
2273 | case DRM_MODE_DPMS_STANDBY: | ||
2274 | case DRM_MODE_DPMS_SUSPEND: | ||
2275 | /* Enable the DPLL */ | ||
2276 | temp = I915_READ(dpll_reg); | ||
2277 | if ((temp & DPLL_VCO_ENABLE) == 0) { | ||
2278 | I915_WRITE(dpll_reg, temp); | ||
2279 | I915_READ(dpll_reg); | ||
2280 | /* Wait for the clocks to stabilize. */ | ||
2281 | udelay(150); | ||
2282 | I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); | ||
2283 | I915_READ(dpll_reg); | ||
2284 | /* Wait for the clocks to stabilize. */ | ||
2285 | udelay(150); | ||
2286 | I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); | ||
2287 | I915_READ(dpll_reg); | ||
2288 | /* Wait for the clocks to stabilize. */ | ||
2289 | udelay(150); | ||
2290 | } | ||
2291 | 2312 | ||
2292 | /* Enable the pipe */ | 2313 | intel_crtc->active = true; |
2293 | temp = I915_READ(pipeconf_reg); | 2314 | intel_update_watermarks(dev); |
2294 | if ((temp & PIPEACONF_ENABLE) == 0) | ||
2295 | I915_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); | ||
2296 | |||
2297 | /* Enable the plane */ | ||
2298 | temp = I915_READ(dspcntr_reg); | ||
2299 | if ((temp & DISPLAY_PLANE_ENABLE) == 0) { | ||
2300 | I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE); | ||
2301 | /* Flush the plane changes */ | ||
2302 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); | ||
2303 | } | ||
2304 | 2315 | ||
2305 | intel_crtc_load_lut(crtc); | 2316 | /* Enable the DPLL */ |
2317 | reg = DPLL(pipe); | ||
2318 | temp = I915_READ(reg); | ||
2319 | if ((temp & DPLL_VCO_ENABLE) == 0) { | ||
2320 | I915_WRITE(reg, temp); | ||
2306 | 2321 | ||
2307 | if ((IS_I965G(dev) || plane == 0)) | 2322 | /* Wait for the clocks to stabilize. */ |
2308 | intel_update_fbc(crtc, &crtc->mode); | 2323 | POSTING_READ(reg); |
2324 | udelay(150); | ||
2309 | 2325 | ||
2310 | /* Give the overlay scaler a chance to enable if it's on this pipe */ | 2326 | I915_WRITE(reg, temp | DPLL_VCO_ENABLE); |
2311 | intel_crtc_dpms_overlay(intel_crtc, true); | 2327 | |
2312 | break; | 2328 | /* Wait for the clocks to stabilize. */ |
2313 | case DRM_MODE_DPMS_OFF: | 2329 | POSTING_READ(reg); |
2314 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 2330 | udelay(150); |
2315 | intel_crtc_dpms_overlay(intel_crtc, false); | 2331 | |
2316 | drm_vblank_off(dev, pipe); | 2332 | I915_WRITE(reg, temp | DPLL_VCO_ENABLE); |
2317 | 2333 | ||
2318 | if (dev_priv->cfb_plane == plane && | 2334 | /* Wait for the clocks to stabilize. */ |
2319 | dev_priv->display.disable_fbc) | 2335 | POSTING_READ(reg); |
2320 | dev_priv->display.disable_fbc(dev); | 2336 | udelay(150); |
2321 | 2337 | } | |
2322 | /* Disable display plane */ | 2338 | |
2323 | temp = I915_READ(dspcntr_reg); | 2339 | /* Enable the pipe */ |
2324 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { | 2340 | reg = PIPECONF(pipe); |
2325 | I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); | 2341 | temp = I915_READ(reg); |
2326 | /* Flush the plane changes */ | 2342 | if ((temp & PIPECONF_ENABLE) == 0) |
2327 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); | 2343 | I915_WRITE(reg, temp | PIPECONF_ENABLE); |
2328 | I915_READ(dspbase_reg); | 2344 | |
2329 | } | 2345 | /* Enable the plane */ |
2346 | reg = DSPCNTR(plane); | ||
2347 | temp = I915_READ(reg); | ||
2348 | if ((temp & DISPLAY_PLANE_ENABLE) == 0) { | ||
2349 | I915_WRITE(reg, temp | DISPLAY_PLANE_ENABLE); | ||
2350 | intel_flush_display_plane(dev, plane); | ||
2351 | } | ||
2352 | |||
2353 | intel_crtc_load_lut(crtc); | ||
2354 | intel_update_fbc(dev); | ||
2355 | |||
2356 | /* Give the overlay scaler a chance to enable if it's on this pipe */ | ||
2357 | intel_crtc_dpms_overlay(intel_crtc, true); | ||
2358 | intel_crtc_update_cursor(crtc, true); | ||
2359 | } | ||
2360 | |||
2361 | static void i9xx_crtc_disable(struct drm_crtc *crtc) | ||
2362 | { | ||
2363 | struct drm_device *dev = crtc->dev; | ||
2364 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2365 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
2366 | int pipe = intel_crtc->pipe; | ||
2367 | int plane = intel_crtc->plane; | ||
2368 | u32 reg, temp; | ||
2369 | |||
2370 | if (!intel_crtc->active) | ||
2371 | return; | ||
2372 | |||
2373 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | ||
2374 | intel_crtc_dpms_overlay(intel_crtc, false); | ||
2375 | intel_crtc_update_cursor(crtc, false); | ||
2376 | drm_vblank_off(dev, pipe); | ||
2377 | |||
2378 | if (dev_priv->cfb_plane == plane && | ||
2379 | dev_priv->display.disable_fbc) | ||
2380 | dev_priv->display.disable_fbc(dev); | ||
2381 | |||
2382 | /* Disable display plane */ | ||
2383 | reg = DSPCNTR(plane); | ||
2384 | temp = I915_READ(reg); | ||
2385 | if (temp & DISPLAY_PLANE_ENABLE) { | ||
2386 | I915_WRITE(reg, temp & ~DISPLAY_PLANE_ENABLE); | ||
2387 | /* Flush the plane changes */ | ||
2388 | intel_flush_display_plane(dev, plane); | ||
2330 | 2389 | ||
2331 | /* Wait for vblank for the disable to take effect */ | 2390 | /* Wait for vblank for the disable to take effect */ |
2332 | intel_wait_for_vblank_off(dev, pipe); | 2391 | if (!IS_I9XX(dev)) |
2392 | intel_wait_for_vblank_off(dev, pipe); | ||
2393 | } | ||
2333 | 2394 | ||
2334 | /* Don't disable pipe A or pipe A PLLs if needed */ | 2395 | /* Don't disable pipe A or pipe A PLLs if needed */ |
2335 | if (pipeconf_reg == PIPEACONF && | 2396 | if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) |
2336 | (dev_priv->quirks & QUIRK_PIPEA_FORCE)) | 2397 | goto done; |
2337 | goto skip_pipe_off; | ||
2338 | 2398 | ||
2339 | /* Next, disable display pipes */ | 2399 | /* Next, disable display pipes */ |
2340 | temp = I915_READ(pipeconf_reg); | 2400 | reg = PIPECONF(pipe); |
2341 | if ((temp & PIPEACONF_ENABLE) != 0) { | 2401 | temp = I915_READ(reg); |
2342 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); | 2402 | if (temp & PIPECONF_ENABLE) { |
2343 | I915_READ(pipeconf_reg); | 2403 | I915_WRITE(reg, temp & ~PIPECONF_ENABLE); |
2344 | } | ||
2345 | 2404 | ||
2346 | /* Wait for vblank for the disable to take effect. */ | 2405 | /* Wait for vblank for the disable to take effect. */ |
2406 | POSTING_READ(reg); | ||
2347 | intel_wait_for_vblank_off(dev, pipe); | 2407 | intel_wait_for_vblank_off(dev, pipe); |
2408 | } | ||
2409 | |||
2410 | reg = DPLL(pipe); | ||
2411 | temp = I915_READ(reg); | ||
2412 | if (temp & DPLL_VCO_ENABLE) { | ||
2413 | I915_WRITE(reg, temp & ~DPLL_VCO_ENABLE); | ||
2348 | 2414 | ||
2349 | temp = I915_READ(dpll_reg); | ||
2350 | if ((temp & DPLL_VCO_ENABLE) != 0) { | ||
2351 | I915_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); | ||
2352 | I915_READ(dpll_reg); | ||
2353 | } | ||
2354 | skip_pipe_off: | ||
2355 | /* Wait for the clocks to turn off. */ | 2415 | /* Wait for the clocks to turn off. */ |
2416 | POSTING_READ(reg); | ||
2356 | udelay(150); | 2417 | udelay(150); |
2418 | } | ||
2419 | |||
2420 | done: | ||
2421 | intel_crtc->active = false; | ||
2422 | intel_update_fbc(dev); | ||
2423 | intel_update_watermarks(dev); | ||
2424 | intel_clear_scanline_wait(dev); | ||
2425 | } | ||
2426 | |||
2427 | static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
2428 | { | ||
2429 | /* XXX: When our outputs are all unaware of DPMS modes other than off | ||
2430 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. | ||
2431 | */ | ||
2432 | switch (mode) { | ||
2433 | case DRM_MODE_DPMS_ON: | ||
2434 | case DRM_MODE_DPMS_STANDBY: | ||
2435 | case DRM_MODE_DPMS_SUSPEND: | ||
2436 | i9xx_crtc_enable(crtc); | ||
2437 | break; | ||
2438 | case DRM_MODE_DPMS_OFF: | ||
2439 | i9xx_crtc_disable(crtc); | ||
2357 | break; | 2440 | break; |
2358 | } | 2441 | } |
2359 | } | 2442 | } |
@@ -2374,26 +2457,9 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2374 | return; | 2457 | return; |
2375 | 2458 | ||
2376 | intel_crtc->dpms_mode = mode; | 2459 | intel_crtc->dpms_mode = mode; |
2377 | intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON; | ||
2378 | |||
2379 | /* When switching on the display, ensure that SR is disabled | ||
2380 | * with multiple pipes prior to enabling to new pipe. | ||
2381 | * | ||
2382 | * When switching off the display, make sure the cursor is | ||
2383 | * properly hidden prior to disabling the pipe. | ||
2384 | */ | ||
2385 | if (mode == DRM_MODE_DPMS_ON) | ||
2386 | intel_update_watermarks(dev); | ||
2387 | else | ||
2388 | intel_crtc_update_cursor(crtc); | ||
2389 | 2460 | ||
2390 | dev_priv->display.dpms(crtc, mode); | 2461 | dev_priv->display.dpms(crtc, mode); |
2391 | 2462 | ||
2392 | if (mode == DRM_MODE_DPMS_ON) | ||
2393 | intel_crtc_update_cursor(crtc); | ||
2394 | else | ||
2395 | intel_update_watermarks(dev); | ||
2396 | |||
2397 | if (!dev->primary->master) | 2463 | if (!dev->primary->master) |
2398 | return; | 2464 | return; |
2399 | 2465 | ||
@@ -2418,16 +2484,32 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2418 | } | 2484 | } |
2419 | } | 2485 | } |
2420 | 2486 | ||
2421 | static void intel_crtc_prepare (struct drm_crtc *crtc) | 2487 | /* Prepare for a mode set. |
2488 | * | ||
2489 | * Note we could be a lot smarter here. We need to figure out which outputs | ||
2490 | * will be enabled, which disabled (in short, how the config will changes) | ||
2491 | * and perform the minimum necessary steps to accomplish that, e.g. updating | ||
2492 | * watermarks, FBC configuration, making sure PLLs are programmed correctly, | ||
2493 | * panel fitting is in the proper state, etc. | ||
2494 | */ | ||
2495 | static void i9xx_crtc_prepare(struct drm_crtc *crtc) | ||
2422 | { | 2496 | { |
2423 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | 2497 | i9xx_crtc_disable(crtc); |
2424 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); | ||
2425 | } | 2498 | } |
2426 | 2499 | ||
2427 | static void intel_crtc_commit (struct drm_crtc *crtc) | 2500 | static void i9xx_crtc_commit(struct drm_crtc *crtc) |
2428 | { | 2501 | { |
2429 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | 2502 | i9xx_crtc_enable(crtc); |
2430 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); | 2503 | } |
2504 | |||
2505 | static void ironlake_crtc_prepare(struct drm_crtc *crtc) | ||
2506 | { | ||
2507 | ironlake_crtc_disable(crtc); | ||
2508 | } | ||
2509 | |||
2510 | static void ironlake_crtc_commit(struct drm_crtc *crtc) | ||
2511 | { | ||
2512 | ironlake_crtc_enable(crtc); | ||
2431 | } | 2513 | } |
2432 | 2514 | ||
2433 | void intel_encoder_prepare (struct drm_encoder *encoder) | 2515 | void intel_encoder_prepare (struct drm_encoder *encoder) |
@@ -2446,13 +2528,7 @@ void intel_encoder_commit (struct drm_encoder *encoder) | |||
2446 | 2528 | ||
2447 | void intel_encoder_destroy(struct drm_encoder *encoder) | 2529 | void intel_encoder_destroy(struct drm_encoder *encoder) |
2448 | { | 2530 | { |
2449 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 2531 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
2450 | |||
2451 | if (intel_encoder->ddc_bus) | ||
2452 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
2453 | |||
2454 | if (intel_encoder->i2c_bus) | ||
2455 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
2456 | 2532 | ||
2457 | drm_encoder_cleanup(encoder); | 2533 | drm_encoder_cleanup(encoder); |
2458 | kfree(intel_encoder); | 2534 | kfree(intel_encoder); |
@@ -2543,33 +2619,6 @@ static int i830_get_display_clock_speed(struct drm_device *dev) | |||
2543 | return 133000; | 2619 | return 133000; |
2544 | } | 2620 | } |
2545 | 2621 | ||
2546 | /** | ||
2547 | * Return the pipe currently connected to the panel fitter, | ||
2548 | * or -1 if the panel fitter is not present or not in use | ||
2549 | */ | ||
2550 | int intel_panel_fitter_pipe (struct drm_device *dev) | ||
2551 | { | ||
2552 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2553 | u32 pfit_control; | ||
2554 | |||
2555 | /* i830 doesn't have a panel fitter */ | ||
2556 | if (IS_I830(dev)) | ||
2557 | return -1; | ||
2558 | |||
2559 | pfit_control = I915_READ(PFIT_CONTROL); | ||
2560 | |||
2561 | /* See if the panel fitter is in use */ | ||
2562 | if ((pfit_control & PFIT_ENABLE) == 0) | ||
2563 | return -1; | ||
2564 | |||
2565 | /* 965 can place panel fitter on either pipe */ | ||
2566 | if (IS_I965G(dev)) | ||
2567 | return (pfit_control >> 29) & 0x3; | ||
2568 | |||
2569 | /* older chips can only use pipe 1 */ | ||
2570 | return 1; | ||
2571 | } | ||
2572 | |||
2573 | struct fdi_m_n { | 2622 | struct fdi_m_n { |
2574 | u32 tu; | 2623 | u32 tu; |
2575 | u32 gmch_m; | 2624 | u32 gmch_m; |
@@ -2888,7 +2937,7 @@ static int i9xx_get_fifo_size(struct drm_device *dev, int plane) | |||
2888 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size; | 2937 | size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size; |
2889 | 2938 | ||
2890 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | 2939 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, |
2891 | plane ? "B" : "A", size); | 2940 | plane ? "B" : "A", size); |
2892 | 2941 | ||
2893 | return size; | 2942 | return size; |
2894 | } | 2943 | } |
@@ -2905,7 +2954,7 @@ static int i85x_get_fifo_size(struct drm_device *dev, int plane) | |||
2905 | size >>= 1; /* Convert to cachelines */ | 2954 | size >>= 1; /* Convert to cachelines */ |
2906 | 2955 | ||
2907 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | 2956 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, |
2908 | plane ? "B" : "A", size); | 2957 | plane ? "B" : "A", size); |
2909 | 2958 | ||
2910 | return size; | 2959 | return size; |
2911 | } | 2960 | } |
@@ -2920,8 +2969,8 @@ static int i845_get_fifo_size(struct drm_device *dev, int plane) | |||
2920 | size >>= 2; /* Convert to cachelines */ | 2969 | size >>= 2; /* Convert to cachelines */ |
2921 | 2970 | ||
2922 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | 2971 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, |
2923 | plane ? "B" : "A", | 2972 | plane ? "B" : "A", |
2924 | size); | 2973 | size); |
2925 | 2974 | ||
2926 | return size; | 2975 | return size; |
2927 | } | 2976 | } |
@@ -2936,14 +2985,14 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane) | |||
2936 | size >>= 1; /* Convert to cachelines */ | 2985 | size >>= 1; /* Convert to cachelines */ |
2937 | 2986 | ||
2938 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, | 2987 | DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, |
2939 | plane ? "B" : "A", size); | 2988 | plane ? "B" : "A", size); |
2940 | 2989 | ||
2941 | return size; | 2990 | return size; |
2942 | } | 2991 | } |
2943 | 2992 | ||
2944 | static void pineview_update_wm(struct drm_device *dev, int planea_clock, | 2993 | static void pineview_update_wm(struct drm_device *dev, int planea_clock, |
2945 | int planeb_clock, int sr_hdisplay, int unused, | 2994 | int planeb_clock, int sr_hdisplay, int unused, |
2946 | int pixel_size) | 2995 | int pixel_size) |
2947 | { | 2996 | { |
2948 | struct drm_i915_private *dev_priv = dev->dev_private; | 2997 | struct drm_i915_private *dev_priv = dev->dev_private; |
2949 | const struct cxsr_latency *latency; | 2998 | const struct cxsr_latency *latency; |
@@ -3055,13 +3104,13 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, | |||
3055 | 3104 | ||
3056 | /* Use ns/us then divide to preserve precision */ | 3105 | /* Use ns/us then divide to preserve precision */ |
3057 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | 3106 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
3058 | pixel_size * sr_hdisplay; | 3107 | pixel_size * sr_hdisplay; |
3059 | sr_entries = DIV_ROUND_UP(sr_entries, cacheline_size); | 3108 | sr_entries = DIV_ROUND_UP(sr_entries, cacheline_size); |
3060 | 3109 | ||
3061 | entries_required = (((sr_latency_ns / line_time_us) + | 3110 | entries_required = (((sr_latency_ns / line_time_us) + |
3062 | 1000) / 1000) * pixel_size * 64; | 3111 | 1000) / 1000) * pixel_size * 64; |
3063 | entries_required = DIV_ROUND_UP(entries_required, | 3112 | entries_required = DIV_ROUND_UP(entries_required, |
3064 | g4x_cursor_wm_info.cacheline_size); | 3113 | g4x_cursor_wm_info.cacheline_size); |
3065 | cursor_sr = entries_required + g4x_cursor_wm_info.guard_size; | 3114 | cursor_sr = entries_required + g4x_cursor_wm_info.guard_size; |
3066 | 3115 | ||
3067 | if (cursor_sr > g4x_cursor_wm_info.max_wm) | 3116 | if (cursor_sr > g4x_cursor_wm_info.max_wm) |
@@ -3073,7 +3122,7 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, | |||
3073 | } else { | 3122 | } else { |
3074 | /* Turn off self refresh if both pipes are enabled */ | 3123 | /* Turn off self refresh if both pipes are enabled */ |
3075 | I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) | 3124 | I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) |
3076 | & ~FW_BLC_SELF_EN); | 3125 | & ~FW_BLC_SELF_EN); |
3077 | } | 3126 | } |
3078 | 3127 | ||
3079 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n", | 3128 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n", |
@@ -3111,7 +3160,7 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, | |||
3111 | 3160 | ||
3112 | /* Use ns/us then divide to preserve precision */ | 3161 | /* Use ns/us then divide to preserve precision */ |
3113 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | 3162 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
3114 | pixel_size * sr_hdisplay; | 3163 | pixel_size * sr_hdisplay; |
3115 | sr_entries = DIV_ROUND_UP(sr_entries, I915_FIFO_LINE_SIZE); | 3164 | sr_entries = DIV_ROUND_UP(sr_entries, I915_FIFO_LINE_SIZE); |
3116 | DRM_DEBUG("self-refresh entries: %d\n", sr_entries); | 3165 | DRM_DEBUG("self-refresh entries: %d\n", sr_entries); |
3117 | srwm = I965_FIFO_SIZE - sr_entries; | 3166 | srwm = I965_FIFO_SIZE - sr_entries; |
@@ -3120,11 +3169,11 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, | |||
3120 | srwm &= 0x1ff; | 3169 | srwm &= 0x1ff; |
3121 | 3170 | ||
3122 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | 3171 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
3123 | pixel_size * 64; | 3172 | pixel_size * 64; |
3124 | sr_entries = DIV_ROUND_UP(sr_entries, | 3173 | sr_entries = DIV_ROUND_UP(sr_entries, |
3125 | i965_cursor_wm_info.cacheline_size); | 3174 | i965_cursor_wm_info.cacheline_size); |
3126 | cursor_sr = i965_cursor_wm_info.fifo_size - | 3175 | cursor_sr = i965_cursor_wm_info.fifo_size - |
3127 | (sr_entries + i965_cursor_wm_info.guard_size); | 3176 | (sr_entries + i965_cursor_wm_info.guard_size); |
3128 | 3177 | ||
3129 | if (cursor_sr > i965_cursor_wm_info.max_wm) | 3178 | if (cursor_sr > i965_cursor_wm_info.max_wm) |
3130 | cursor_sr = i965_cursor_wm_info.max_wm; | 3179 | cursor_sr = i965_cursor_wm_info.max_wm; |
@@ -3203,7 +3252,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
3203 | 3252 | ||
3204 | /* Use ns/us then divide to preserve precision */ | 3253 | /* Use ns/us then divide to preserve precision */ |
3205 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * | 3254 | sr_entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * |
3206 | pixel_size * sr_hdisplay; | 3255 | pixel_size * sr_hdisplay; |
3207 | sr_entries = DIV_ROUND_UP(sr_entries, cacheline_size); | 3256 | sr_entries = DIV_ROUND_UP(sr_entries, cacheline_size); |
3208 | DRM_DEBUG_KMS("self-refresh entries: %d\n", sr_entries); | 3257 | DRM_DEBUG_KMS("self-refresh entries: %d\n", sr_entries); |
3209 | srwm = total_size - sr_entries; | 3258 | srwm = total_size - sr_entries; |
@@ -3228,7 +3277,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
3228 | } | 3277 | } |
3229 | 3278 | ||
3230 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | 3279 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", |
3231 | planea_wm, planeb_wm, cwm, srwm); | 3280 | planea_wm, planeb_wm, cwm, srwm); |
3232 | 3281 | ||
3233 | fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f); | 3282 | fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f); |
3234 | fwater_hi = (cwm & 0x1f); | 3283 | fwater_hi = (cwm & 0x1f); |
@@ -3262,146 +3311,130 @@ static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, | |||
3262 | #define ILK_LP0_PLANE_LATENCY 700 | 3311 | #define ILK_LP0_PLANE_LATENCY 700 |
3263 | #define ILK_LP0_CURSOR_LATENCY 1300 | 3312 | #define ILK_LP0_CURSOR_LATENCY 1300 |
3264 | 3313 | ||
3265 | static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | 3314 | static bool ironlake_compute_wm0(struct drm_device *dev, |
3266 | int planeb_clock, int sr_hdisplay, int sr_htotal, | 3315 | int pipe, |
3267 | int pixel_size) | 3316 | int *plane_wm, |
3317 | int *cursor_wm) | ||
3268 | { | 3318 | { |
3269 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3270 | int planea_wm, planeb_wm, cursora_wm, cursorb_wm; | ||
3271 | int sr_wm, cursor_wm; | ||
3272 | unsigned long line_time_us; | ||
3273 | int sr_clock, entries_required; | ||
3274 | u32 reg_value; | ||
3275 | int line_count; | ||
3276 | int planea_htotal = 0, planeb_htotal = 0; | ||
3277 | struct drm_crtc *crtc; | 3319 | struct drm_crtc *crtc; |
3320 | int htotal, hdisplay, clock, pixel_size = 0; | ||
3321 | int line_time_us, line_count, entries; | ||
3278 | 3322 | ||
3279 | /* Need htotal for all active display plane */ | 3323 | crtc = intel_get_crtc_for_pipe(dev, pipe); |
3280 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3324 | if (crtc->fb == NULL || !crtc->enabled) |
3281 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3325 | return false; |
3282 | if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { | ||
3283 | if (intel_crtc->plane == 0) | ||
3284 | planea_htotal = crtc->mode.htotal; | ||
3285 | else | ||
3286 | planeb_htotal = crtc->mode.htotal; | ||
3287 | } | ||
3288 | } | ||
3289 | |||
3290 | /* Calculate and update the watermark for plane A */ | ||
3291 | if (planea_clock) { | ||
3292 | entries_required = ((planea_clock / 1000) * pixel_size * | ||
3293 | ILK_LP0_PLANE_LATENCY) / 1000; | ||
3294 | entries_required = DIV_ROUND_UP(entries_required, | ||
3295 | ironlake_display_wm_info.cacheline_size); | ||
3296 | planea_wm = entries_required + | ||
3297 | ironlake_display_wm_info.guard_size; | ||
3298 | |||
3299 | if (planea_wm > (int)ironlake_display_wm_info.max_wm) | ||
3300 | planea_wm = ironlake_display_wm_info.max_wm; | ||
3301 | |||
3302 | /* Use the large buffer method to calculate cursor watermark */ | ||
3303 | line_time_us = (planea_htotal * 1000) / planea_clock; | ||
3304 | |||
3305 | /* Use ns/us then divide to preserve precision */ | ||
3306 | line_count = (ILK_LP0_CURSOR_LATENCY / line_time_us + 1000) / 1000; | ||
3307 | |||
3308 | /* calculate the cursor watermark for cursor A */ | ||
3309 | entries_required = line_count * 64 * pixel_size; | ||
3310 | entries_required = DIV_ROUND_UP(entries_required, | ||
3311 | ironlake_cursor_wm_info.cacheline_size); | ||
3312 | cursora_wm = entries_required + ironlake_cursor_wm_info.guard_size; | ||
3313 | if (cursora_wm > ironlake_cursor_wm_info.max_wm) | ||
3314 | cursora_wm = ironlake_cursor_wm_info.max_wm; | ||
3315 | |||
3316 | reg_value = I915_READ(WM0_PIPEA_ILK); | ||
3317 | reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | ||
3318 | reg_value |= (planea_wm << WM0_PIPE_PLANE_SHIFT) | | ||
3319 | (cursora_wm & WM0_PIPE_CURSOR_MASK); | ||
3320 | I915_WRITE(WM0_PIPEA_ILK, reg_value); | ||
3321 | DRM_DEBUG_KMS("FIFO watermarks For pipe A - plane %d, " | ||
3322 | "cursor: %d\n", planea_wm, cursora_wm); | ||
3323 | } | ||
3324 | /* Calculate and update the watermark for plane B */ | ||
3325 | if (planeb_clock) { | ||
3326 | entries_required = ((planeb_clock / 1000) * pixel_size * | ||
3327 | ILK_LP0_PLANE_LATENCY) / 1000; | ||
3328 | entries_required = DIV_ROUND_UP(entries_required, | ||
3329 | ironlake_display_wm_info.cacheline_size); | ||
3330 | planeb_wm = entries_required + | ||
3331 | ironlake_display_wm_info.guard_size; | ||
3332 | |||
3333 | if (planeb_wm > (int)ironlake_display_wm_info.max_wm) | ||
3334 | planeb_wm = ironlake_display_wm_info.max_wm; | ||
3335 | 3326 | ||
3336 | /* Use the large buffer method to calculate cursor watermark */ | 3327 | htotal = crtc->mode.htotal; |
3337 | line_time_us = (planeb_htotal * 1000) / planeb_clock; | 3328 | hdisplay = crtc->mode.hdisplay; |
3329 | clock = crtc->mode.clock; | ||
3330 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
3331 | |||
3332 | /* Use the small buffer method to calculate plane watermark */ | ||
3333 | entries = ((clock * pixel_size / 1000) * ILK_LP0_PLANE_LATENCY) / 1000; | ||
3334 | entries = DIV_ROUND_UP(entries, | ||
3335 | ironlake_display_wm_info.cacheline_size); | ||
3336 | *plane_wm = entries + ironlake_display_wm_info.guard_size; | ||
3337 | if (*plane_wm > (int)ironlake_display_wm_info.max_wm) | ||
3338 | *plane_wm = ironlake_display_wm_info.max_wm; | ||
3339 | |||
3340 | /* Use the large buffer method to calculate cursor watermark */ | ||
3341 | line_time_us = ((htotal * 1000) / clock); | ||
3342 | line_count = (ILK_LP0_CURSOR_LATENCY / line_time_us + 1000) / 1000; | ||
3343 | entries = line_count * 64 * pixel_size; | ||
3344 | entries = DIV_ROUND_UP(entries, | ||
3345 | ironlake_cursor_wm_info.cacheline_size); | ||
3346 | *cursor_wm = entries + ironlake_cursor_wm_info.guard_size; | ||
3347 | if (*cursor_wm > ironlake_cursor_wm_info.max_wm) | ||
3348 | *cursor_wm = ironlake_cursor_wm_info.max_wm; | ||
3338 | 3349 | ||
3339 | /* Use ns/us then divide to preserve precision */ | 3350 | return true; |
3340 | line_count = (ILK_LP0_CURSOR_LATENCY / line_time_us + 1000) / 1000; | 3351 | } |
3341 | 3352 | ||
3342 | /* calculate the cursor watermark for cursor B */ | 3353 | static void ironlake_update_wm(struct drm_device *dev, |
3343 | entries_required = line_count * 64 * pixel_size; | 3354 | int planea_clock, int planeb_clock, |
3344 | entries_required = DIV_ROUND_UP(entries_required, | 3355 | int sr_hdisplay, int sr_htotal, |
3345 | ironlake_cursor_wm_info.cacheline_size); | 3356 | int pixel_size) |
3346 | cursorb_wm = entries_required + ironlake_cursor_wm_info.guard_size; | 3357 | { |
3347 | if (cursorb_wm > ironlake_cursor_wm_info.max_wm) | 3358 | struct drm_i915_private *dev_priv = dev->dev_private; |
3348 | cursorb_wm = ironlake_cursor_wm_info.max_wm; | 3359 | int plane_wm, cursor_wm, enabled; |
3360 | int tmp; | ||
3361 | |||
3362 | enabled = 0; | ||
3363 | if (ironlake_compute_wm0(dev, 0, &plane_wm, &cursor_wm)) { | ||
3364 | I915_WRITE(WM0_PIPEA_ILK, | ||
3365 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | ||
3366 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | ||
3367 | " plane %d, " "cursor: %d\n", | ||
3368 | plane_wm, cursor_wm); | ||
3369 | enabled++; | ||
3370 | } | ||
3349 | 3371 | ||
3350 | reg_value = I915_READ(WM0_PIPEB_ILK); | 3372 | if (ironlake_compute_wm0(dev, 1, &plane_wm, &cursor_wm)) { |
3351 | reg_value &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); | 3373 | I915_WRITE(WM0_PIPEB_ILK, |
3352 | reg_value |= (planeb_wm << WM0_PIPE_PLANE_SHIFT) | | 3374 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); |
3353 | (cursorb_wm & WM0_PIPE_CURSOR_MASK); | 3375 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" |
3354 | I915_WRITE(WM0_PIPEB_ILK, reg_value); | 3376 | " plane %d, cursor: %d\n", |
3355 | DRM_DEBUG_KMS("FIFO watermarks For pipe B - plane %d, " | 3377 | plane_wm, cursor_wm); |
3356 | "cursor: %d\n", planeb_wm, cursorb_wm); | 3378 | enabled++; |
3357 | } | 3379 | } |
3358 | 3380 | ||
3359 | /* | 3381 | /* |
3360 | * Calculate and update the self-refresh watermark only when one | 3382 | * Calculate and update the self-refresh watermark only when one |
3361 | * display plane is used. | 3383 | * display plane is used. |
3362 | */ | 3384 | */ |
3363 | if (!planea_clock || !planeb_clock) { | 3385 | tmp = 0; |
3364 | 3386 | if (enabled == 1 && /* XXX disabled due to buggy implmentation? */ 0) { | |
3387 | unsigned long line_time_us; | ||
3388 | int small, large, plane_fbc; | ||
3389 | int sr_clock, entries; | ||
3390 | int line_count, line_size; | ||
3365 | /* Read the self-refresh latency. The unit is 0.5us */ | 3391 | /* Read the self-refresh latency. The unit is 0.5us */ |
3366 | int ilk_sr_latency = I915_READ(MLTR_ILK) & ILK_SRLT_MASK; | 3392 | int ilk_sr_latency = I915_READ(MLTR_ILK) & ILK_SRLT_MASK; |
3367 | 3393 | ||
3368 | sr_clock = planea_clock ? planea_clock : planeb_clock; | 3394 | sr_clock = planea_clock ? planea_clock : planeb_clock; |
3369 | line_time_us = ((sr_htotal * 1000) / sr_clock); | 3395 | line_time_us = (sr_htotal * 1000) / sr_clock; |
3370 | 3396 | ||
3371 | /* Use ns/us then divide to preserve precision */ | 3397 | /* Use ns/us then divide to preserve precision */ |
3372 | line_count = ((ilk_sr_latency * 500) / line_time_us + 1000) | 3398 | line_count = ((ilk_sr_latency * 500) / line_time_us + 1000) |
3373 | / 1000; | 3399 | / 1000; |
3400 | line_size = sr_hdisplay * pixel_size; | ||
3374 | 3401 | ||
3375 | /* calculate the self-refresh watermark for display plane */ | 3402 | /* Use the minimum of the small and large buffer method for primary */ |
3376 | entries_required = line_count * sr_hdisplay * pixel_size; | 3403 | small = ((sr_clock * pixel_size / 1000) * (ilk_sr_latency * 500)) / 1000; |
3377 | entries_required = DIV_ROUND_UP(entries_required, | 3404 | large = line_count * line_size; |
3378 | ironlake_display_srwm_info.cacheline_size); | ||
3379 | sr_wm = entries_required + | ||
3380 | ironlake_display_srwm_info.guard_size; | ||
3381 | 3405 | ||
3382 | /* calculate the self-refresh watermark for display cursor */ | 3406 | entries = DIV_ROUND_UP(min(small, large), |
3383 | entries_required = line_count * pixel_size * 64; | 3407 | ironlake_display_srwm_info.cacheline_size); |
3384 | entries_required = DIV_ROUND_UP(entries_required, | ||
3385 | ironlake_cursor_srwm_info.cacheline_size); | ||
3386 | cursor_wm = entries_required + | ||
3387 | ironlake_cursor_srwm_info.guard_size; | ||
3388 | 3408 | ||
3389 | /* configure watermark and enable self-refresh */ | 3409 | plane_fbc = entries * 64; |
3390 | reg_value = I915_READ(WM1_LP_ILK); | 3410 | plane_fbc = DIV_ROUND_UP(plane_fbc, line_size); |
3391 | reg_value &= ~(WM1_LP_LATENCY_MASK | WM1_LP_SR_MASK | | ||
3392 | WM1_LP_CURSOR_MASK); | ||
3393 | reg_value |= (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) | | ||
3394 | (sr_wm << WM1_LP_SR_SHIFT) | cursor_wm; | ||
3395 | 3411 | ||
3396 | I915_WRITE(WM1_LP_ILK, reg_value); | 3412 | plane_wm = entries + ironlake_display_srwm_info.guard_size; |
3397 | DRM_DEBUG_KMS("self-refresh watermark: display plane %d " | 3413 | if (plane_wm > (int)ironlake_display_srwm_info.max_wm) |
3398 | "cursor %d\n", sr_wm, cursor_wm); | 3414 | plane_wm = ironlake_display_srwm_info.max_wm; |
3399 | 3415 | ||
3400 | } else { | 3416 | /* calculate the self-refresh watermark for display cursor */ |
3401 | /* Turn off self refresh if both pipes are enabled */ | 3417 | entries = line_count * pixel_size * 64; |
3402 | I915_WRITE(WM1_LP_ILK, I915_READ(WM1_LP_ILK) & ~WM1_LP_SR_EN); | 3418 | entries = DIV_ROUND_UP(entries, |
3403 | } | 3419 | ironlake_cursor_srwm_info.cacheline_size); |
3420 | |||
3421 | cursor_wm = entries + ironlake_cursor_srwm_info.guard_size; | ||
3422 | if (cursor_wm > (int)ironlake_cursor_srwm_info.max_wm) | ||
3423 | cursor_wm = ironlake_cursor_srwm_info.max_wm; | ||
3424 | |||
3425 | /* configure watermark and enable self-refresh */ | ||
3426 | tmp = (WM1_LP_SR_EN | | ||
3427 | (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) | | ||
3428 | (plane_fbc << WM1_LP_FBC_SHIFT) | | ||
3429 | (plane_wm << WM1_LP_SR_SHIFT) | | ||
3430 | cursor_wm); | ||
3431 | DRM_DEBUG_KMS("self-refresh watermark: display plane %d, fbc lines %d," | ||
3432 | " cursor %d\n", plane_wm, plane_fbc, cursor_wm); | ||
3433 | } | ||
3434 | I915_WRITE(WM1_LP_ILK, tmp); | ||
3435 | /* XXX setup WM2 and WM3 */ | ||
3404 | } | 3436 | } |
3437 | |||
3405 | /** | 3438 | /** |
3406 | * intel_update_watermarks - update FIFO watermark values based on current modes | 3439 | * intel_update_watermarks - update FIFO watermark values based on current modes |
3407 | * | 3440 | * |
@@ -3433,7 +3466,7 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
3433 | * | 3466 | * |
3434 | * We don't use the sprite, so we can ignore that. And on Crestline we have | 3467 | * We don't use the sprite, so we can ignore that. And on Crestline we have |
3435 | * to set the non-SR watermarks to 8. | 3468 | * to set the non-SR watermarks to 8. |
3436 | */ | 3469 | */ |
3437 | static void intel_update_watermarks(struct drm_device *dev) | 3470 | static void intel_update_watermarks(struct drm_device *dev) |
3438 | { | 3471 | { |
3439 | struct drm_i915_private *dev_priv = dev->dev_private; | 3472 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -3449,15 +3482,15 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
3449 | /* Get the clock config from both planes */ | 3482 | /* Get the clock config from both planes */ |
3450 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3483 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
3451 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3484 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3452 | if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { | 3485 | if (intel_crtc->active) { |
3453 | enabled++; | 3486 | enabled++; |
3454 | if (intel_crtc->plane == 0) { | 3487 | if (intel_crtc->plane == 0) { |
3455 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", | 3488 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", |
3456 | intel_crtc->pipe, crtc->mode.clock); | 3489 | intel_crtc->pipe, crtc->mode.clock); |
3457 | planea_clock = crtc->mode.clock; | 3490 | planea_clock = crtc->mode.clock; |
3458 | } else { | 3491 | } else { |
3459 | DRM_DEBUG_KMS("plane B (pipe %d) clock: %d\n", | 3492 | DRM_DEBUG_KMS("plane B (pipe %d) clock: %d\n", |
3460 | intel_crtc->pipe, crtc->mode.clock); | 3493 | intel_crtc->pipe, crtc->mode.clock); |
3461 | planeb_clock = crtc->mode.clock; | 3494 | planeb_clock = crtc->mode.clock; |
3462 | } | 3495 | } |
3463 | sr_hdisplay = crtc->mode.hdisplay; | 3496 | sr_hdisplay = crtc->mode.hdisplay; |
@@ -3488,62 +3521,35 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3488 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3521 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3489 | int pipe = intel_crtc->pipe; | 3522 | int pipe = intel_crtc->pipe; |
3490 | int plane = intel_crtc->plane; | 3523 | int plane = intel_crtc->plane; |
3491 | int fp_reg = (pipe == 0) ? FPA0 : FPB0; | 3524 | u32 fp_reg, dpll_reg; |
3492 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | ||
3493 | int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD; | ||
3494 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; | ||
3495 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; | ||
3496 | int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; | ||
3497 | int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; | ||
3498 | int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; | ||
3499 | int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; | ||
3500 | int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; | ||
3501 | int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; | ||
3502 | int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE; | ||
3503 | int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS; | ||
3504 | int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; | ||
3505 | int refclk, num_connectors = 0; | 3525 | int refclk, num_connectors = 0; |
3506 | intel_clock_t clock, reduced_clock; | 3526 | intel_clock_t clock, reduced_clock; |
3507 | u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; | 3527 | u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; |
3508 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; | 3528 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; |
3509 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 3529 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
3510 | struct intel_encoder *has_edp_encoder = NULL; | 3530 | struct intel_encoder *has_edp_encoder = NULL; |
3511 | struct drm_mode_config *mode_config = &dev->mode_config; | 3531 | struct drm_mode_config *mode_config = &dev->mode_config; |
3512 | struct drm_encoder *encoder; | 3532 | struct intel_encoder *encoder; |
3513 | const intel_limit_t *limit; | 3533 | const intel_limit_t *limit; |
3514 | int ret; | 3534 | int ret; |
3515 | struct fdi_m_n m_n = {0}; | 3535 | struct fdi_m_n m_n = {0}; |
3516 | int data_m1_reg = (pipe == 0) ? PIPEA_DATA_M1 : PIPEB_DATA_M1; | 3536 | u32 reg, temp; |
3517 | int data_n1_reg = (pipe == 0) ? PIPEA_DATA_N1 : PIPEB_DATA_N1; | ||
3518 | int link_m1_reg = (pipe == 0) ? PIPEA_LINK_M1 : PIPEB_LINK_M1; | ||
3519 | int link_n1_reg = (pipe == 0) ? PIPEA_LINK_N1 : PIPEB_LINK_N1; | ||
3520 | int pch_fp_reg = (pipe == 0) ? PCH_FPA0 : PCH_FPB0; | ||
3521 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; | ||
3522 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; | ||
3523 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; | ||
3524 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; | ||
3525 | int lvds_reg = LVDS; | ||
3526 | u32 temp; | ||
3527 | int sdvo_pixel_multiply; | ||
3528 | int target_clock; | 3537 | int target_clock; |
3529 | 3538 | ||
3530 | drm_vblank_pre_modeset(dev, pipe); | 3539 | drm_vblank_pre_modeset(dev, pipe); |
3531 | 3540 | ||
3532 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 3541 | list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { |
3533 | struct intel_encoder *intel_encoder; | 3542 | if (encoder->base.crtc != crtc) |
3534 | |||
3535 | if (encoder->crtc != crtc) | ||
3536 | continue; | 3543 | continue; |
3537 | 3544 | ||
3538 | intel_encoder = enc_to_intel_encoder(encoder); | 3545 | switch (encoder->type) { |
3539 | switch (intel_encoder->type) { | ||
3540 | case INTEL_OUTPUT_LVDS: | 3546 | case INTEL_OUTPUT_LVDS: |
3541 | is_lvds = true; | 3547 | is_lvds = true; |
3542 | break; | 3548 | break; |
3543 | case INTEL_OUTPUT_SDVO: | 3549 | case INTEL_OUTPUT_SDVO: |
3544 | case INTEL_OUTPUT_HDMI: | 3550 | case INTEL_OUTPUT_HDMI: |
3545 | is_sdvo = true; | 3551 | is_sdvo = true; |
3546 | if (intel_encoder->needs_tv_clock) | 3552 | if (encoder->needs_tv_clock) |
3547 | is_tv = true; | 3553 | is_tv = true; |
3548 | break; | 3554 | break; |
3549 | case INTEL_OUTPUT_DVO: | 3555 | case INTEL_OUTPUT_DVO: |
@@ -3559,7 +3565,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3559 | is_dp = true; | 3565 | is_dp = true; |
3560 | break; | 3566 | break; |
3561 | case INTEL_OUTPUT_EDP: | 3567 | case INTEL_OUTPUT_EDP: |
3562 | has_edp_encoder = intel_encoder; | 3568 | has_edp_encoder = encoder; |
3563 | break; | 3569 | break; |
3564 | } | 3570 | } |
3565 | 3571 | ||
@@ -3569,7 +3575,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3569 | if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) { | 3575 | if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) { |
3570 | refclk = dev_priv->lvds_ssc_freq * 1000; | 3576 | refclk = dev_priv->lvds_ssc_freq * 1000; |
3571 | DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", | 3577 | DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", |
3572 | refclk / 1000); | 3578 | refclk / 1000); |
3573 | } else if (IS_I9XX(dev)) { | 3579 | } else if (IS_I9XX(dev)) { |
3574 | refclk = 96000; | 3580 | refclk = 96000; |
3575 | if (HAS_PCH_SPLIT(dev)) | 3581 | if (HAS_PCH_SPLIT(dev)) |
@@ -3577,7 +3583,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3577 | } else { | 3583 | } else { |
3578 | refclk = 48000; | 3584 | refclk = 48000; |
3579 | } | 3585 | } |
3580 | |||
3581 | 3586 | ||
3582 | /* | 3587 | /* |
3583 | * Returns a set of divisors for the desired target clock with the given | 3588 | * Returns a set of divisors for the desired target clock with the given |
@@ -3593,13 +3598,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3593 | } | 3598 | } |
3594 | 3599 | ||
3595 | /* Ensure that the cursor is valid for the new mode before changing... */ | 3600 | /* Ensure that the cursor is valid for the new mode before changing... */ |
3596 | intel_crtc_update_cursor(crtc); | 3601 | intel_crtc_update_cursor(crtc, true); |
3597 | 3602 | ||
3598 | if (is_lvds && dev_priv->lvds_downclock_avail) { | 3603 | if (is_lvds && dev_priv->lvds_downclock_avail) { |
3599 | has_reduced_clock = limit->find_pll(limit, crtc, | 3604 | has_reduced_clock = limit->find_pll(limit, crtc, |
3600 | dev_priv->lvds_downclock, | 3605 | dev_priv->lvds_downclock, |
3601 | refclk, | 3606 | refclk, |
3602 | &reduced_clock); | 3607 | &reduced_clock); |
3603 | if (has_reduced_clock && (clock.p != reduced_clock.p)) { | 3608 | if (has_reduced_clock && (clock.p != reduced_clock.p)) { |
3604 | /* | 3609 | /* |
3605 | * If the different P is found, it means that we can't | 3610 | * If the different P is found, it means that we can't |
@@ -3608,7 +3613,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3608 | * feature. | 3613 | * feature. |
3609 | */ | 3614 | */ |
3610 | DRM_DEBUG_KMS("Different P is found for " | 3615 | DRM_DEBUG_KMS("Different P is found for " |
3611 | "LVDS clock/downclock\n"); | 3616 | "LVDS clock/downclock\n"); |
3612 | has_reduced_clock = 0; | 3617 | has_reduced_clock = 0; |
3613 | } | 3618 | } |
3614 | } | 3619 | } |
@@ -3616,14 +3621,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3616 | this mirrors vbios setting. */ | 3621 | this mirrors vbios setting. */ |
3617 | if (is_sdvo && is_tv) { | 3622 | if (is_sdvo && is_tv) { |
3618 | if (adjusted_mode->clock >= 100000 | 3623 | if (adjusted_mode->clock >= 100000 |
3619 | && adjusted_mode->clock < 140500) { | 3624 | && adjusted_mode->clock < 140500) { |
3620 | clock.p1 = 2; | 3625 | clock.p1 = 2; |
3621 | clock.p2 = 10; | 3626 | clock.p2 = 10; |
3622 | clock.n = 3; | 3627 | clock.n = 3; |
3623 | clock.m1 = 16; | 3628 | clock.m1 = 16; |
3624 | clock.m2 = 8; | 3629 | clock.m2 = 8; |
3625 | } else if (adjusted_mode->clock >= 140500 | 3630 | } else if (adjusted_mode->clock >= 140500 |
3626 | && adjusted_mode->clock <= 200000) { | 3631 | && adjusted_mode->clock <= 200000) { |
3627 | clock.p1 = 1; | 3632 | clock.p1 = 1; |
3628 | clock.p2 = 10; | 3633 | clock.p2 = 10; |
3629 | clock.n = 6; | 3634 | clock.n = 6; |
@@ -3648,16 +3653,23 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3648 | target_clock = mode->clock; | 3653 | target_clock = mode->clock; |
3649 | else | 3654 | else |
3650 | target_clock = adjusted_mode->clock; | 3655 | target_clock = adjusted_mode->clock; |
3651 | link_bw = 270000; | 3656 | |
3657 | /* FDI is a binary signal running at ~2.7GHz, encoding | ||
3658 | * each output octet as 10 bits. The actual frequency | ||
3659 | * is stored as a divider into a 100MHz clock, and the | ||
3660 | * mode pixel clock is stored in units of 1KHz. | ||
3661 | * Hence the bw of each lane in terms of the mode signal | ||
3662 | * is: | ||
3663 | */ | ||
3664 | link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; | ||
3652 | } | 3665 | } |
3653 | 3666 | ||
3654 | /* determine panel color depth */ | 3667 | /* determine panel color depth */ |
3655 | temp = I915_READ(pipeconf_reg); | 3668 | temp = I915_READ(PIPECONF(pipe)); |
3656 | temp &= ~PIPE_BPC_MASK; | 3669 | temp &= ~PIPE_BPC_MASK; |
3657 | if (is_lvds) { | 3670 | if (is_lvds) { |
3658 | int lvds_reg = I915_READ(PCH_LVDS); | ||
3659 | /* the BPC will be 6 if it is 18-bit LVDS panel */ | 3671 | /* the BPC will be 6 if it is 18-bit LVDS panel */ |
3660 | if ((lvds_reg & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP) | 3672 | if ((I915_READ(PCH_LVDS) & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP) |
3661 | temp |= PIPE_8BPC; | 3673 | temp |= PIPE_8BPC; |
3662 | else | 3674 | else |
3663 | temp |= PIPE_6BPC; | 3675 | temp |= PIPE_6BPC; |
@@ -3678,8 +3690,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3678 | } | 3690 | } |
3679 | } else | 3691 | } else |
3680 | temp |= PIPE_8BPC; | 3692 | temp |= PIPE_8BPC; |
3681 | I915_WRITE(pipeconf_reg, temp); | 3693 | I915_WRITE(PIPECONF(pipe), temp); |
3682 | I915_READ(pipeconf_reg); | ||
3683 | 3694 | ||
3684 | switch (temp & PIPE_BPC_MASK) { | 3695 | switch (temp & PIPE_BPC_MASK) { |
3685 | case PIPE_8BPC: | 3696 | case PIPE_8BPC: |
@@ -3724,33 +3735,27 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3724 | /* Always enable nonspread source */ | 3735 | /* Always enable nonspread source */ |
3725 | temp &= ~DREF_NONSPREAD_SOURCE_MASK; | 3736 | temp &= ~DREF_NONSPREAD_SOURCE_MASK; |
3726 | temp |= DREF_NONSPREAD_SOURCE_ENABLE; | 3737 | temp |= DREF_NONSPREAD_SOURCE_ENABLE; |
3727 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
3728 | POSTING_READ(PCH_DREF_CONTROL); | ||
3729 | |||
3730 | temp &= ~DREF_SSC_SOURCE_MASK; | 3738 | temp &= ~DREF_SSC_SOURCE_MASK; |
3731 | temp |= DREF_SSC_SOURCE_ENABLE; | 3739 | temp |= DREF_SSC_SOURCE_ENABLE; |
3732 | I915_WRITE(PCH_DREF_CONTROL, temp); | 3740 | I915_WRITE(PCH_DREF_CONTROL, temp); |
3733 | POSTING_READ(PCH_DREF_CONTROL); | ||
3734 | 3741 | ||
3742 | POSTING_READ(PCH_DREF_CONTROL); | ||
3735 | udelay(200); | 3743 | udelay(200); |
3736 | 3744 | ||
3737 | if (has_edp_encoder) { | 3745 | if (has_edp_encoder) { |
3738 | if (dev_priv->lvds_use_ssc) { | 3746 | if (dev_priv->lvds_use_ssc) { |
3739 | temp |= DREF_SSC1_ENABLE; | 3747 | temp |= DREF_SSC1_ENABLE; |
3740 | I915_WRITE(PCH_DREF_CONTROL, temp); | 3748 | I915_WRITE(PCH_DREF_CONTROL, temp); |
3741 | POSTING_READ(PCH_DREF_CONTROL); | ||
3742 | 3749 | ||
3750 | POSTING_READ(PCH_DREF_CONTROL); | ||
3743 | udelay(200); | 3751 | udelay(200); |
3744 | 3752 | ||
3745 | temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; | 3753 | temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; |
3746 | temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; | 3754 | temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; |
3747 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
3748 | POSTING_READ(PCH_DREF_CONTROL); | ||
3749 | } else { | 3755 | } else { |
3750 | temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; | 3756 | temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; |
3751 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
3752 | POSTING_READ(PCH_DREF_CONTROL); | ||
3753 | } | 3757 | } |
3758 | I915_WRITE(PCH_DREF_CONTROL, temp); | ||
3754 | } | 3759 | } |
3755 | } | 3760 | } |
3756 | 3761 | ||
@@ -3766,6 +3771,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3766 | reduced_clock.m2; | 3771 | reduced_clock.m2; |
3767 | } | 3772 | } |
3768 | 3773 | ||
3774 | dpll = 0; | ||
3769 | if (!HAS_PCH_SPLIT(dev)) | 3775 | if (!HAS_PCH_SPLIT(dev)) |
3770 | dpll = DPLL_VGA_MODE_DIS; | 3776 | dpll = DPLL_VGA_MODE_DIS; |
3771 | 3777 | ||
@@ -3775,12 +3781,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3775 | else | 3781 | else |
3776 | dpll |= DPLLB_MODE_DAC_SERIAL; | 3782 | dpll |= DPLLB_MODE_DAC_SERIAL; |
3777 | if (is_sdvo) { | 3783 | if (is_sdvo) { |
3784 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | ||
3785 | if (pixel_multiplier > 1) { | ||
3786 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | ||
3787 | dpll |= (pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; | ||
3788 | else if (HAS_PCH_SPLIT(dev)) | ||
3789 | dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; | ||
3790 | } | ||
3778 | dpll |= DPLL_DVO_HIGH_SPEED; | 3791 | dpll |= DPLL_DVO_HIGH_SPEED; |
3779 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | ||
3780 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | ||
3781 | dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; | ||
3782 | else if (HAS_PCH_SPLIT(dev)) | ||
3783 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; | ||
3784 | } | 3792 | } |
3785 | if (is_dp) | 3793 | if (is_dp) |
3786 | dpll |= DPLL_DVO_HIGH_SPEED; | 3794 | dpll |= DPLL_DVO_HIGH_SPEED; |
@@ -3837,7 +3845,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3837 | dpll |= PLL_REF_INPUT_DREFCLK; | 3845 | dpll |= PLL_REF_INPUT_DREFCLK; |
3838 | 3846 | ||
3839 | /* setup pipeconf */ | 3847 | /* setup pipeconf */ |
3840 | pipeconf = I915_READ(pipeconf_reg); | 3848 | pipeconf = I915_READ(PIPECONF(pipe)); |
3841 | 3849 | ||
3842 | /* Set up the display plane register */ | 3850 | /* Set up the display plane register */ |
3843 | dspcntr = DISPPLANE_GAMMA_ENABLE; | 3851 | dspcntr = DISPPLANE_GAMMA_ENABLE; |
@@ -3860,51 +3868,46 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3860 | */ | 3868 | */ |
3861 | if (mode->clock > | 3869 | if (mode->clock > |
3862 | dev_priv->display.get_display_clock_speed(dev) * 9 / 10) | 3870 | dev_priv->display.get_display_clock_speed(dev) * 9 / 10) |
3863 | pipeconf |= PIPEACONF_DOUBLE_WIDE; | 3871 | pipeconf |= PIPECONF_DOUBLE_WIDE; |
3864 | else | 3872 | else |
3865 | pipeconf &= ~PIPEACONF_DOUBLE_WIDE; | 3873 | pipeconf &= ~PIPECONF_DOUBLE_WIDE; |
3866 | } | 3874 | } |
3867 | 3875 | ||
3868 | dspcntr |= DISPLAY_PLANE_ENABLE; | 3876 | dspcntr |= DISPLAY_PLANE_ENABLE; |
3869 | pipeconf |= PIPEACONF_ENABLE; | 3877 | pipeconf |= PIPECONF_ENABLE; |
3870 | dpll |= DPLL_VCO_ENABLE; | 3878 | dpll |= DPLL_VCO_ENABLE; |
3871 | 3879 | ||
3872 | |||
3873 | /* Disable the panel fitter if it was on our pipe */ | ||
3874 | if (!HAS_PCH_SPLIT(dev) && intel_panel_fitter_pipe(dev) == pipe) | ||
3875 | I915_WRITE(PFIT_CONTROL, 0); | ||
3876 | |||
3877 | DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); | 3880 | DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); |
3878 | drm_mode_debug_printmodeline(mode); | 3881 | drm_mode_debug_printmodeline(mode); |
3879 | 3882 | ||
3880 | /* assign to Ironlake registers */ | 3883 | /* assign to Ironlake registers */ |
3881 | if (HAS_PCH_SPLIT(dev)) { | 3884 | if (HAS_PCH_SPLIT(dev)) { |
3882 | fp_reg = pch_fp_reg; | 3885 | fp_reg = PCH_FP0(pipe); |
3883 | dpll_reg = pch_dpll_reg; | 3886 | dpll_reg = PCH_DPLL(pipe); |
3887 | } else { | ||
3888 | fp_reg = FP0(pipe); | ||
3889 | dpll_reg = DPLL(pipe); | ||
3884 | } | 3890 | } |
3885 | 3891 | ||
3886 | if (!has_edp_encoder) { | 3892 | if (!has_edp_encoder) { |
3887 | I915_WRITE(fp_reg, fp); | 3893 | I915_WRITE(fp_reg, fp); |
3888 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); | 3894 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); |
3889 | I915_READ(dpll_reg); | 3895 | |
3896 | POSTING_READ(dpll_reg); | ||
3890 | udelay(150); | 3897 | udelay(150); |
3891 | } | 3898 | } |
3892 | 3899 | ||
3893 | /* enable transcoder DPLL */ | 3900 | /* enable transcoder DPLL */ |
3894 | if (HAS_PCH_CPT(dev)) { | 3901 | if (HAS_PCH_CPT(dev)) { |
3895 | temp = I915_READ(PCH_DPLL_SEL); | 3902 | temp = I915_READ(PCH_DPLL_SEL); |
3896 | if (trans_dpll_sel == 0) | 3903 | if (pipe == 0) |
3897 | temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL); | 3904 | temp |= TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL; |
3898 | else | 3905 | else |
3899 | temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); | 3906 | temp |= TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL; |
3900 | I915_WRITE(PCH_DPLL_SEL, temp); | 3907 | I915_WRITE(PCH_DPLL_SEL, temp); |
3901 | I915_READ(PCH_DPLL_SEL); | ||
3902 | udelay(150); | ||
3903 | } | ||
3904 | 3908 | ||
3905 | if (HAS_PCH_SPLIT(dev)) { | 3909 | POSTING_READ(PCH_DPLL_SEL); |
3906 | pipeconf &= ~PIPE_ENABLE_DITHER; | 3910 | udelay(150); |
3907 | pipeconf &= ~PIPE_DITHER_TYPE_MASK; | ||
3908 | } | 3911 | } |
3909 | 3912 | ||
3910 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. | 3913 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
@@ -3912,55 +3915,57 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3912 | * things on. | 3915 | * things on. |
3913 | */ | 3916 | */ |
3914 | if (is_lvds) { | 3917 | if (is_lvds) { |
3915 | u32 lvds; | 3918 | reg = LVDS; |
3916 | |||
3917 | if (HAS_PCH_SPLIT(dev)) | 3919 | if (HAS_PCH_SPLIT(dev)) |
3918 | lvds_reg = PCH_LVDS; | 3920 | reg = PCH_LVDS; |
3919 | 3921 | ||
3920 | lvds = I915_READ(lvds_reg); | 3922 | temp = I915_READ(reg); |
3921 | lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; | 3923 | temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; |
3922 | if (pipe == 1) { | 3924 | if (pipe == 1) { |
3923 | if (HAS_PCH_CPT(dev)) | 3925 | if (HAS_PCH_CPT(dev)) |
3924 | lvds |= PORT_TRANS_B_SEL_CPT; | 3926 | temp |= PORT_TRANS_B_SEL_CPT; |
3925 | else | 3927 | else |
3926 | lvds |= LVDS_PIPEB_SELECT; | 3928 | temp |= LVDS_PIPEB_SELECT; |
3927 | } else { | 3929 | } else { |
3928 | if (HAS_PCH_CPT(dev)) | 3930 | if (HAS_PCH_CPT(dev)) |
3929 | lvds &= ~PORT_TRANS_SEL_MASK; | 3931 | temp &= ~PORT_TRANS_SEL_MASK; |
3930 | else | 3932 | else |
3931 | lvds &= ~LVDS_PIPEB_SELECT; | 3933 | temp &= ~LVDS_PIPEB_SELECT; |
3932 | } | 3934 | } |
3933 | /* set the corresponsding LVDS_BORDER bit */ | 3935 | /* set the corresponsding LVDS_BORDER bit */ |
3934 | lvds |= dev_priv->lvds_border_bits; | 3936 | temp |= dev_priv->lvds_border_bits; |
3935 | /* Set the B0-B3 data pairs corresponding to whether we're going to | 3937 | /* Set the B0-B3 data pairs corresponding to whether we're going to |
3936 | * set the DPLLs for dual-channel mode or not. | 3938 | * set the DPLLs for dual-channel mode or not. |
3937 | */ | 3939 | */ |
3938 | if (clock.p2 == 7) | 3940 | if (clock.p2 == 7) |
3939 | lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; | 3941 | temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; |
3940 | else | 3942 | else |
3941 | lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); | 3943 | temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); |
3942 | 3944 | ||
3943 | /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) | 3945 | /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) |
3944 | * appropriately here, but we need to look more thoroughly into how | 3946 | * appropriately here, but we need to look more thoroughly into how |
3945 | * panels behave in the two modes. | 3947 | * panels behave in the two modes. |
3946 | */ | 3948 | */ |
3947 | /* set the dithering flag */ | 3949 | /* set the dithering flag on non-PCH LVDS as needed */ |
3948 | if (IS_I965G(dev)) { | 3950 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) { |
3949 | if (dev_priv->lvds_dither) { | 3951 | if (dev_priv->lvds_dither) |
3950 | if (HAS_PCH_SPLIT(dev)) { | 3952 | temp |= LVDS_ENABLE_DITHER; |
3951 | pipeconf |= PIPE_ENABLE_DITHER; | 3953 | else |
3952 | pipeconf |= PIPE_DITHER_TYPE_ST01; | 3954 | temp &= ~LVDS_ENABLE_DITHER; |
3953 | } else | 3955 | } |
3954 | lvds |= LVDS_ENABLE_DITHER; | 3956 | I915_WRITE(reg, temp); |
3955 | } else { | 3957 | } |
3956 | if (!HAS_PCH_SPLIT(dev)) { | 3958 | |
3957 | lvds &= ~LVDS_ENABLE_DITHER; | 3959 | /* set the dithering flag and clear for anything other than a panel. */ |
3958 | } | 3960 | if (HAS_PCH_SPLIT(dev)) { |
3959 | } | 3961 | pipeconf &= ~PIPECONF_DITHER_EN; |
3962 | pipeconf &= ~PIPECONF_DITHER_TYPE_MASK; | ||
3963 | if (dev_priv->lvds_dither && (is_lvds || has_edp_encoder)) { | ||
3964 | pipeconf |= PIPECONF_DITHER_EN; | ||
3965 | pipeconf |= PIPECONF_DITHER_TYPE_ST1; | ||
3960 | } | 3966 | } |
3961 | I915_WRITE(lvds_reg, lvds); | ||
3962 | I915_READ(lvds_reg); | ||
3963 | } | 3967 | } |
3968 | |||
3964 | if (is_dp) | 3969 | if (is_dp) |
3965 | intel_dp_set_m_n(crtc, mode, adjusted_mode); | 3970 | intel_dp_set_m_n(crtc, mode, adjusted_mode); |
3966 | else if (HAS_PCH_SPLIT(dev)) { | 3971 | else if (HAS_PCH_SPLIT(dev)) { |
@@ -3981,26 +3986,32 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3981 | if (!has_edp_encoder) { | 3986 | if (!has_edp_encoder) { |
3982 | I915_WRITE(fp_reg, fp); | 3987 | I915_WRITE(fp_reg, fp); |
3983 | I915_WRITE(dpll_reg, dpll); | 3988 | I915_WRITE(dpll_reg, dpll); |
3984 | I915_READ(dpll_reg); | 3989 | |
3985 | /* Wait for the clocks to stabilize. */ | 3990 | /* Wait for the clocks to stabilize. */ |
3991 | POSTING_READ(dpll_reg); | ||
3986 | udelay(150); | 3992 | udelay(150); |
3987 | 3993 | ||
3988 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) { | 3994 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) { |
3995 | temp = 0; | ||
3989 | if (is_sdvo) { | 3996 | if (is_sdvo) { |
3990 | sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; | 3997 | temp = intel_mode_get_pixel_multiplier(adjusted_mode); |
3991 | I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | | 3998 | if (temp > 1) |
3992 | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); | 3999 | temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; |
3993 | } else | 4000 | else |
3994 | I915_WRITE(dpll_md_reg, 0); | 4001 | temp = 0; |
4002 | } | ||
4003 | I915_WRITE(DPLL_MD(pipe), temp); | ||
3995 | } else { | 4004 | } else { |
3996 | /* write it again -- the BIOS does, after all */ | 4005 | /* write it again -- the BIOS does, after all */ |
3997 | I915_WRITE(dpll_reg, dpll); | 4006 | I915_WRITE(dpll_reg, dpll); |
3998 | } | 4007 | } |
3999 | I915_READ(dpll_reg); | 4008 | |
4000 | /* Wait for the clocks to stabilize. */ | 4009 | /* Wait for the clocks to stabilize. */ |
4010 | POSTING_READ(dpll_reg); | ||
4001 | udelay(150); | 4011 | udelay(150); |
4002 | } | 4012 | } |
4003 | 4013 | ||
4014 | intel_crtc->lowfreq_avail = false; | ||
4004 | if (is_lvds && has_reduced_clock && i915_powersave) { | 4015 | if (is_lvds && has_reduced_clock && i915_powersave) { |
4005 | I915_WRITE(fp_reg + 4, fp2); | 4016 | I915_WRITE(fp_reg + 4, fp2); |
4006 | intel_crtc->lowfreq_avail = true; | 4017 | intel_crtc->lowfreq_avail = true; |
@@ -4010,7 +4021,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4010 | } | 4021 | } |
4011 | } else { | 4022 | } else { |
4012 | I915_WRITE(fp_reg + 4, fp); | 4023 | I915_WRITE(fp_reg + 4, fp); |
4013 | intel_crtc->lowfreq_avail = false; | ||
4014 | if (HAS_PIPE_CXSR(dev)) { | 4024 | if (HAS_PIPE_CXSR(dev)) { |
4015 | DRM_DEBUG_KMS("disabling CxSR downclocking\n"); | 4025 | DRM_DEBUG_KMS("disabling CxSR downclocking\n"); |
4016 | pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; | 4026 | pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; |
@@ -4029,58 +4039,72 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4029 | } else | 4039 | } else |
4030 | pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */ | 4040 | pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */ |
4031 | 4041 | ||
4032 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | | 4042 | I915_WRITE(HTOTAL(pipe), |
4043 | (adjusted_mode->crtc_hdisplay - 1) | | ||
4033 | ((adjusted_mode->crtc_htotal - 1) << 16)); | 4044 | ((adjusted_mode->crtc_htotal - 1) << 16)); |
4034 | I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | | 4045 | I915_WRITE(HBLANK(pipe), |
4046 | (adjusted_mode->crtc_hblank_start - 1) | | ||
4035 | ((adjusted_mode->crtc_hblank_end - 1) << 16)); | 4047 | ((adjusted_mode->crtc_hblank_end - 1) << 16)); |
4036 | I915_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | | 4048 | I915_WRITE(HSYNC(pipe), |
4049 | (adjusted_mode->crtc_hsync_start - 1) | | ||
4037 | ((adjusted_mode->crtc_hsync_end - 1) << 16)); | 4050 | ((adjusted_mode->crtc_hsync_end - 1) << 16)); |
4038 | I915_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | | 4051 | |
4052 | I915_WRITE(VTOTAL(pipe), | ||
4053 | (adjusted_mode->crtc_vdisplay - 1) | | ||
4039 | ((adjusted_mode->crtc_vtotal - 1) << 16)); | 4054 | ((adjusted_mode->crtc_vtotal - 1) << 16)); |
4040 | I915_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | | 4055 | I915_WRITE(VBLANK(pipe), |
4056 | (adjusted_mode->crtc_vblank_start - 1) | | ||
4041 | ((adjusted_mode->crtc_vblank_end - 1) << 16)); | 4057 | ((adjusted_mode->crtc_vblank_end - 1) << 16)); |
4042 | I915_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | | 4058 | I915_WRITE(VSYNC(pipe), |
4059 | (adjusted_mode->crtc_vsync_start - 1) | | ||
4043 | ((adjusted_mode->crtc_vsync_end - 1) << 16)); | 4060 | ((adjusted_mode->crtc_vsync_end - 1) << 16)); |
4044 | /* pipesrc and dspsize control the size that is scaled from, which should | 4061 | |
4045 | * always be the user's requested size. | 4062 | /* pipesrc and dspsize control the size that is scaled from, |
4063 | * which should always be the user's requested size. | ||
4046 | */ | 4064 | */ |
4047 | if (!HAS_PCH_SPLIT(dev)) { | 4065 | if (!HAS_PCH_SPLIT(dev)) { |
4048 | I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | | 4066 | I915_WRITE(DSPSIZE(plane), |
4049 | (mode->hdisplay - 1)); | 4067 | ((mode->vdisplay - 1) << 16) | |
4050 | I915_WRITE(dsppos_reg, 0); | 4068 | (mode->hdisplay - 1)); |
4069 | I915_WRITE(DSPPOS(plane), 0); | ||
4051 | } | 4070 | } |
4052 | I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); | 4071 | I915_WRITE(PIPESRC(pipe), |
4072 | ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); | ||
4053 | 4073 | ||
4054 | if (HAS_PCH_SPLIT(dev)) { | 4074 | if (HAS_PCH_SPLIT(dev)) { |
4055 | I915_WRITE(data_m1_reg, TU_SIZE(m_n.tu) | m_n.gmch_m); | 4075 | I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m); |
4056 | I915_WRITE(data_n1_reg, TU_SIZE(m_n.tu) | m_n.gmch_n); | 4076 | I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n); |
4057 | I915_WRITE(link_m1_reg, m_n.link_m); | 4077 | I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m); |
4058 | I915_WRITE(link_n1_reg, m_n.link_n); | 4078 | I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n); |
4059 | 4079 | ||
4060 | if (has_edp_encoder) { | 4080 | if (has_edp_encoder) { |
4061 | ironlake_set_pll_edp(crtc, adjusted_mode->clock); | 4081 | ironlake_set_pll_edp(crtc, adjusted_mode->clock); |
4062 | } else { | 4082 | } else { |
4063 | /* enable FDI RX PLL too */ | 4083 | /* enable FDI RX PLL too */ |
4064 | temp = I915_READ(fdi_rx_reg); | 4084 | reg = FDI_RX_CTL(pipe); |
4065 | I915_WRITE(fdi_rx_reg, temp | FDI_RX_PLL_ENABLE); | 4085 | temp = I915_READ(reg); |
4066 | I915_READ(fdi_rx_reg); | 4086 | I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE); |
4087 | |||
4088 | POSTING_READ(reg); | ||
4067 | udelay(200); | 4089 | udelay(200); |
4068 | 4090 | ||
4069 | /* enable FDI TX PLL too */ | 4091 | /* enable FDI TX PLL too */ |
4070 | temp = I915_READ(fdi_tx_reg); | 4092 | reg = FDI_TX_CTL(pipe); |
4071 | I915_WRITE(fdi_tx_reg, temp | FDI_TX_PLL_ENABLE); | 4093 | temp = I915_READ(reg); |
4072 | I915_READ(fdi_tx_reg); | 4094 | I915_WRITE(reg, temp | FDI_TX_PLL_ENABLE); |
4073 | 4095 | ||
4074 | /* enable FDI RX PCDCLK */ | 4096 | /* enable FDI RX PCDCLK */ |
4075 | temp = I915_READ(fdi_rx_reg); | 4097 | reg = FDI_RX_CTL(pipe); |
4076 | I915_WRITE(fdi_rx_reg, temp | FDI_SEL_PCDCLK); | 4098 | temp = I915_READ(reg); |
4077 | I915_READ(fdi_rx_reg); | 4099 | I915_WRITE(reg, temp | FDI_PCDCLK); |
4100 | |||
4101 | POSTING_READ(reg); | ||
4078 | udelay(200); | 4102 | udelay(200); |
4079 | } | 4103 | } |
4080 | } | 4104 | } |
4081 | 4105 | ||
4082 | I915_WRITE(pipeconf_reg, pipeconf); | 4106 | I915_WRITE(PIPECONF(pipe), pipeconf); |
4083 | I915_READ(pipeconf_reg); | 4107 | POSTING_READ(PIPECONF(pipe)); |
4084 | 4108 | ||
4085 | intel_wait_for_vblank(dev, pipe); | 4109 | intel_wait_for_vblank(dev, pipe); |
4086 | 4110 | ||
@@ -4090,9 +4114,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4090 | I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING); | 4114 | I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING); |
4091 | } | 4115 | } |
4092 | 4116 | ||
4093 | I915_WRITE(dspcntr_reg, dspcntr); | 4117 | I915_WRITE(DSPCNTR(plane), dspcntr); |
4094 | 4118 | ||
4095 | /* Flush the plane changes */ | ||
4096 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 4119 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
4097 | 4120 | ||
4098 | intel_update_watermarks(dev); | 4121 | intel_update_watermarks(dev); |
@@ -4185,7 +4208,8 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) | |||
4185 | } | 4208 | } |
4186 | 4209 | ||
4187 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ | 4210 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ |
4188 | static void intel_crtc_update_cursor(struct drm_crtc *crtc) | 4211 | static void intel_crtc_update_cursor(struct drm_crtc *crtc, |
4212 | bool on) | ||
4189 | { | 4213 | { |
4190 | struct drm_device *dev = crtc->dev; | 4214 | struct drm_device *dev = crtc->dev; |
4191 | struct drm_i915_private *dev_priv = dev->dev_private; | 4215 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -4198,7 +4222,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) | |||
4198 | 4222 | ||
4199 | pos = 0; | 4223 | pos = 0; |
4200 | 4224 | ||
4201 | if (intel_crtc->cursor_on && crtc->fb) { | 4225 | if (on && crtc->enabled && crtc->fb) { |
4202 | base = intel_crtc->cursor_addr; | 4226 | base = intel_crtc->cursor_addr; |
4203 | if (x > (int) crtc->fb->width) | 4227 | if (x > (int) crtc->fb->width) |
4204 | base = 0; | 4228 | base = 0; |
@@ -4330,7 +4354,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4330 | intel_crtc->cursor_width = width; | 4354 | intel_crtc->cursor_width = width; |
4331 | intel_crtc->cursor_height = height; | 4355 | intel_crtc->cursor_height = height; |
4332 | 4356 | ||
4333 | intel_crtc_update_cursor(crtc); | 4357 | intel_crtc_update_cursor(crtc, true); |
4334 | 4358 | ||
4335 | return 0; | 4359 | return 0; |
4336 | fail_unpin: | 4360 | fail_unpin: |
@@ -4349,7 +4373,7 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
4349 | intel_crtc->cursor_x = x; | 4373 | intel_crtc->cursor_x = x; |
4350 | intel_crtc->cursor_y = y; | 4374 | intel_crtc->cursor_y = y; |
4351 | 4375 | ||
4352 | intel_crtc_update_cursor(crtc); | 4376 | intel_crtc_update_cursor(crtc, true); |
4353 | 4377 | ||
4354 | return 0; | 4378 | return 0; |
4355 | } | 4379 | } |
@@ -4418,7 +4442,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | |||
4418 | struct intel_crtc *intel_crtc; | 4442 | struct intel_crtc *intel_crtc; |
4419 | struct drm_crtc *possible_crtc; | 4443 | struct drm_crtc *possible_crtc; |
4420 | struct drm_crtc *supported_crtc =NULL; | 4444 | struct drm_crtc *supported_crtc =NULL; |
4421 | struct drm_encoder *encoder = &intel_encoder->enc; | 4445 | struct drm_encoder *encoder = &intel_encoder->base; |
4422 | struct drm_crtc *crtc = NULL; | 4446 | struct drm_crtc *crtc = NULL; |
4423 | struct drm_device *dev = encoder->dev; | 4447 | struct drm_device *dev = encoder->dev; |
4424 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | 4448 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; |
@@ -4499,7 +4523,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | |||
4499 | void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, | 4523 | void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, |
4500 | struct drm_connector *connector, int dpms_mode) | 4524 | struct drm_connector *connector, int dpms_mode) |
4501 | { | 4525 | { |
4502 | struct drm_encoder *encoder = &intel_encoder->enc; | 4526 | struct drm_encoder *encoder = &intel_encoder->base; |
4503 | struct drm_device *dev = encoder->dev; | 4527 | struct drm_device *dev = encoder->dev; |
4504 | struct drm_crtc *crtc = encoder->crtc; | 4528 | struct drm_crtc *crtc = encoder->crtc; |
4505 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | 4529 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; |
@@ -4671,7 +4695,7 @@ static void intel_crtc_idle_timer(unsigned long arg) | |||
4671 | queue_work(dev_priv->wq, &dev_priv->idle_work); | 4695 | queue_work(dev_priv->wq, &dev_priv->idle_work); |
4672 | } | 4696 | } |
4673 | 4697 | ||
4674 | static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule) | 4698 | static void intel_increase_pllclock(struct drm_crtc *crtc) |
4675 | { | 4699 | { |
4676 | struct drm_device *dev = crtc->dev; | 4700 | struct drm_device *dev = crtc->dev; |
4677 | drm_i915_private_t *dev_priv = dev->dev_private; | 4701 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -4706,9 +4730,8 @@ static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule) | |||
4706 | } | 4730 | } |
4707 | 4731 | ||
4708 | /* Schedule downclock */ | 4732 | /* Schedule downclock */ |
4709 | if (schedule) | 4733 | mod_timer(&intel_crtc->idle_timer, jiffies + |
4710 | mod_timer(&intel_crtc->idle_timer, jiffies + | 4734 | msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); |
4711 | msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); | ||
4712 | } | 4735 | } |
4713 | 4736 | ||
4714 | static void intel_decrease_pllclock(struct drm_crtc *crtc) | 4737 | static void intel_decrease_pllclock(struct drm_crtc *crtc) |
@@ -4844,7 +4867,7 @@ void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj) | |||
4844 | I915_WRITE(FW_BLC_SELF, fw_blc_self | FW_BLC_SELF_EN_MASK); | 4867 | I915_WRITE(FW_BLC_SELF, fw_blc_self | FW_BLC_SELF_EN_MASK); |
4845 | } | 4868 | } |
4846 | /* Non-busy -> busy, upclock */ | 4869 | /* Non-busy -> busy, upclock */ |
4847 | intel_increase_pllclock(crtc, true); | 4870 | intel_increase_pllclock(crtc); |
4848 | intel_crtc->busy = true; | 4871 | intel_crtc->busy = true; |
4849 | } else { | 4872 | } else { |
4850 | /* Busy -> busy, put off timer */ | 4873 | /* Busy -> busy, put off timer */ |
@@ -4858,8 +4881,22 @@ void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj) | |||
4858 | static void intel_crtc_destroy(struct drm_crtc *crtc) | 4881 | static void intel_crtc_destroy(struct drm_crtc *crtc) |
4859 | { | 4882 | { |
4860 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4883 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
4884 | struct drm_device *dev = crtc->dev; | ||
4885 | struct intel_unpin_work *work; | ||
4886 | unsigned long flags; | ||
4887 | |||
4888 | spin_lock_irqsave(&dev->event_lock, flags); | ||
4889 | work = intel_crtc->unpin_work; | ||
4890 | intel_crtc->unpin_work = NULL; | ||
4891 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
4892 | |||
4893 | if (work) { | ||
4894 | cancel_work_sync(&work->work); | ||
4895 | kfree(work); | ||
4896 | } | ||
4861 | 4897 | ||
4862 | drm_crtc_cleanup(crtc); | 4898 | drm_crtc_cleanup(crtc); |
4899 | |||
4863 | kfree(intel_crtc); | 4900 | kfree(intel_crtc); |
4864 | } | 4901 | } |
4865 | 4902 | ||
@@ -4971,7 +5008,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4971 | struct intel_unpin_work *work; | 5008 | struct intel_unpin_work *work; |
4972 | unsigned long flags, offset; | 5009 | unsigned long flags, offset; |
4973 | int pipe = intel_crtc->pipe; | 5010 | int pipe = intel_crtc->pipe; |
4974 | u32 pf, pipesrc; | 5011 | u32 was_dirty, pf, pipesrc; |
4975 | int ret; | 5012 | int ret; |
4976 | 5013 | ||
4977 | work = kzalloc(sizeof *work, GFP_KERNEL); | 5014 | work = kzalloc(sizeof *work, GFP_KERNEL); |
@@ -5000,7 +5037,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5000 | obj = intel_fb->obj; | 5037 | obj = intel_fb->obj; |
5001 | 5038 | ||
5002 | mutex_lock(&dev->struct_mutex); | 5039 | mutex_lock(&dev->struct_mutex); |
5003 | ret = intel_pin_and_fence_fb_obj(dev, obj); | 5040 | was_dirty = obj->write_domain & I915_GEM_GPU_DOMAINS; |
5041 | ret = intel_pin_and_fence_fb_obj(dev, obj, true); | ||
5004 | if (ret) | 5042 | if (ret) |
5005 | goto cleanup_work; | 5043 | goto cleanup_work; |
5006 | 5044 | ||
@@ -5009,9 +5047,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5009 | drm_gem_object_reference(obj); | 5047 | drm_gem_object_reference(obj); |
5010 | 5048 | ||
5011 | crtc->fb = fb; | 5049 | crtc->fb = fb; |
5012 | ret = i915_gem_object_flush_write_domain(obj); | ||
5013 | if (ret) | ||
5014 | goto cleanup_objs; | ||
5015 | 5050 | ||
5016 | ret = drm_vblank_get(dev, intel_crtc->pipe); | 5051 | ret = drm_vblank_get(dev, intel_crtc->pipe); |
5017 | if (ret) | 5052 | if (ret) |
@@ -5021,17 +5056,24 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5021 | atomic_inc(&obj_priv->pending_flip); | 5056 | atomic_inc(&obj_priv->pending_flip); |
5022 | work->pending_flip_obj = obj; | 5057 | work->pending_flip_obj = obj; |
5023 | 5058 | ||
5024 | if (IS_GEN3(dev) || IS_GEN2(dev)) { | 5059 | if (was_dirty || IS_GEN3(dev) || IS_GEN2(dev)) { |
5025 | u32 flip_mask; | 5060 | BEGIN_LP_RING(2); |
5061 | if (IS_GEN3(dev) || IS_GEN2(dev)) { | ||
5062 | u32 flip_mask; | ||
5026 | 5063 | ||
5027 | if (intel_crtc->plane) | 5064 | /* Can't queue multiple flips, so wait for the previous |
5028 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; | 5065 | * one to finish before executing the next. |
5029 | else | 5066 | */ |
5030 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; | ||
5031 | 5067 | ||
5032 | BEGIN_LP_RING(2); | 5068 | if (intel_crtc->plane) |
5033 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); | 5069 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; |
5034 | OUT_RING(0); | 5070 | else |
5071 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; | ||
5072 | |||
5073 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); | ||
5074 | } else | ||
5075 | OUT_RING(MI_NOOP); | ||
5076 | OUT_RING(MI_FLUSH); | ||
5035 | ADVANCE_LP_RING(); | 5077 | ADVANCE_LP_RING(); |
5036 | } | 5078 | } |
5037 | 5079 | ||
@@ -5112,14 +5154,12 @@ cleanup_work: | |||
5112 | return ret; | 5154 | return ret; |
5113 | } | 5155 | } |
5114 | 5156 | ||
5115 | static const struct drm_crtc_helper_funcs intel_helper_funcs = { | 5157 | static struct drm_crtc_helper_funcs intel_helper_funcs = { |
5116 | .dpms = intel_crtc_dpms, | 5158 | .dpms = intel_crtc_dpms, |
5117 | .mode_fixup = intel_crtc_mode_fixup, | 5159 | .mode_fixup = intel_crtc_mode_fixup, |
5118 | .mode_set = intel_crtc_mode_set, | 5160 | .mode_set = intel_crtc_mode_set, |
5119 | .mode_set_base = intel_pipe_set_base, | 5161 | .mode_set_base = intel_pipe_set_base, |
5120 | .mode_set_base_atomic = intel_pipe_set_base_atomic, | 5162 | .mode_set_base_atomic = intel_pipe_set_base_atomic, |
5121 | .prepare = intel_crtc_prepare, | ||
5122 | .commit = intel_crtc_commit, | ||
5123 | .load_lut = intel_crtc_load_lut, | 5163 | .load_lut = intel_crtc_load_lut, |
5124 | }; | 5164 | }; |
5125 | 5165 | ||
@@ -5146,8 +5186,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
5146 | drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs); | 5186 | drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs); |
5147 | 5187 | ||
5148 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); | 5188 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); |
5149 | intel_crtc->pipe = pipe; | ||
5150 | intel_crtc->plane = pipe; | ||
5151 | for (i = 0; i < 256; i++) { | 5189 | for (i = 0; i < 256; i++) { |
5152 | intel_crtc->lut_r[i] = i; | 5190 | intel_crtc->lut_r[i] = i; |
5153 | intel_crtc->lut_g[i] = i; | 5191 | intel_crtc->lut_g[i] = i; |
@@ -5157,9 +5195,9 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
5157 | /* Swap pipes & planes for FBC on pre-965 */ | 5195 | /* Swap pipes & planes for FBC on pre-965 */ |
5158 | intel_crtc->pipe = pipe; | 5196 | intel_crtc->pipe = pipe; |
5159 | intel_crtc->plane = pipe; | 5197 | intel_crtc->plane = pipe; |
5160 | if (IS_MOBILE(dev) && (IS_I9XX(dev) && !IS_I965G(dev))) { | 5198 | if (IS_MOBILE(dev) && IS_GEN3(dev)) { |
5161 | DRM_DEBUG_KMS("swapping pipes & planes for FBC\n"); | 5199 | DRM_DEBUG_KMS("swapping pipes & planes for FBC\n"); |
5162 | intel_crtc->plane = ((pipe == 0) ? 1 : 0); | 5200 | intel_crtc->plane = !pipe; |
5163 | } | 5201 | } |
5164 | 5202 | ||
5165 | BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || | 5203 | BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || |
@@ -5169,6 +5207,16 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
5169 | 5207 | ||
5170 | intel_crtc->cursor_addr = 0; | 5208 | intel_crtc->cursor_addr = 0; |
5171 | intel_crtc->dpms_mode = -1; | 5209 | intel_crtc->dpms_mode = -1; |
5210 | intel_crtc->active = true; /* force the pipe off on setup_init_config */ | ||
5211 | |||
5212 | if (HAS_PCH_SPLIT(dev)) { | ||
5213 | intel_helper_funcs.prepare = ironlake_crtc_prepare; | ||
5214 | intel_helper_funcs.commit = ironlake_crtc_commit; | ||
5215 | } else { | ||
5216 | intel_helper_funcs.prepare = i9xx_crtc_prepare; | ||
5217 | intel_helper_funcs.commit = i9xx_crtc_commit; | ||
5218 | } | ||
5219 | |||
5172 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); | 5220 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); |
5173 | 5221 | ||
5174 | intel_crtc->busy = false; | 5222 | intel_crtc->busy = false; |
@@ -5204,38 +5252,25 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | |||
5204 | return 0; | 5252 | return 0; |
5205 | } | 5253 | } |
5206 | 5254 | ||
5207 | struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) | ||
5208 | { | ||
5209 | struct drm_crtc *crtc = NULL; | ||
5210 | |||
5211 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
5212 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
5213 | if (intel_crtc->pipe == pipe) | ||
5214 | break; | ||
5215 | } | ||
5216 | return crtc; | ||
5217 | } | ||
5218 | |||
5219 | static int intel_encoder_clones(struct drm_device *dev, int type_mask) | 5255 | static int intel_encoder_clones(struct drm_device *dev, int type_mask) |
5220 | { | 5256 | { |
5257 | struct intel_encoder *encoder; | ||
5221 | int index_mask = 0; | 5258 | int index_mask = 0; |
5222 | struct drm_encoder *encoder; | ||
5223 | int entry = 0; | 5259 | int entry = 0; |
5224 | 5260 | ||
5225 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 5261 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { |
5226 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 5262 | if (type_mask & encoder->clone_mask) |
5227 | if (type_mask & intel_encoder->clone_mask) | ||
5228 | index_mask |= (1 << entry); | 5263 | index_mask |= (1 << entry); |
5229 | entry++; | 5264 | entry++; |
5230 | } | 5265 | } |
5266 | |||
5231 | return index_mask; | 5267 | return index_mask; |
5232 | } | 5268 | } |
5233 | 5269 | ||
5234 | |||
5235 | static void intel_setup_outputs(struct drm_device *dev) | 5270 | static void intel_setup_outputs(struct drm_device *dev) |
5236 | { | 5271 | { |
5237 | struct drm_i915_private *dev_priv = dev->dev_private; | 5272 | struct drm_i915_private *dev_priv = dev->dev_private; |
5238 | struct drm_encoder *encoder; | 5273 | struct intel_encoder *encoder; |
5239 | bool dpd_is_edp = false; | 5274 | bool dpd_is_edp = false; |
5240 | 5275 | ||
5241 | if (IS_MOBILE(dev) && !IS_I830(dev)) | 5276 | if (IS_MOBILE(dev) && !IS_I830(dev)) |
@@ -5324,12 +5359,10 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
5324 | if (SUPPORTS_TV(dev)) | 5359 | if (SUPPORTS_TV(dev)) |
5325 | intel_tv_init(dev); | 5360 | intel_tv_init(dev); |
5326 | 5361 | ||
5327 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 5362 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { |
5328 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 5363 | encoder->base.possible_crtcs = encoder->crtc_mask; |
5329 | 5364 | encoder->base.possible_clones = | |
5330 | encoder->possible_crtcs = intel_encoder->crtc_mask; | 5365 | intel_encoder_clones(dev, encoder->clone_mask); |
5331 | encoder->possible_clones = intel_encoder_clones(dev, | ||
5332 | intel_encoder->clone_mask); | ||
5333 | } | 5366 | } |
5334 | } | 5367 | } |
5335 | 5368 | ||
@@ -5363,8 +5396,25 @@ int intel_framebuffer_init(struct drm_device *dev, | |||
5363 | struct drm_mode_fb_cmd *mode_cmd, | 5396 | struct drm_mode_fb_cmd *mode_cmd, |
5364 | struct drm_gem_object *obj) | 5397 | struct drm_gem_object *obj) |
5365 | { | 5398 | { |
5399 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
5366 | int ret; | 5400 | int ret; |
5367 | 5401 | ||
5402 | if (obj_priv->tiling_mode == I915_TILING_Y) | ||
5403 | return -EINVAL; | ||
5404 | |||
5405 | if (mode_cmd->pitch & 63) | ||
5406 | return -EINVAL; | ||
5407 | |||
5408 | switch (mode_cmd->bpp) { | ||
5409 | case 8: | ||
5410 | case 16: | ||
5411 | case 24: | ||
5412 | case 32: | ||
5413 | break; | ||
5414 | default: | ||
5415 | return -EINVAL; | ||
5416 | } | ||
5417 | |||
5368 | ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs); | 5418 | ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs); |
5369 | if (ret) { | 5419 | if (ret) { |
5370 | DRM_ERROR("framebuffer init failed %d\n", ret); | 5420 | DRM_ERROR("framebuffer init failed %d\n", ret); |
@@ -5473,6 +5523,10 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5473 | u32 rgvmodectl = I915_READ(MEMMODECTL); | 5523 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
5474 | u8 fmax, fmin, fstart, vstart; | 5524 | u8 fmax, fmin, fstart, vstart; |
5475 | 5525 | ||
5526 | /* Enable temp reporting */ | ||
5527 | I915_WRITE16(PMMISC, I915_READ(PMMISC) | MCPPCE_EN); | ||
5528 | I915_WRITE16(TSC1, I915_READ(TSC1) | TSE); | ||
5529 | |||
5476 | /* 100ms RC evaluation intervals */ | 5530 | /* 100ms RC evaluation intervals */ |
5477 | I915_WRITE(RCUPEI, 100000); | 5531 | I915_WRITE(RCUPEI, 100000); |
5478 | I915_WRITE(RCDNEI, 100000); | 5532 | I915_WRITE(RCDNEI, 100000); |
@@ -5515,7 +5569,7 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5515 | rgvmodectl |= MEMMODE_SWMODE_EN; | 5569 | rgvmodectl |= MEMMODE_SWMODE_EN; |
5516 | I915_WRITE(MEMMODECTL, rgvmodectl); | 5570 | I915_WRITE(MEMMODECTL, rgvmodectl); |
5517 | 5571 | ||
5518 | if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 1, 0)) | 5572 | if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 10)) |
5519 | DRM_ERROR("stuck trying to change perf mode\n"); | 5573 | DRM_ERROR("stuck trying to change perf mode\n"); |
5520 | msleep(1); | 5574 | msleep(1); |
5521 | 5575 | ||
@@ -6049,12 +6103,9 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
6049 | continue; | 6103 | continue; |
6050 | 6104 | ||
6051 | intel_crtc = to_intel_crtc(crtc); | 6105 | intel_crtc = to_intel_crtc(crtc); |
6052 | intel_increase_pllclock(crtc, false); | 6106 | intel_increase_pllclock(crtc); |
6053 | del_timer_sync(&intel_crtc->idle_timer); | ||
6054 | } | 6107 | } |
6055 | 6108 | ||
6056 | del_timer_sync(&dev_priv->idle_timer); | ||
6057 | |||
6058 | if (dev_priv->display.disable_fbc) | 6109 | if (dev_priv->display.disable_fbc) |
6059 | dev_priv->display.disable_fbc(dev); | 6110 | dev_priv->display.disable_fbc(dev); |
6060 | 6111 | ||
@@ -6083,33 +6134,36 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
6083 | 6134 | ||
6084 | mutex_unlock(&dev->struct_mutex); | 6135 | mutex_unlock(&dev->struct_mutex); |
6085 | 6136 | ||
6137 | /* Disable the irq before mode object teardown, for the irq might | ||
6138 | * enqueue unpin/hotplug work. */ | ||
6139 | drm_irq_uninstall(dev); | ||
6140 | cancel_work_sync(&dev_priv->hotplug_work); | ||
6141 | |||
6142 | /* Shut off idle work before the crtcs get freed. */ | ||
6143 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
6144 | intel_crtc = to_intel_crtc(crtc); | ||
6145 | del_timer_sync(&intel_crtc->idle_timer); | ||
6146 | } | ||
6147 | del_timer_sync(&dev_priv->idle_timer); | ||
6148 | cancel_work_sync(&dev_priv->idle_work); | ||
6149 | |||
6086 | drm_mode_config_cleanup(dev); | 6150 | drm_mode_config_cleanup(dev); |
6087 | } | 6151 | } |
6088 | 6152 | ||
6089 | |||
6090 | /* | 6153 | /* |
6091 | * Return which encoder is currently attached for connector. | 6154 | * Return which encoder is currently attached for connector. |
6092 | */ | 6155 | */ |
6093 | struct drm_encoder *intel_attached_encoder (struct drm_connector *connector) | 6156 | struct drm_encoder *intel_best_encoder(struct drm_connector *connector) |
6094 | { | 6157 | { |
6095 | struct drm_mode_object *obj; | 6158 | return &intel_attached_encoder(connector)->base; |
6096 | struct drm_encoder *encoder; | 6159 | } |
6097 | int i; | ||
6098 | |||
6099 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | ||
6100 | if (connector->encoder_ids[i] == 0) | ||
6101 | break; | ||
6102 | |||
6103 | obj = drm_mode_object_find(connector->dev, | ||
6104 | connector->encoder_ids[i], | ||
6105 | DRM_MODE_OBJECT_ENCODER); | ||
6106 | if (!obj) | ||
6107 | continue; | ||
6108 | 6160 | ||
6109 | encoder = obj_to_encoder(obj); | 6161 | void intel_connector_attach_encoder(struct intel_connector *connector, |
6110 | return encoder; | 6162 | struct intel_encoder *encoder) |
6111 | } | 6163 | { |
6112 | return NULL; | 6164 | connector->encoder = encoder; |
6165 | drm_mode_connector_attach_encoder(&connector->base, | ||
6166 | &encoder->base); | ||
6113 | } | 6167 | } |
6114 | 6168 | ||
6115 | /* | 6169 | /* |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1a51ee07de3e..ec26ee7ca992 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -58,14 +58,23 @@ struct intel_dp { | |||
58 | struct i2c_adapter adapter; | 58 | struct i2c_adapter adapter; |
59 | struct i2c_algo_dp_aux_data algo; | 59 | struct i2c_algo_dp_aux_data algo; |
60 | bool is_pch_edp; | 60 | bool is_pch_edp; |
61 | uint8_t train_set[4]; | ||
62 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
61 | }; | 63 | }; |
62 | 64 | ||
63 | static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder) | 65 | static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder) |
64 | { | 66 | { |
65 | return container_of(enc_to_intel_encoder(encoder), struct intel_dp, base); | 67 | return container_of(encoder, struct intel_dp, base.base); |
68 | } | ||
69 | |||
70 | static struct intel_dp *intel_attached_dp(struct drm_connector *connector) | ||
71 | { | ||
72 | return container_of(intel_attached_encoder(connector), | ||
73 | struct intel_dp, base); | ||
66 | } | 74 | } |
67 | 75 | ||
68 | static void intel_dp_link_train(struct intel_dp *intel_dp); | 76 | static void intel_dp_start_link_train(struct intel_dp *intel_dp); |
77 | static void intel_dp_complete_link_train(struct intel_dp *intel_dp); | ||
69 | static void intel_dp_link_down(struct intel_dp *intel_dp); | 78 | static void intel_dp_link_down(struct intel_dp *intel_dp); |
70 | 79 | ||
71 | void | 80 | void |
@@ -145,8 +154,7 @@ static int | |||
145 | intel_dp_mode_valid(struct drm_connector *connector, | 154 | intel_dp_mode_valid(struct drm_connector *connector, |
146 | struct drm_display_mode *mode) | 155 | struct drm_display_mode *mode) |
147 | { | 156 | { |
148 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 157 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
149 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
150 | struct drm_device *dev = connector->dev; | 158 | struct drm_device *dev = connector->dev; |
151 | struct drm_i915_private *dev_priv = dev->dev_private; | 159 | struct drm_i915_private *dev_priv = dev->dev_private; |
152 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); | 160 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); |
@@ -233,7 +241,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
233 | uint8_t *recv, int recv_size) | 241 | uint8_t *recv, int recv_size) |
234 | { | 242 | { |
235 | uint32_t output_reg = intel_dp->output_reg; | 243 | uint32_t output_reg = intel_dp->output_reg; |
236 | struct drm_device *dev = intel_dp->base.enc.dev; | 244 | struct drm_device *dev = intel_dp->base.base.dev; |
237 | struct drm_i915_private *dev_priv = dev->dev_private; | 245 | struct drm_i915_private *dev_priv = dev->dev_private; |
238 | uint32_t ch_ctl = output_reg + 0x10; | 246 | uint32_t ch_ctl = output_reg + 0x10; |
239 | uint32_t ch_data = ch_ctl + 4; | 247 | uint32_t ch_data = ch_ctl + 4; |
@@ -246,8 +254,11 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
246 | /* The clock divider is based off the hrawclk, | 254 | /* The clock divider is based off the hrawclk, |
247 | * and would like to run at 2MHz. So, take the | 255 | * and would like to run at 2MHz. So, take the |
248 | * hrawclk value and divide by 2 and use that | 256 | * hrawclk value and divide by 2 and use that |
257 | * | ||
258 | * Note that PCH attached eDP panels should use a 125MHz input | ||
259 | * clock divider. | ||
249 | */ | 260 | */ |
250 | if (IS_eDP(intel_dp)) { | 261 | if (IS_eDP(intel_dp) && !IS_PCH_eDP(intel_dp)) { |
251 | if (IS_GEN6(dev)) | 262 | if (IS_GEN6(dev)) |
252 | aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */ | 263 | aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */ |
253 | else | 264 | else |
@@ -698,7 +709,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
698 | { | 709 | { |
699 | struct drm_device *dev = encoder->dev; | 710 | struct drm_device *dev = encoder->dev; |
700 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 711 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
701 | struct drm_crtc *crtc = intel_dp->base.enc.crtc; | 712 | struct drm_crtc *crtc = intel_dp->base.base.crtc; |
702 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 713 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
703 | 714 | ||
704 | intel_dp->DP = (DP_VOLTAGE_0_4 | | 715 | intel_dp->DP = (DP_VOLTAGE_0_4 | |
@@ -754,13 +765,14 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
754 | } | 765 | } |
755 | } | 766 | } |
756 | 767 | ||
757 | static void ironlake_edp_panel_on (struct drm_device *dev) | 768 | /* Returns true if the panel was already on when called */ |
769 | static bool ironlake_edp_panel_on (struct drm_device *dev) | ||
758 | { | 770 | { |
759 | struct drm_i915_private *dev_priv = dev->dev_private; | 771 | struct drm_i915_private *dev_priv = dev->dev_private; |
760 | u32 pp; | 772 | u32 pp; |
761 | 773 | ||
762 | if (I915_READ(PCH_PP_STATUS) & PP_ON) | 774 | if (I915_READ(PCH_PP_STATUS) & PP_ON) |
763 | return; | 775 | return true; |
764 | 776 | ||
765 | pp = I915_READ(PCH_PP_CONTROL); | 777 | pp = I915_READ(PCH_PP_CONTROL); |
766 | 778 | ||
@@ -769,17 +781,19 @@ static void ironlake_edp_panel_on (struct drm_device *dev) | |||
769 | I915_WRITE(PCH_PP_CONTROL, pp); | 781 | I915_WRITE(PCH_PP_CONTROL, pp); |
770 | POSTING_READ(PCH_PP_CONTROL); | 782 | POSTING_READ(PCH_PP_CONTROL); |
771 | 783 | ||
772 | pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON; | 784 | pp |= POWER_TARGET_ON; |
773 | I915_WRITE(PCH_PP_CONTROL, pp); | 785 | I915_WRITE(PCH_PP_CONTROL, pp); |
774 | 786 | ||
775 | if (wait_for(I915_READ(PCH_PP_STATUS) & PP_ON, 5000, 10)) | 787 | if (wait_for(I915_READ(PCH_PP_STATUS) & PP_ON, 5000)) |
776 | DRM_ERROR("panel on wait timed out: 0x%08x\n", | 788 | DRM_ERROR("panel on wait timed out: 0x%08x\n", |
777 | I915_READ(PCH_PP_STATUS)); | 789 | I915_READ(PCH_PP_STATUS)); |
778 | 790 | ||
779 | pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD); | 791 | pp &= ~(PANEL_UNLOCK_REGS); |
780 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ | 792 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ |
781 | I915_WRITE(PCH_PP_CONTROL, pp); | 793 | I915_WRITE(PCH_PP_CONTROL, pp); |
782 | POSTING_READ(PCH_PP_CONTROL); | 794 | POSTING_READ(PCH_PP_CONTROL); |
795 | |||
796 | return false; | ||
783 | } | 797 | } |
784 | 798 | ||
785 | static void ironlake_edp_panel_off (struct drm_device *dev) | 799 | static void ironlake_edp_panel_off (struct drm_device *dev) |
@@ -797,14 +811,38 @@ static void ironlake_edp_panel_off (struct drm_device *dev) | |||
797 | pp &= ~POWER_TARGET_ON; | 811 | pp &= ~POWER_TARGET_ON; |
798 | I915_WRITE(PCH_PP_CONTROL, pp); | 812 | I915_WRITE(PCH_PP_CONTROL, pp); |
799 | 813 | ||
800 | if (wait_for((I915_READ(PCH_PP_STATUS) & PP_ON) == 0, 5000, 10)) | 814 | if (wait_for((I915_READ(PCH_PP_STATUS) & PP_ON) == 0, 5000)) |
801 | DRM_ERROR("panel off wait timed out: 0x%08x\n", | 815 | DRM_ERROR("panel off wait timed out: 0x%08x\n", |
802 | I915_READ(PCH_PP_STATUS)); | 816 | I915_READ(PCH_PP_STATUS)); |
803 | 817 | ||
804 | /* Make sure VDD is enabled so DP AUX will work */ | 818 | /* Make sure VDD is enabled so DP AUX will work */ |
805 | pp |= EDP_FORCE_VDD | PANEL_POWER_RESET; /* restore panel reset bit */ | 819 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ |
820 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
821 | POSTING_READ(PCH_PP_CONTROL); | ||
822 | } | ||
823 | |||
824 | static void ironlake_edp_panel_vdd_on(struct drm_device *dev) | ||
825 | { | ||
826 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
827 | u32 pp; | ||
828 | |||
829 | pp = I915_READ(PCH_PP_CONTROL); | ||
830 | pp |= EDP_FORCE_VDD; | ||
806 | I915_WRITE(PCH_PP_CONTROL, pp); | 831 | I915_WRITE(PCH_PP_CONTROL, pp); |
807 | POSTING_READ(PCH_PP_CONTROL); | 832 | POSTING_READ(PCH_PP_CONTROL); |
833 | msleep(300); | ||
834 | } | ||
835 | |||
836 | static void ironlake_edp_panel_vdd_off(struct drm_device *dev) | ||
837 | { | ||
838 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
839 | u32 pp; | ||
840 | |||
841 | pp = I915_READ(PCH_PP_CONTROL); | ||
842 | pp &= ~EDP_FORCE_VDD; | ||
843 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
844 | POSTING_READ(PCH_PP_CONTROL); | ||
845 | msleep(300); | ||
808 | } | 846 | } |
809 | 847 | ||
810 | static void ironlake_edp_backlight_on (struct drm_device *dev) | 848 | static void ironlake_edp_backlight_on (struct drm_device *dev) |
@@ -850,6 +888,7 @@ static void ironlake_edp_pll_off(struct drm_encoder *encoder) | |||
850 | dpa_ctl = I915_READ(DP_A); | 888 | dpa_ctl = I915_READ(DP_A); |
851 | dpa_ctl |= DP_PLL_ENABLE; | 889 | dpa_ctl |= DP_PLL_ENABLE; |
852 | I915_WRITE(DP_A, dpa_ctl); | 890 | I915_WRITE(DP_A, dpa_ctl); |
891 | POSTING_READ(DP_A); | ||
853 | udelay(200); | 892 | udelay(200); |
854 | } | 893 | } |
855 | 894 | ||
@@ -860,9 +899,10 @@ static void intel_dp_prepare(struct drm_encoder *encoder) | |||
860 | struct drm_i915_private *dev_priv = dev->dev_private; | 899 | struct drm_i915_private *dev_priv = dev->dev_private; |
861 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | 900 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); |
862 | 901 | ||
863 | if (IS_eDP(intel_dp)) { | 902 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
903 | ironlake_edp_panel_off(dev); | ||
864 | ironlake_edp_backlight_off(dev); | 904 | ironlake_edp_backlight_off(dev); |
865 | ironlake_edp_panel_on(dev); | 905 | ironlake_edp_panel_vdd_on(dev); |
866 | ironlake_edp_pll_on(encoder); | 906 | ironlake_edp_pll_on(encoder); |
867 | } | 907 | } |
868 | if (dp_reg & DP_PORT_EN) | 908 | if (dp_reg & DP_PORT_EN) |
@@ -873,12 +913,14 @@ static void intel_dp_commit(struct drm_encoder *encoder) | |||
873 | { | 913 | { |
874 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 914 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
875 | struct drm_device *dev = encoder->dev; | 915 | struct drm_device *dev = encoder->dev; |
876 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
877 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | ||
878 | 916 | ||
879 | if (!(dp_reg & DP_PORT_EN)) { | 917 | intel_dp_start_link_train(intel_dp); |
880 | intel_dp_link_train(intel_dp); | 918 | |
881 | } | 919 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) |
920 | ironlake_edp_panel_on(dev); | ||
921 | |||
922 | intel_dp_complete_link_train(intel_dp); | ||
923 | |||
882 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | 924 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) |
883 | ironlake_edp_backlight_on(dev); | 925 | ironlake_edp_backlight_on(dev); |
884 | } | 926 | } |
@@ -902,9 +944,10 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
902 | ironlake_edp_pll_off(encoder); | 944 | ironlake_edp_pll_off(encoder); |
903 | } else { | 945 | } else { |
904 | if (!(dp_reg & DP_PORT_EN)) { | 946 | if (!(dp_reg & DP_PORT_EN)) { |
947 | intel_dp_start_link_train(intel_dp); | ||
905 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | 948 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) |
906 | ironlake_edp_panel_on(dev); | 949 | ironlake_edp_panel_on(dev); |
907 | intel_dp_link_train(intel_dp); | 950 | intel_dp_complete_link_train(intel_dp); |
908 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | 951 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) |
909 | ironlake_edp_backlight_on(dev); | 952 | ironlake_edp_backlight_on(dev); |
910 | } | 953 | } |
@@ -917,14 +960,13 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
917 | * link status information | 960 | * link status information |
918 | */ | 961 | */ |
919 | static bool | 962 | static bool |
920 | intel_dp_get_link_status(struct intel_dp *intel_dp, | 963 | intel_dp_get_link_status(struct intel_dp *intel_dp) |
921 | uint8_t link_status[DP_LINK_STATUS_SIZE]) | ||
922 | { | 964 | { |
923 | int ret; | 965 | int ret; |
924 | 966 | ||
925 | ret = intel_dp_aux_native_read(intel_dp, | 967 | ret = intel_dp_aux_native_read(intel_dp, |
926 | DP_LANE0_1_STATUS, | 968 | DP_LANE0_1_STATUS, |
927 | link_status, DP_LINK_STATUS_SIZE); | 969 | intel_dp->link_status, DP_LINK_STATUS_SIZE); |
928 | if (ret != DP_LINK_STATUS_SIZE) | 970 | if (ret != DP_LINK_STATUS_SIZE) |
929 | return false; | 971 | return false; |
930 | return true; | 972 | return true; |
@@ -999,18 +1041,15 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing) | |||
999 | } | 1041 | } |
1000 | 1042 | ||
1001 | static void | 1043 | static void |
1002 | intel_get_adjust_train(struct intel_dp *intel_dp, | 1044 | intel_get_adjust_train(struct intel_dp *intel_dp) |
1003 | uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
1004 | int lane_count, | ||
1005 | uint8_t train_set[4]) | ||
1006 | { | 1045 | { |
1007 | uint8_t v = 0; | 1046 | uint8_t v = 0; |
1008 | uint8_t p = 0; | 1047 | uint8_t p = 0; |
1009 | int lane; | 1048 | int lane; |
1010 | 1049 | ||
1011 | for (lane = 0; lane < lane_count; lane++) { | 1050 | for (lane = 0; lane < intel_dp->lane_count; lane++) { |
1012 | uint8_t this_v = intel_get_adjust_request_voltage(link_status, lane); | 1051 | uint8_t this_v = intel_get_adjust_request_voltage(intel_dp->link_status, lane); |
1013 | uint8_t this_p = intel_get_adjust_request_pre_emphasis(link_status, lane); | 1052 | uint8_t this_p = intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane); |
1014 | 1053 | ||
1015 | if (this_v > v) | 1054 | if (this_v > v) |
1016 | v = this_v; | 1055 | v = this_v; |
@@ -1025,7 +1064,7 @@ intel_get_adjust_train(struct intel_dp *intel_dp, | |||
1025 | p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | 1064 | p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; |
1026 | 1065 | ||
1027 | for (lane = 0; lane < 4; lane++) | 1066 | for (lane = 0; lane < 4; lane++) |
1028 | train_set[lane] = v | p; | 1067 | intel_dp->train_set[lane] = v | p; |
1029 | } | 1068 | } |
1030 | 1069 | ||
1031 | static uint32_t | 1070 | static uint32_t |
@@ -1116,18 +1155,18 @@ intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count | |||
1116 | DP_LANE_CHANNEL_EQ_DONE|\ | 1155 | DP_LANE_CHANNEL_EQ_DONE|\ |
1117 | DP_LANE_SYMBOL_LOCKED) | 1156 | DP_LANE_SYMBOL_LOCKED) |
1118 | static bool | 1157 | static bool |
1119 | intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) | 1158 | intel_channel_eq_ok(struct intel_dp *intel_dp) |
1120 | { | 1159 | { |
1121 | uint8_t lane_align; | 1160 | uint8_t lane_align; |
1122 | uint8_t lane_status; | 1161 | uint8_t lane_status; |
1123 | int lane; | 1162 | int lane; |
1124 | 1163 | ||
1125 | lane_align = intel_dp_link_status(link_status, | 1164 | lane_align = intel_dp_link_status(intel_dp->link_status, |
1126 | DP_LANE_ALIGN_STATUS_UPDATED); | 1165 | DP_LANE_ALIGN_STATUS_UPDATED); |
1127 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) | 1166 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) |
1128 | return false; | 1167 | return false; |
1129 | for (lane = 0; lane < lane_count; lane++) { | 1168 | for (lane = 0; lane < intel_dp->lane_count; lane++) { |
1130 | lane_status = intel_get_lane_status(link_status, lane); | 1169 | lane_status = intel_get_lane_status(intel_dp->link_status, lane); |
1131 | if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) | 1170 | if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) |
1132 | return false; | 1171 | return false; |
1133 | } | 1172 | } |
@@ -1138,12 +1177,11 @@ static bool | |||
1138 | intel_dp_set_link_train(struct intel_dp *intel_dp, | 1177 | intel_dp_set_link_train(struct intel_dp *intel_dp, |
1139 | uint32_t dp_reg_value, | 1178 | uint32_t dp_reg_value, |
1140 | uint8_t dp_train_pat, | 1179 | uint8_t dp_train_pat, |
1141 | uint8_t train_set[4], | ||
1142 | bool first) | 1180 | bool first) |
1143 | { | 1181 | { |
1144 | struct drm_device *dev = intel_dp->base.enc.dev; | 1182 | struct drm_device *dev = intel_dp->base.base.dev; |
1145 | struct drm_i915_private *dev_priv = dev->dev_private; | 1183 | struct drm_i915_private *dev_priv = dev->dev_private; |
1146 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); | 1184 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); |
1147 | int ret; | 1185 | int ret; |
1148 | 1186 | ||
1149 | I915_WRITE(intel_dp->output_reg, dp_reg_value); | 1187 | I915_WRITE(intel_dp->output_reg, dp_reg_value); |
@@ -1156,24 +1194,21 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, | |||
1156 | dp_train_pat); | 1194 | dp_train_pat); |
1157 | 1195 | ||
1158 | ret = intel_dp_aux_native_write(intel_dp, | 1196 | ret = intel_dp_aux_native_write(intel_dp, |
1159 | DP_TRAINING_LANE0_SET, train_set, 4); | 1197 | DP_TRAINING_LANE0_SET, intel_dp->train_set, 4); |
1160 | if (ret != 4) | 1198 | if (ret != 4) |
1161 | return false; | 1199 | return false; |
1162 | 1200 | ||
1163 | return true; | 1201 | return true; |
1164 | } | 1202 | } |
1165 | 1203 | ||
1204 | /* Enable corresponding port and start training pattern 1 */ | ||
1166 | static void | 1205 | static void |
1167 | intel_dp_link_train(struct intel_dp *intel_dp) | 1206 | intel_dp_start_link_train(struct intel_dp *intel_dp) |
1168 | { | 1207 | { |
1169 | struct drm_device *dev = intel_dp->base.enc.dev; | 1208 | struct drm_device *dev = intel_dp->base.base.dev; |
1170 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1171 | uint8_t train_set[4]; | ||
1172 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
1173 | int i; | 1209 | int i; |
1174 | uint8_t voltage; | 1210 | uint8_t voltage; |
1175 | bool clock_recovery = false; | 1211 | bool clock_recovery = false; |
1176 | bool channel_eq = false; | ||
1177 | bool first = true; | 1212 | bool first = true; |
1178 | int tries; | 1213 | int tries; |
1179 | u32 reg; | 1214 | u32 reg; |
@@ -1189,18 +1224,18 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1189 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1224 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
1190 | else | 1225 | else |
1191 | DP &= ~DP_LINK_TRAIN_MASK; | 1226 | DP &= ~DP_LINK_TRAIN_MASK; |
1192 | memset(train_set, 0, 4); | 1227 | memset(intel_dp->train_set, 0, 4); |
1193 | voltage = 0xff; | 1228 | voltage = 0xff; |
1194 | tries = 0; | 1229 | tries = 0; |
1195 | clock_recovery = false; | 1230 | clock_recovery = false; |
1196 | for (;;) { | 1231 | for (;;) { |
1197 | /* Use train_set[0] to set the voltage and pre emphasis values */ | 1232 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ |
1198 | uint32_t signal_levels; | 1233 | uint32_t signal_levels; |
1199 | if (IS_GEN6(dev) && IS_eDP(intel_dp)) { | 1234 | if (IS_GEN6(dev) && IS_eDP(intel_dp)) { |
1200 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); | 1235 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1201 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1236 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1202 | } else { | 1237 | } else { |
1203 | signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count); | 1238 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); |
1204 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1239 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1205 | } | 1240 | } |
1206 | 1241 | ||
@@ -1210,52 +1245,65 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1210 | reg = DP | DP_LINK_TRAIN_PAT_1; | 1245 | reg = DP | DP_LINK_TRAIN_PAT_1; |
1211 | 1246 | ||
1212 | if (!intel_dp_set_link_train(intel_dp, reg, | 1247 | if (!intel_dp_set_link_train(intel_dp, reg, |
1213 | DP_TRAINING_PATTERN_1, train_set, first)) | 1248 | DP_TRAINING_PATTERN_1, first)) |
1214 | break; | 1249 | break; |
1215 | first = false; | 1250 | first = false; |
1216 | /* Set training pattern 1 */ | 1251 | /* Set training pattern 1 */ |
1217 | 1252 | ||
1218 | udelay(100); | 1253 | udelay(100); |
1219 | if (!intel_dp_get_link_status(intel_dp, link_status)) | 1254 | if (!intel_dp_get_link_status(intel_dp)) |
1220 | break; | 1255 | break; |
1221 | 1256 | ||
1222 | if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { | 1257 | if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { |
1223 | clock_recovery = true; | 1258 | clock_recovery = true; |
1224 | break; | 1259 | break; |
1225 | } | 1260 | } |
1226 | 1261 | ||
1227 | /* Check to see if we've tried the max voltage */ | 1262 | /* Check to see if we've tried the max voltage */ |
1228 | for (i = 0; i < intel_dp->lane_count; i++) | 1263 | for (i = 0; i < intel_dp->lane_count; i++) |
1229 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1264 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
1230 | break; | 1265 | break; |
1231 | if (i == intel_dp->lane_count) | 1266 | if (i == intel_dp->lane_count) |
1232 | break; | 1267 | break; |
1233 | 1268 | ||
1234 | /* Check to see if we've tried the same voltage 5 times */ | 1269 | /* Check to see if we've tried the same voltage 5 times */ |
1235 | if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { | 1270 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { |
1236 | ++tries; | 1271 | ++tries; |
1237 | if (tries == 5) | 1272 | if (tries == 5) |
1238 | break; | 1273 | break; |
1239 | } else | 1274 | } else |
1240 | tries = 0; | 1275 | tries = 0; |
1241 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | 1276 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; |
1242 | 1277 | ||
1243 | /* Compute new train_set as requested by target */ | 1278 | /* Compute new intel_dp->train_set as requested by target */ |
1244 | intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set); | 1279 | intel_get_adjust_train(intel_dp); |
1245 | } | 1280 | } |
1246 | 1281 | ||
1282 | intel_dp->DP = DP; | ||
1283 | } | ||
1284 | |||
1285 | static void | ||
1286 | intel_dp_complete_link_train(struct intel_dp *intel_dp) | ||
1287 | { | ||
1288 | struct drm_device *dev = intel_dp->base.base.dev; | ||
1289 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1290 | bool channel_eq = false; | ||
1291 | int tries; | ||
1292 | u32 reg; | ||
1293 | uint32_t DP = intel_dp->DP; | ||
1294 | |||
1247 | /* channel equalization */ | 1295 | /* channel equalization */ |
1248 | tries = 0; | 1296 | tries = 0; |
1249 | channel_eq = false; | 1297 | channel_eq = false; |
1250 | for (;;) { | 1298 | for (;;) { |
1251 | /* Use train_set[0] to set the voltage and pre emphasis values */ | 1299 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ |
1252 | uint32_t signal_levels; | 1300 | uint32_t signal_levels; |
1253 | 1301 | ||
1254 | if (IS_GEN6(dev) && IS_eDP(intel_dp)) { | 1302 | if (IS_GEN6(dev) && IS_eDP(intel_dp)) { |
1255 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); | 1303 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1256 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1304 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1257 | } else { | 1305 | } else { |
1258 | signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count); | 1306 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); |
1259 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1307 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1260 | } | 1308 | } |
1261 | 1309 | ||
@@ -1266,15 +1314,15 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1266 | 1314 | ||
1267 | /* channel eq pattern */ | 1315 | /* channel eq pattern */ |
1268 | if (!intel_dp_set_link_train(intel_dp, reg, | 1316 | if (!intel_dp_set_link_train(intel_dp, reg, |
1269 | DP_TRAINING_PATTERN_2, train_set, | 1317 | DP_TRAINING_PATTERN_2, |
1270 | false)) | 1318 | false)) |
1271 | break; | 1319 | break; |
1272 | 1320 | ||
1273 | udelay(400); | 1321 | udelay(400); |
1274 | if (!intel_dp_get_link_status(intel_dp, link_status)) | 1322 | if (!intel_dp_get_link_status(intel_dp)) |
1275 | break; | 1323 | break; |
1276 | 1324 | ||
1277 | if (intel_channel_eq_ok(link_status, intel_dp->lane_count)) { | 1325 | if (intel_channel_eq_ok(intel_dp)) { |
1278 | channel_eq = true; | 1326 | channel_eq = true; |
1279 | break; | 1327 | break; |
1280 | } | 1328 | } |
@@ -1283,8 +1331,8 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1283 | if (tries > 5) | 1331 | if (tries > 5) |
1284 | break; | 1332 | break; |
1285 | 1333 | ||
1286 | /* Compute new train_set as requested by target */ | 1334 | /* Compute new intel_dp->train_set as requested by target */ |
1287 | intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set); | 1335 | intel_get_adjust_train(intel_dp); |
1288 | ++tries; | 1336 | ++tries; |
1289 | } | 1337 | } |
1290 | 1338 | ||
@@ -1302,7 +1350,7 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1302 | static void | 1350 | static void |
1303 | intel_dp_link_down(struct intel_dp *intel_dp) | 1351 | intel_dp_link_down(struct intel_dp *intel_dp) |
1304 | { | 1352 | { |
1305 | struct drm_device *dev = intel_dp->base.enc.dev; | 1353 | struct drm_device *dev = intel_dp->base.base.dev; |
1306 | struct drm_i915_private *dev_priv = dev->dev_private; | 1354 | struct drm_i915_private *dev_priv = dev->dev_private; |
1307 | uint32_t DP = intel_dp->DP; | 1355 | uint32_t DP = intel_dp->DP; |
1308 | 1356 | ||
@@ -1318,14 +1366,13 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1318 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) { | 1366 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) { |
1319 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1367 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
1320 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); | 1368 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); |
1321 | POSTING_READ(intel_dp->output_reg); | ||
1322 | } else { | 1369 | } else { |
1323 | DP &= ~DP_LINK_TRAIN_MASK; | 1370 | DP &= ~DP_LINK_TRAIN_MASK; |
1324 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); | 1371 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); |
1325 | POSTING_READ(intel_dp->output_reg); | ||
1326 | } | 1372 | } |
1373 | POSTING_READ(intel_dp->output_reg); | ||
1327 | 1374 | ||
1328 | udelay(17000); | 1375 | msleep(17); |
1329 | 1376 | ||
1330 | if (IS_eDP(intel_dp)) | 1377 | if (IS_eDP(intel_dp)) |
1331 | DP |= DP_LINK_TRAIN_OFF; | 1378 | DP |= DP_LINK_TRAIN_OFF; |
@@ -1345,27 +1392,29 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1345 | static void | 1392 | static void |
1346 | intel_dp_check_link_status(struct intel_dp *intel_dp) | 1393 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
1347 | { | 1394 | { |
1348 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | 1395 | if (!intel_dp->base.base.crtc) |
1349 | |||
1350 | if (!intel_dp->base.enc.crtc) | ||
1351 | return; | 1396 | return; |
1352 | 1397 | ||
1353 | if (!intel_dp_get_link_status(intel_dp, link_status)) { | 1398 | if (!intel_dp_get_link_status(intel_dp)) { |
1354 | intel_dp_link_down(intel_dp); | 1399 | intel_dp_link_down(intel_dp); |
1355 | return; | 1400 | return; |
1356 | } | 1401 | } |
1357 | 1402 | ||
1358 | if (!intel_channel_eq_ok(link_status, intel_dp->lane_count)) | 1403 | if (!intel_channel_eq_ok(intel_dp)) { |
1359 | intel_dp_link_train(intel_dp); | 1404 | intel_dp_start_link_train(intel_dp); |
1405 | intel_dp_complete_link_train(intel_dp); | ||
1406 | } | ||
1360 | } | 1407 | } |
1361 | 1408 | ||
1362 | static enum drm_connector_status | 1409 | static enum drm_connector_status |
1363 | ironlake_dp_detect(struct drm_connector *connector) | 1410 | ironlake_dp_detect(struct drm_connector *connector) |
1364 | { | 1411 | { |
1365 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1412 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
1366 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
1367 | enum drm_connector_status status; | 1413 | enum drm_connector_status status; |
1368 | 1414 | ||
1415 | /* Panel needs power for AUX to work */ | ||
1416 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
1417 | ironlake_edp_panel_vdd_on(connector->dev); | ||
1369 | status = connector_status_disconnected; | 1418 | status = connector_status_disconnected; |
1370 | if (intel_dp_aux_native_read(intel_dp, | 1419 | if (intel_dp_aux_native_read(intel_dp, |
1371 | 0x000, intel_dp->dpcd, | 1420 | 0x000, intel_dp->dpcd, |
@@ -1376,6 +1425,8 @@ ironlake_dp_detect(struct drm_connector *connector) | |||
1376 | } | 1425 | } |
1377 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], | 1426 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], |
1378 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); | 1427 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); |
1428 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
1429 | ironlake_edp_panel_vdd_off(connector->dev); | ||
1379 | return status; | 1430 | return status; |
1380 | } | 1431 | } |
1381 | 1432 | ||
@@ -1388,9 +1439,8 @@ ironlake_dp_detect(struct drm_connector *connector) | |||
1388 | static enum drm_connector_status | 1439 | static enum drm_connector_status |
1389 | intel_dp_detect(struct drm_connector *connector, bool force) | 1440 | intel_dp_detect(struct drm_connector *connector, bool force) |
1390 | { | 1441 | { |
1391 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1442 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
1392 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1443 | struct drm_device *dev = intel_dp->base.base.dev; |
1393 | struct drm_device *dev = intel_dp->base.enc.dev; | ||
1394 | struct drm_i915_private *dev_priv = dev->dev_private; | 1444 | struct drm_i915_private *dev_priv = dev->dev_private; |
1395 | uint32_t temp, bit; | 1445 | uint32_t temp, bit; |
1396 | enum drm_connector_status status; | 1446 | enum drm_connector_status status; |
@@ -1432,16 +1482,15 @@ intel_dp_detect(struct drm_connector *connector, bool force) | |||
1432 | 1482 | ||
1433 | static int intel_dp_get_modes(struct drm_connector *connector) | 1483 | static int intel_dp_get_modes(struct drm_connector *connector) |
1434 | { | 1484 | { |
1435 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1485 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
1436 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1486 | struct drm_device *dev = intel_dp->base.base.dev; |
1437 | struct drm_device *dev = intel_dp->base.enc.dev; | ||
1438 | struct drm_i915_private *dev_priv = dev->dev_private; | 1487 | struct drm_i915_private *dev_priv = dev->dev_private; |
1439 | int ret; | 1488 | int ret; |
1440 | 1489 | ||
1441 | /* We should parse the EDID data and find out if it has an audio sink | 1490 | /* We should parse the EDID data and find out if it has an audio sink |
1442 | */ | 1491 | */ |
1443 | 1492 | ||
1444 | ret = intel_ddc_get_modes(connector, intel_dp->base.ddc_bus); | 1493 | ret = intel_ddc_get_modes(connector, &intel_dp->adapter); |
1445 | if (ret) { | 1494 | if (ret) { |
1446 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && | 1495 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
1447 | !dev_priv->panel_fixed_mode) { | 1496 | !dev_priv->panel_fixed_mode) { |
@@ -1479,6 +1528,15 @@ intel_dp_destroy (struct drm_connector *connector) | |||
1479 | kfree(connector); | 1528 | kfree(connector); |
1480 | } | 1529 | } |
1481 | 1530 | ||
1531 | static void intel_dp_encoder_destroy(struct drm_encoder *encoder) | ||
1532 | { | ||
1533 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
1534 | |||
1535 | i2c_del_adapter(&intel_dp->adapter); | ||
1536 | drm_encoder_cleanup(encoder); | ||
1537 | kfree(intel_dp); | ||
1538 | } | ||
1539 | |||
1482 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { | 1540 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { |
1483 | .dpms = intel_dp_dpms, | 1541 | .dpms = intel_dp_dpms, |
1484 | .mode_fixup = intel_dp_mode_fixup, | 1542 | .mode_fixup = intel_dp_mode_fixup, |
@@ -1497,14 +1555,14 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = { | |||
1497 | static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { | 1555 | static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { |
1498 | .get_modes = intel_dp_get_modes, | 1556 | .get_modes = intel_dp_get_modes, |
1499 | .mode_valid = intel_dp_mode_valid, | 1557 | .mode_valid = intel_dp_mode_valid, |
1500 | .best_encoder = intel_attached_encoder, | 1558 | .best_encoder = intel_best_encoder, |
1501 | }; | 1559 | }; |
1502 | 1560 | ||
1503 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { | 1561 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { |
1504 | .destroy = intel_encoder_destroy, | 1562 | .destroy = intel_dp_encoder_destroy, |
1505 | }; | 1563 | }; |
1506 | 1564 | ||
1507 | void | 1565 | static void |
1508 | intel_dp_hot_plug(struct intel_encoder *intel_encoder) | 1566 | intel_dp_hot_plug(struct intel_encoder *intel_encoder) |
1509 | { | 1567 | { |
1510 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); | 1568 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); |
@@ -1613,12 +1671,11 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1613 | intel_dp->has_audio = false; | 1671 | intel_dp->has_audio = false; |
1614 | intel_dp->dpms_mode = DRM_MODE_DPMS_ON; | 1672 | intel_dp->dpms_mode = DRM_MODE_DPMS_ON; |
1615 | 1673 | ||
1616 | drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs, | 1674 | drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs, |
1617 | DRM_MODE_ENCODER_TMDS); | 1675 | DRM_MODE_ENCODER_TMDS); |
1618 | drm_encoder_helper_add(&intel_encoder->enc, &intel_dp_helper_funcs); | 1676 | drm_encoder_helper_add(&intel_encoder->base, &intel_dp_helper_funcs); |
1619 | 1677 | ||
1620 | drm_mode_connector_attach_encoder(&intel_connector->base, | 1678 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
1621 | &intel_encoder->enc); | ||
1622 | drm_sysfs_connector_add(connector); | 1679 | drm_sysfs_connector_add(connector); |
1623 | 1680 | ||
1624 | /* Set up the DDC bus. */ | 1681 | /* Set up the DDC bus. */ |
@@ -1648,7 +1705,6 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1648 | 1705 | ||
1649 | intel_dp_i2c_init(intel_dp, intel_connector, name); | 1706 | intel_dp_i2c_init(intel_dp, intel_connector, name); |
1650 | 1707 | ||
1651 | intel_encoder->ddc_bus = &intel_dp->adapter; | ||
1652 | intel_encoder->hot_plug = intel_dp_hot_plug; | 1708 | intel_encoder->hot_plug = intel_dp_hot_plug; |
1653 | 1709 | ||
1654 | if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) { | 1710 | if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) { |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ad312ca6b3e5..60ce9305e772 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -26,14 +26,12 @@ | |||
26 | #define __INTEL_DRV_H__ | 26 | #define __INTEL_DRV_H__ |
27 | 27 | ||
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/i2c-id.h> | ||
30 | #include <linux/i2c-algo-bit.h> | ||
31 | #include "i915_drv.h" | 29 | #include "i915_drv.h" |
32 | #include "drm_crtc.h" | 30 | #include "drm_crtc.h" |
33 | |||
34 | #include "drm_crtc_helper.h" | 31 | #include "drm_crtc_helper.h" |
32 | #include "drm_fb_helper.h" | ||
35 | 33 | ||
36 | #define wait_for(COND, MS, W) ({ \ | 34 | #define _wait_for(COND, MS, W) ({ \ |
37 | unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ | 35 | unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ |
38 | int ret__ = 0; \ | 36 | int ret__ = 0; \ |
39 | while (! (COND)) { \ | 37 | while (! (COND)) { \ |
@@ -41,11 +39,24 @@ | |||
41 | ret__ = -ETIMEDOUT; \ | 39 | ret__ = -ETIMEDOUT; \ |
42 | break; \ | 40 | break; \ |
43 | } \ | 41 | } \ |
44 | if (W) msleep(W); \ | 42 | if (W && !in_dbg_master()) msleep(W); \ |
45 | } \ | 43 | } \ |
46 | ret__; \ | 44 | ret__; \ |
47 | }) | 45 | }) |
48 | 46 | ||
47 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) | ||
48 | #define wait_for_atomic(COND, MS) _wait_for(COND, MS, 0) | ||
49 | |||
50 | #define MSLEEP(x) do { \ | ||
51 | if (in_dbg_master()) \ | ||
52 | mdelay(x); \ | ||
53 | else \ | ||
54 | msleep(x); \ | ||
55 | } while(0) | ||
56 | |||
57 | #define KHz(x) (1000*x) | ||
58 | #define MHz(x) KHz(1000*x) | ||
59 | |||
49 | /* | 60 | /* |
50 | * Display related stuff | 61 | * Display related stuff |
51 | */ | 62 | */ |
@@ -96,24 +107,39 @@ | |||
96 | #define INTEL_DVO_CHIP_TMDS 2 | 107 | #define INTEL_DVO_CHIP_TMDS 2 |
97 | #define INTEL_DVO_CHIP_TVOUT 4 | 108 | #define INTEL_DVO_CHIP_TVOUT 4 |
98 | 109 | ||
99 | struct intel_i2c_chan { | 110 | /* drm_display_mode->private_flags */ |
100 | struct drm_device *drm_dev; /* for getting at dev. private (mmio etc.) */ | 111 | #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) |
101 | u32 reg; /* GPIO reg */ | 112 | #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) |
102 | struct i2c_adapter adapter; | 113 | |
103 | struct i2c_algo_bit_data algo; | 114 | static inline void |
104 | }; | 115 | intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, |
116 | int multiplier) | ||
117 | { | ||
118 | mode->clock *= multiplier; | ||
119 | mode->private_flags |= multiplier; | ||
120 | } | ||
121 | |||
122 | static inline int | ||
123 | intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode) | ||
124 | { | ||
125 | return (mode->private_flags & INTEL_MODE_PIXEL_MULTIPLIER_MASK) >> INTEL_MODE_PIXEL_MULTIPLIER_SHIFT; | ||
126 | } | ||
105 | 127 | ||
106 | struct intel_framebuffer { | 128 | struct intel_framebuffer { |
107 | struct drm_framebuffer base; | 129 | struct drm_framebuffer base; |
108 | struct drm_gem_object *obj; | 130 | struct drm_gem_object *obj; |
109 | }; | 131 | }; |
110 | 132 | ||
133 | struct intel_fbdev { | ||
134 | struct drm_fb_helper helper; | ||
135 | struct intel_framebuffer ifb; | ||
136 | struct list_head fbdev_list; | ||
137 | struct drm_display_mode *our_mode; | ||
138 | }; | ||
111 | 139 | ||
112 | struct intel_encoder { | 140 | struct intel_encoder { |
113 | struct drm_encoder enc; | 141 | struct drm_encoder base; |
114 | int type; | 142 | int type; |
115 | struct i2c_adapter *i2c_bus; | ||
116 | struct i2c_adapter *ddc_bus; | ||
117 | bool load_detect_temp; | 143 | bool load_detect_temp; |
118 | bool needs_tv_clock; | 144 | bool needs_tv_clock; |
119 | void (*hot_plug)(struct intel_encoder *); | 145 | void (*hot_plug)(struct intel_encoder *); |
@@ -123,32 +149,7 @@ struct intel_encoder { | |||
123 | 149 | ||
124 | struct intel_connector { | 150 | struct intel_connector { |
125 | struct drm_connector base; | 151 | struct drm_connector base; |
126 | }; | 152 | struct intel_encoder *encoder; |
127 | |||
128 | struct intel_crtc; | ||
129 | struct intel_overlay { | ||
130 | struct drm_device *dev; | ||
131 | struct intel_crtc *crtc; | ||
132 | struct drm_i915_gem_object *vid_bo; | ||
133 | struct drm_i915_gem_object *old_vid_bo; | ||
134 | int active; | ||
135 | int pfit_active; | ||
136 | u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */ | ||
137 | u32 color_key; | ||
138 | u32 brightness, contrast, saturation; | ||
139 | u32 old_xscale, old_yscale; | ||
140 | /* register access */ | ||
141 | u32 flip_addr; | ||
142 | struct drm_i915_gem_object *reg_bo; | ||
143 | void *virt_addr; | ||
144 | /* flip handling */ | ||
145 | uint32_t last_flip_req; | ||
146 | int hw_wedged; | ||
147 | #define HW_WEDGED 1 | ||
148 | #define NEEDS_WAIT_FOR_FLIP 2 | ||
149 | #define RELEASE_OLD_VID 3 | ||
150 | #define SWITCH_OFF_STAGE_1 4 | ||
151 | #define SWITCH_OFF_STAGE_2 5 | ||
152 | }; | 153 | }; |
153 | 154 | ||
154 | struct intel_crtc { | 155 | struct intel_crtc { |
@@ -157,6 +158,7 @@ struct intel_crtc { | |||
157 | enum plane plane; | 158 | enum plane plane; |
158 | u8 lut_r[256], lut_g[256], lut_b[256]; | 159 | u8 lut_r[256], lut_g[256], lut_b[256]; |
159 | int dpms_mode; | 160 | int dpms_mode; |
161 | bool active; /* is the crtc on? independent of the dpms mode */ | ||
160 | bool busy; /* is scanout buffer being updated frequently? */ | 162 | bool busy; /* is scanout buffer being updated frequently? */ |
161 | struct timer_list idle_timer; | 163 | struct timer_list idle_timer; |
162 | bool lowfreq_avail; | 164 | bool lowfreq_avail; |
@@ -168,14 +170,21 @@ struct intel_crtc { | |||
168 | uint32_t cursor_addr; | 170 | uint32_t cursor_addr; |
169 | int16_t cursor_x, cursor_y; | 171 | int16_t cursor_x, cursor_y; |
170 | int16_t cursor_width, cursor_height; | 172 | int16_t cursor_width, cursor_height; |
171 | bool cursor_visible, cursor_on; | 173 | bool cursor_visible; |
172 | }; | 174 | }; |
173 | 175 | ||
174 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) | 176 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) |
175 | #define to_intel_connector(x) container_of(x, struct intel_connector, base) | 177 | #define to_intel_connector(x) container_of(x, struct intel_connector, base) |
176 | #define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc) | 178 | #define to_intel_encoder(x) container_of(x, struct intel_encoder, base) |
177 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) | 179 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) |
178 | 180 | ||
181 | static inline struct drm_crtc * | ||
182 | intel_get_crtc_for_pipe(struct drm_device *dev, int pipe) | ||
183 | { | ||
184 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
185 | return dev_priv->pipe_to_crtc_mapping[pipe]; | ||
186 | } | ||
187 | |||
179 | struct intel_unpin_work { | 188 | struct intel_unpin_work { |
180 | struct work_struct work; | 189 | struct work_struct work; |
181 | struct drm_device *dev; | 190 | struct drm_device *dev; |
@@ -186,13 +195,8 @@ struct intel_unpin_work { | |||
186 | bool enable_stall_check; | 195 | bool enable_stall_check; |
187 | }; | 196 | }; |
188 | 197 | ||
189 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, | ||
190 | const char *name); | ||
191 | void intel_i2c_destroy(struct i2c_adapter *adapter); | ||
192 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); | 198 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); |
193 | extern bool intel_ddc_probe(struct intel_encoder *intel_encoder); | 199 | extern bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus); |
194 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable); | ||
195 | void intel_i2c_reset_gmbus(struct drm_device *dev); | ||
196 | 200 | ||
197 | extern void intel_crt_init(struct drm_device *dev); | 201 | extern void intel_crt_init(struct drm_device *dev); |
198 | extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); | 202 | extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); |
@@ -209,21 +213,30 @@ extern bool intel_pch_has_edp(struct drm_crtc *crtc); | |||
209 | extern bool intel_dpd_is_edp(struct drm_device *dev); | 213 | extern bool intel_dpd_is_edp(struct drm_device *dev); |
210 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); | 214 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); |
211 | 215 | ||
212 | 216 | /* intel_panel.c */ | |
213 | extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | 217 | extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, |
214 | struct drm_display_mode *adjusted_mode); | 218 | struct drm_display_mode *adjusted_mode); |
215 | extern void intel_pch_panel_fitting(struct drm_device *dev, | 219 | extern void intel_pch_panel_fitting(struct drm_device *dev, |
216 | int fitting_mode, | 220 | int fitting_mode, |
217 | struct drm_display_mode *mode, | 221 | struct drm_display_mode *mode, |
218 | struct drm_display_mode *adjusted_mode); | 222 | struct drm_display_mode *adjusted_mode); |
223 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); | ||
224 | extern u32 intel_panel_get_backlight(struct drm_device *dev); | ||
225 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); | ||
219 | 226 | ||
220 | extern int intel_panel_fitter_pipe (struct drm_device *dev); | ||
221 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 227 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
222 | extern void intel_encoder_prepare (struct drm_encoder *encoder); | 228 | extern void intel_encoder_prepare (struct drm_encoder *encoder); |
223 | extern void intel_encoder_commit (struct drm_encoder *encoder); | 229 | extern void intel_encoder_commit (struct drm_encoder *encoder); |
224 | extern void intel_encoder_destroy(struct drm_encoder *encoder); | 230 | extern void intel_encoder_destroy(struct drm_encoder *encoder); |
225 | 231 | ||
226 | extern struct drm_encoder *intel_attached_encoder(struct drm_connector *connector); | 232 | static inline struct intel_encoder *intel_attached_encoder(struct drm_connector *connector) |
233 | { | ||
234 | return to_intel_connector(connector)->encoder; | ||
235 | } | ||
236 | |||
237 | extern void intel_connector_attach_encoder(struct intel_connector *connector, | ||
238 | struct intel_encoder *encoder); | ||
239 | extern struct drm_encoder *intel_best_encoder(struct drm_connector *connector); | ||
227 | 240 | ||
228 | extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | 241 | extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, |
229 | struct drm_crtc *crtc); | 242 | struct drm_crtc *crtc); |
@@ -231,7 +244,6 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | |||
231 | struct drm_file *file_priv); | 244 | struct drm_file *file_priv); |
232 | extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe); | 245 | extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe); |
233 | extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); | 246 | extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); |
234 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); | ||
235 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | 247 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
236 | struct drm_connector *connector, | 248 | struct drm_connector *connector, |
237 | struct drm_display_mode *mode, | 249 | struct drm_display_mode *mode, |
@@ -253,7 +265,8 @@ extern void ironlake_enable_drps(struct drm_device *dev); | |||
253 | extern void ironlake_disable_drps(struct drm_device *dev); | 265 | extern void ironlake_disable_drps(struct drm_device *dev); |
254 | 266 | ||
255 | extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, | 267 | extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, |
256 | struct drm_gem_object *obj); | 268 | struct drm_gem_object *obj, |
269 | bool pipelined); | ||
257 | 270 | ||
258 | extern int intel_framebuffer_init(struct drm_device *dev, | 271 | extern int intel_framebuffer_init(struct drm_device *dev, |
259 | struct intel_framebuffer *ifb, | 272 | struct intel_framebuffer *ifb, |
@@ -268,9 +281,8 @@ extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane); | |||
268 | 281 | ||
269 | extern void intel_setup_overlay(struct drm_device *dev); | 282 | extern void intel_setup_overlay(struct drm_device *dev); |
270 | extern void intel_cleanup_overlay(struct drm_device *dev); | 283 | extern void intel_cleanup_overlay(struct drm_device *dev); |
271 | extern int intel_overlay_switch_off(struct intel_overlay *overlay); | 284 | extern int intel_overlay_switch_off(struct intel_overlay *overlay, |
272 | extern int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, | 285 | bool interruptible); |
273 | int interruptible); | ||
274 | extern int intel_overlay_put_image(struct drm_device *dev, void *data, | 286 | extern int intel_overlay_put_image(struct drm_device *dev, void *data, |
275 | struct drm_file *file_priv); | 287 | struct drm_file *file_priv); |
276 | extern int intel_overlay_attrs(struct drm_device *dev, void *data, | 288 | extern int intel_overlay_attrs(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 7c9ec1472d46..ad28bc4fb732 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -72,7 +72,7 @@ static const struct intel_dvo_device intel_dvo_devices[] = { | |||
72 | .name = "ch7017", | 72 | .name = "ch7017", |
73 | .dvo_reg = DVOC, | 73 | .dvo_reg = DVOC, |
74 | .slave_addr = 0x75, | 74 | .slave_addr = 0x75, |
75 | .gpio = GPIOE, | 75 | .gpio = GMBUS_PORT_DPD, |
76 | .dev_ops = &ch7017_ops, | 76 | .dev_ops = &ch7017_ops, |
77 | } | 77 | } |
78 | }; | 78 | }; |
@@ -81,6 +81,7 @@ struct intel_dvo { | |||
81 | struct intel_encoder base; | 81 | struct intel_encoder base; |
82 | 82 | ||
83 | struct intel_dvo_device dev; | 83 | struct intel_dvo_device dev; |
84 | int ddc_bus; | ||
84 | 85 | ||
85 | struct drm_display_mode *panel_fixed_mode; | 86 | struct drm_display_mode *panel_fixed_mode; |
86 | bool panel_wants_dither; | 87 | bool panel_wants_dither; |
@@ -88,7 +89,13 @@ struct intel_dvo { | |||
88 | 89 | ||
89 | static struct intel_dvo *enc_to_intel_dvo(struct drm_encoder *encoder) | 90 | static struct intel_dvo *enc_to_intel_dvo(struct drm_encoder *encoder) |
90 | { | 91 | { |
91 | return container_of(enc_to_intel_encoder(encoder), struct intel_dvo, base); | 92 | return container_of(encoder, struct intel_dvo, base.base); |
93 | } | ||
94 | |||
95 | static struct intel_dvo *intel_attached_dvo(struct drm_connector *connector) | ||
96 | { | ||
97 | return container_of(intel_attached_encoder(connector), | ||
98 | struct intel_dvo, base); | ||
92 | } | 99 | } |
93 | 100 | ||
94 | static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) | 101 | static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) |
@@ -112,8 +119,7 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) | |||
112 | static int intel_dvo_mode_valid(struct drm_connector *connector, | 119 | static int intel_dvo_mode_valid(struct drm_connector *connector, |
113 | struct drm_display_mode *mode) | 120 | struct drm_display_mode *mode) |
114 | { | 121 | { |
115 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 122 | struct intel_dvo *intel_dvo = intel_attached_dvo(connector); |
116 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); | ||
117 | 123 | ||
118 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 124 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
119 | return MODE_NO_DBLESCAN; | 125 | return MODE_NO_DBLESCAN; |
@@ -224,23 +230,22 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
224 | static enum drm_connector_status | 230 | static enum drm_connector_status |
225 | intel_dvo_detect(struct drm_connector *connector, bool force) | 231 | intel_dvo_detect(struct drm_connector *connector, bool force) |
226 | { | 232 | { |
227 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 233 | struct intel_dvo *intel_dvo = intel_attached_dvo(connector); |
228 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); | ||
229 | |||
230 | return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev); | 234 | return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev); |
231 | } | 235 | } |
232 | 236 | ||
233 | static int intel_dvo_get_modes(struct drm_connector *connector) | 237 | static int intel_dvo_get_modes(struct drm_connector *connector) |
234 | { | 238 | { |
235 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 239 | struct intel_dvo *intel_dvo = intel_attached_dvo(connector); |
236 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); | 240 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
237 | 241 | ||
238 | /* We should probably have an i2c driver get_modes function for those | 242 | /* We should probably have an i2c driver get_modes function for those |
239 | * devices which will have a fixed set of modes determined by the chip | 243 | * devices which will have a fixed set of modes determined by the chip |
240 | * (TV-out, for example), but for now with just TMDS and LVDS, | 244 | * (TV-out, for example), but for now with just TMDS and LVDS, |
241 | * that's not the case. | 245 | * that's not the case. |
242 | */ | 246 | */ |
243 | intel_ddc_get_modes(connector, intel_dvo->base.ddc_bus); | 247 | intel_ddc_get_modes(connector, |
248 | &dev_priv->gmbus[intel_dvo->ddc_bus].adapter); | ||
244 | if (!list_empty(&connector->probed_modes)) | 249 | if (!list_empty(&connector->probed_modes)) |
245 | return 1; | 250 | return 1; |
246 | 251 | ||
@@ -281,7 +286,7 @@ static const struct drm_connector_funcs intel_dvo_connector_funcs = { | |||
281 | static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = { | 286 | static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = { |
282 | .mode_valid = intel_dvo_mode_valid, | 287 | .mode_valid = intel_dvo_mode_valid, |
283 | .get_modes = intel_dvo_get_modes, | 288 | .get_modes = intel_dvo_get_modes, |
284 | .best_encoder = intel_attached_encoder, | 289 | .best_encoder = intel_best_encoder, |
285 | }; | 290 | }; |
286 | 291 | ||
287 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) | 292 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) |
@@ -311,8 +316,7 @@ intel_dvo_get_current_mode(struct drm_connector *connector) | |||
311 | { | 316 | { |
312 | struct drm_device *dev = connector->dev; | 317 | struct drm_device *dev = connector->dev; |
313 | struct drm_i915_private *dev_priv = dev->dev_private; | 318 | struct drm_i915_private *dev_priv = dev->dev_private; |
314 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 319 | struct intel_dvo *intel_dvo = intel_attached_dvo(connector); |
315 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); | ||
316 | uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg); | 320 | uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg); |
317 | struct drm_display_mode *mode = NULL; | 321 | struct drm_display_mode *mode = NULL; |
318 | 322 | ||
@@ -323,7 +327,7 @@ intel_dvo_get_current_mode(struct drm_connector *connector) | |||
323 | struct drm_crtc *crtc; | 327 | struct drm_crtc *crtc; |
324 | int pipe = (dvo_val & DVO_PIPE_B_SELECT) ? 1 : 0; | 328 | int pipe = (dvo_val & DVO_PIPE_B_SELECT) ? 1 : 0; |
325 | 329 | ||
326 | crtc = intel_get_crtc_from_pipe(dev, pipe); | 330 | crtc = intel_get_crtc_for_pipe(dev, pipe); |
327 | if (crtc) { | 331 | if (crtc) { |
328 | mode = intel_crtc_mode_get(dev, crtc); | 332 | mode = intel_crtc_mode_get(dev, crtc); |
329 | if (mode) { | 333 | if (mode) { |
@@ -341,10 +345,10 @@ intel_dvo_get_current_mode(struct drm_connector *connector) | |||
341 | 345 | ||
342 | void intel_dvo_init(struct drm_device *dev) | 346 | void intel_dvo_init(struct drm_device *dev) |
343 | { | 347 | { |
348 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
344 | struct intel_encoder *intel_encoder; | 349 | struct intel_encoder *intel_encoder; |
345 | struct intel_dvo *intel_dvo; | 350 | struct intel_dvo *intel_dvo; |
346 | struct intel_connector *intel_connector; | 351 | struct intel_connector *intel_connector; |
347 | struct i2c_adapter *i2cbus = NULL; | ||
348 | int ret = 0; | 352 | int ret = 0; |
349 | int i; | 353 | int i; |
350 | int encoder_type = DRM_MODE_ENCODER_NONE; | 354 | int encoder_type = DRM_MODE_ENCODER_NONE; |
@@ -360,16 +364,17 @@ void intel_dvo_init(struct drm_device *dev) | |||
360 | } | 364 | } |
361 | 365 | ||
362 | intel_encoder = &intel_dvo->base; | 366 | intel_encoder = &intel_dvo->base; |
367 | drm_encoder_init(dev, &intel_encoder->base, | ||
368 | &intel_dvo_enc_funcs, encoder_type); | ||
363 | 369 | ||
364 | /* Set up the DDC bus */ | 370 | /* Set up the DDC bus */ |
365 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); | 371 | intel_dvo->ddc_bus = GMBUS_PORT_DPB; |
366 | if (!intel_encoder->ddc_bus) | ||
367 | goto free_intel; | ||
368 | 372 | ||
369 | /* Now, try to find a controller */ | 373 | /* Now, try to find a controller */ |
370 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { | 374 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { |
371 | struct drm_connector *connector = &intel_connector->base; | 375 | struct drm_connector *connector = &intel_connector->base; |
372 | const struct intel_dvo_device *dvo = &intel_dvo_devices[i]; | 376 | const struct intel_dvo_device *dvo = &intel_dvo_devices[i]; |
377 | struct i2c_adapter *i2c; | ||
373 | int gpio; | 378 | int gpio; |
374 | 379 | ||
375 | /* Allow the I2C driver info to specify the GPIO to be used in | 380 | /* Allow the I2C driver info to specify the GPIO to be used in |
@@ -379,23 +384,18 @@ void intel_dvo_init(struct drm_device *dev) | |||
379 | if (dvo->gpio != 0) | 384 | if (dvo->gpio != 0) |
380 | gpio = dvo->gpio; | 385 | gpio = dvo->gpio; |
381 | else if (dvo->type == INTEL_DVO_CHIP_LVDS) | 386 | else if (dvo->type == INTEL_DVO_CHIP_LVDS) |
382 | gpio = GPIOB; | 387 | gpio = GMBUS_PORT_PANEL; |
383 | else | 388 | else |
384 | gpio = GPIOE; | 389 | gpio = GMBUS_PORT_DPD; |
385 | 390 | ||
386 | /* Set up the I2C bus necessary for the chip we're probing. | 391 | /* Set up the I2C bus necessary for the chip we're probing. |
387 | * It appears that everything is on GPIOE except for panels | 392 | * It appears that everything is on GPIOE except for panels |
388 | * on i830 laptops, which are on GPIOB (DVOA). | 393 | * on i830 laptops, which are on GPIOB (DVOA). |
389 | */ | 394 | */ |
390 | if (i2cbus != NULL) | 395 | i2c = &dev_priv->gmbus[gpio].adapter; |
391 | intel_i2c_destroy(i2cbus); | ||
392 | if (!(i2cbus = intel_i2c_create(dev, gpio, | ||
393 | gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) { | ||
394 | continue; | ||
395 | } | ||
396 | 396 | ||
397 | intel_dvo->dev = *dvo; | 397 | intel_dvo->dev = *dvo; |
398 | ret = dvo->dev_ops->init(&intel_dvo->dev, i2cbus); | 398 | ret = dvo->dev_ops->init(&intel_dvo->dev, i2c); |
399 | if (!ret) | 399 | if (!ret) |
400 | continue; | 400 | continue; |
401 | 401 | ||
@@ -427,13 +427,10 @@ void intel_dvo_init(struct drm_device *dev) | |||
427 | connector->interlace_allowed = false; | 427 | connector->interlace_allowed = false; |
428 | connector->doublescan_allowed = false; | 428 | connector->doublescan_allowed = false; |
429 | 429 | ||
430 | drm_encoder_init(dev, &intel_encoder->enc, | 430 | drm_encoder_helper_add(&intel_encoder->base, |
431 | &intel_dvo_enc_funcs, encoder_type); | ||
432 | drm_encoder_helper_add(&intel_encoder->enc, | ||
433 | &intel_dvo_helper_funcs); | 431 | &intel_dvo_helper_funcs); |
434 | 432 | ||
435 | drm_mode_connector_attach_encoder(&intel_connector->base, | 433 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
436 | &intel_encoder->enc); | ||
437 | if (dvo->type == INTEL_DVO_CHIP_LVDS) { | 434 | if (dvo->type == INTEL_DVO_CHIP_LVDS) { |
438 | /* For our LVDS chipsets, we should hopefully be able | 435 | /* For our LVDS chipsets, we should hopefully be able |
439 | * to dig the fixed panel mode out of the BIOS data. | 436 | * to dig the fixed panel mode out of the BIOS data. |
@@ -451,11 +448,7 @@ void intel_dvo_init(struct drm_device *dev) | |||
451 | return; | 448 | return; |
452 | } | 449 | } |
453 | 450 | ||
454 | intel_i2c_destroy(intel_encoder->ddc_bus); | 451 | drm_encoder_cleanup(&intel_encoder->base); |
455 | /* Didn't find a chip, so tear down. */ | ||
456 | if (i2cbus != NULL) | ||
457 | intel_i2c_destroy(i2cbus); | ||
458 | free_intel: | ||
459 | kfree(intel_dvo); | 452 | kfree(intel_dvo); |
460 | kfree(intel_connector); | 453 | kfree(intel_connector); |
461 | } | 454 | } |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 7bdc96256bf5..8a23bf772c95 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -44,13 +44,6 @@ | |||
44 | #include "i915_drm.h" | 44 | #include "i915_drm.h" |
45 | #include "i915_drv.h" | 45 | #include "i915_drv.h" |
46 | 46 | ||
47 | struct intel_fbdev { | ||
48 | struct drm_fb_helper helper; | ||
49 | struct intel_framebuffer ifb; | ||
50 | struct list_head fbdev_list; | ||
51 | struct drm_display_mode *our_mode; | ||
52 | }; | ||
53 | |||
54 | static struct fb_ops intelfb_ops = { | 47 | static struct fb_ops intelfb_ops = { |
55 | .owner = THIS_MODULE, | 48 | .owner = THIS_MODULE, |
56 | .fb_check_var = drm_fb_helper_check_var, | 49 | .fb_check_var = drm_fb_helper_check_var, |
@@ -100,19 +93,13 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
100 | 93 | ||
101 | mutex_lock(&dev->struct_mutex); | 94 | mutex_lock(&dev->struct_mutex); |
102 | 95 | ||
103 | ret = intel_pin_and_fence_fb_obj(dev, fbo); | 96 | /* Flush everything out, we'll be doing GTT only from now on */ |
97 | ret = intel_pin_and_fence_fb_obj(dev, fbo, false); | ||
104 | if (ret) { | 98 | if (ret) { |
105 | DRM_ERROR("failed to pin fb: %d\n", ret); | 99 | DRM_ERROR("failed to pin fb: %d\n", ret); |
106 | goto out_unref; | 100 | goto out_unref; |
107 | } | 101 | } |
108 | 102 | ||
109 | /* Flush everything out, we'll be doing GTT only from now on */ | ||
110 | ret = i915_gem_object_set_to_gtt_domain(fbo, 1); | ||
111 | if (ret) { | ||
112 | DRM_ERROR("failed to bind fb: %d.\n", ret); | ||
113 | goto out_unpin; | ||
114 | } | ||
115 | |||
116 | info = framebuffer_alloc(0, device); | 103 | info = framebuffer_alloc(0, device); |
117 | if (!info) { | 104 | if (!info) { |
118 | ret = -ENOMEM; | 105 | ret = -ENOMEM; |
@@ -219,8 +206,8 @@ static struct drm_fb_helper_funcs intel_fb_helper_funcs = { | |||
219 | .fb_probe = intel_fb_find_or_create_single, | 206 | .fb_probe = intel_fb_find_or_create_single, |
220 | }; | 207 | }; |
221 | 208 | ||
222 | int intel_fbdev_destroy(struct drm_device *dev, | 209 | static int intel_fbdev_destroy(struct drm_device *dev, |
223 | struct intel_fbdev *ifbdev) | 210 | struct intel_fbdev *ifbdev) |
224 | { | 211 | { |
225 | struct fb_info *info; | 212 | struct fb_info *info; |
226 | struct intel_framebuffer *ifb = &ifbdev->ifb; | 213 | struct intel_framebuffer *ifb = &ifbdev->ifb; |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 926934a482ec..9fb9501f2d07 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -40,12 +40,19 @@ | |||
40 | struct intel_hdmi { | 40 | struct intel_hdmi { |
41 | struct intel_encoder base; | 41 | struct intel_encoder base; |
42 | u32 sdvox_reg; | 42 | u32 sdvox_reg; |
43 | int ddc_bus; | ||
43 | bool has_hdmi_sink; | 44 | bool has_hdmi_sink; |
44 | }; | 45 | }; |
45 | 46 | ||
46 | static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) | 47 | static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) |
47 | { | 48 | { |
48 | return container_of(enc_to_intel_encoder(encoder), struct intel_hdmi, base); | 49 | return container_of(encoder, struct intel_hdmi, base.base); |
50 | } | ||
51 | |||
52 | static struct intel_hdmi *intel_attached_hdmi(struct drm_connector *connector) | ||
53 | { | ||
54 | return container_of(intel_attached_encoder(connector), | ||
55 | struct intel_hdmi, base); | ||
49 | } | 56 | } |
50 | 57 | ||
51 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, | 58 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, |
@@ -141,13 +148,14 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
141 | static enum drm_connector_status | 148 | static enum drm_connector_status |
142 | intel_hdmi_detect(struct drm_connector *connector, bool force) | 149 | intel_hdmi_detect(struct drm_connector *connector, bool force) |
143 | { | 150 | { |
144 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 151 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); |
145 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 152 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
146 | struct edid *edid = NULL; | 153 | struct edid *edid; |
147 | enum drm_connector_status status = connector_status_disconnected; | 154 | enum drm_connector_status status = connector_status_disconnected; |
148 | 155 | ||
149 | intel_hdmi->has_hdmi_sink = false; | 156 | intel_hdmi->has_hdmi_sink = false; |
150 | edid = drm_get_edid(connector, intel_hdmi->base.ddc_bus); | 157 | edid = drm_get_edid(connector, |
158 | &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); | ||
151 | 159 | ||
152 | if (edid) { | 160 | if (edid) { |
153 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { | 161 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
@@ -163,14 +171,15 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) | |||
163 | 171 | ||
164 | static int intel_hdmi_get_modes(struct drm_connector *connector) | 172 | static int intel_hdmi_get_modes(struct drm_connector *connector) |
165 | { | 173 | { |
166 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 174 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); |
167 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 175 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
168 | 176 | ||
169 | /* We should parse the EDID data and find out if it's an HDMI sink so | 177 | /* We should parse the EDID data and find out if it's an HDMI sink so |
170 | * we can send audio to it. | 178 | * we can send audio to it. |
171 | */ | 179 | */ |
172 | 180 | ||
173 | return intel_ddc_get_modes(connector, intel_hdmi->base.ddc_bus); | 181 | return intel_ddc_get_modes(connector, |
182 | &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); | ||
174 | } | 183 | } |
175 | 184 | ||
176 | static void intel_hdmi_destroy(struct drm_connector *connector) | 185 | static void intel_hdmi_destroy(struct drm_connector *connector) |
@@ -198,7 +207,7 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = { | |||
198 | static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = { | 207 | static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = { |
199 | .get_modes = intel_hdmi_get_modes, | 208 | .get_modes = intel_hdmi_get_modes, |
200 | .mode_valid = intel_hdmi_mode_valid, | 209 | .mode_valid = intel_hdmi_mode_valid, |
201 | .best_encoder = intel_attached_encoder, | 210 | .best_encoder = intel_best_encoder, |
202 | }; | 211 | }; |
203 | 212 | ||
204 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { | 213 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { |
@@ -224,6 +233,9 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
224 | } | 233 | } |
225 | 234 | ||
226 | intel_encoder = &intel_hdmi->base; | 235 | intel_encoder = &intel_hdmi->base; |
236 | drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs, | ||
237 | DRM_MODE_ENCODER_TMDS); | ||
238 | |||
227 | connector = &intel_connector->base; | 239 | connector = &intel_connector->base; |
228 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, | 240 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, |
229 | DRM_MODE_CONNECTOR_HDMIA); | 241 | DRM_MODE_CONNECTOR_HDMIA); |
@@ -239,39 +251,31 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
239 | /* Set up the DDC bus. */ | 251 | /* Set up the DDC bus. */ |
240 | if (sdvox_reg == SDVOB) { | 252 | if (sdvox_reg == SDVOB) { |
241 | intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); | 253 | intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); |
242 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); | 254 | intel_hdmi->ddc_bus = GMBUS_PORT_DPB; |
243 | dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; | 255 | dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; |
244 | } else if (sdvox_reg == SDVOC) { | 256 | } else if (sdvox_reg == SDVOC) { |
245 | intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); | 257 | intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); |
246 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); | 258 | intel_hdmi->ddc_bus = GMBUS_PORT_DPC; |
247 | dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; | 259 | dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; |
248 | } else if (sdvox_reg == HDMIB) { | 260 | } else if (sdvox_reg == HDMIB) { |
249 | intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); | 261 | intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); |
250 | intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, | 262 | intel_hdmi->ddc_bus = GMBUS_PORT_DPB; |
251 | "HDMIB"); | ||
252 | dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; | 263 | dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; |
253 | } else if (sdvox_reg == HDMIC) { | 264 | } else if (sdvox_reg == HDMIC) { |
254 | intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); | 265 | intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); |
255 | intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, | 266 | intel_hdmi->ddc_bus = GMBUS_PORT_DPC; |
256 | "HDMIC"); | ||
257 | dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; | 267 | dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; |
258 | } else if (sdvox_reg == HDMID) { | 268 | } else if (sdvox_reg == HDMID) { |
259 | intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); | 269 | intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); |
260 | intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, | 270 | intel_hdmi->ddc_bus = GMBUS_PORT_DPD; |
261 | "HDMID"); | ||
262 | dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; | 271 | dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; |
263 | } | 272 | } |
264 | if (!intel_encoder->ddc_bus) | ||
265 | goto err_connector; | ||
266 | 273 | ||
267 | intel_hdmi->sdvox_reg = sdvox_reg; | 274 | intel_hdmi->sdvox_reg = sdvox_reg; |
268 | 275 | ||
269 | drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs, | 276 | drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs); |
270 | DRM_MODE_ENCODER_TMDS); | ||
271 | drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs); | ||
272 | 277 | ||
273 | drm_mode_connector_attach_encoder(&intel_connector->base, | 278 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
274 | &intel_encoder->enc); | ||
275 | drm_sysfs_connector_add(connector); | 279 | drm_sysfs_connector_add(connector); |
276 | 280 | ||
277 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written | 281 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written |
@@ -282,13 +286,4 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
282 | u32 temp = I915_READ(PEG_BAND_GAP_DATA); | 286 | u32 temp = I915_READ(PEG_BAND_GAP_DATA); |
283 | I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); | 287 | I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); |
284 | } | 288 | } |
285 | |||
286 | return; | ||
287 | |||
288 | err_connector: | ||
289 | drm_connector_cleanup(connector); | ||
290 | kfree(intel_hdmi); | ||
291 | kfree(intel_connector); | ||
292 | |||
293 | return; | ||
294 | } | 289 | } |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index c2649c7df14c..6f4d128935ac 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 Dave Airlie <airlied@linux.ie> | 2 | * Copyright (c) 2006 Dave Airlie <airlied@linux.ie> |
3 | * Copyright © 2006-2008 Intel Corporation | 3 | * Copyright © 2006-2008,2010 Intel Corporation |
4 | * Jesse Barnes <jesse.barnes@intel.com> | 4 | * Jesse Barnes <jesse.barnes@intel.com> |
5 | * | 5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a | 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
@@ -24,10 +24,9 @@ | |||
24 | * | 24 | * |
25 | * Authors: | 25 | * Authors: |
26 | * Eric Anholt <eric@anholt.net> | 26 | * Eric Anholt <eric@anholt.net> |
27 | * Chris Wilson <chris@chris-wilson.co.uk> | ||
27 | */ | 28 | */ |
28 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
29 | #include <linux/slab.h> | ||
30 | #include <linux/i2c-id.h> | ||
31 | #include <linux/i2c-algo-bit.h> | 30 | #include <linux/i2c-algo-bit.h> |
32 | #include "drmP.h" | 31 | #include "drmP.h" |
33 | #include "drm.h" | 32 | #include "drm.h" |
@@ -35,57 +34,67 @@ | |||
35 | #include "i915_drm.h" | 34 | #include "i915_drm.h" |
36 | #include "i915_drv.h" | 35 | #include "i915_drv.h" |
37 | 36 | ||
38 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable) | 37 | /* Intel GPIO access functions */ |
38 | |||
39 | #define I2C_RISEFALL_TIME 20 | ||
40 | |||
41 | struct intel_gpio { | ||
42 | struct i2c_adapter adapter; | ||
43 | struct i2c_algo_bit_data algo; | ||
44 | struct drm_i915_private *dev_priv; | ||
45 | u32 reg; | ||
46 | }; | ||
47 | |||
48 | void | ||
49 | intel_i2c_reset(struct drm_device *dev) | ||
39 | { | 50 | { |
40 | struct drm_i915_private *dev_priv = dev->dev_private; | 51 | struct drm_i915_private *dev_priv = dev->dev_private; |
52 | if (HAS_PCH_SPLIT(dev)) | ||
53 | I915_WRITE(PCH_GMBUS0, 0); | ||
54 | else | ||
55 | I915_WRITE(GMBUS0, 0); | ||
56 | } | ||
57 | |||
58 | static void intel_i2c_quirk_set(struct drm_i915_private *dev_priv, bool enable) | ||
59 | { | ||
60 | u32 val; | ||
41 | 61 | ||
42 | /* When using bit bashing for I2C, this bit needs to be set to 1 */ | 62 | /* When using bit bashing for I2C, this bit needs to be set to 1 */ |
43 | if (!IS_PINEVIEW(dev)) | 63 | if (!IS_PINEVIEW(dev_priv->dev)) |
44 | return; | 64 | return; |
65 | |||
66 | val = I915_READ(DSPCLK_GATE_D); | ||
45 | if (enable) | 67 | if (enable) |
46 | I915_WRITE(DSPCLK_GATE_D, | 68 | val |= DPCUNIT_CLOCK_GATE_DISABLE; |
47 | I915_READ(DSPCLK_GATE_D) | DPCUNIT_CLOCK_GATE_DISABLE); | ||
48 | else | 69 | else |
49 | I915_WRITE(DSPCLK_GATE_D, | 70 | val &= ~DPCUNIT_CLOCK_GATE_DISABLE; |
50 | I915_READ(DSPCLK_GATE_D) & (~DPCUNIT_CLOCK_GATE_DISABLE)); | 71 | I915_WRITE(DSPCLK_GATE_D, val); |
51 | } | 72 | } |
52 | 73 | ||
53 | /* | ||
54 | * Intel GPIO access functions | ||
55 | */ | ||
56 | |||
57 | #define I2C_RISEFALL_TIME 20 | ||
58 | |||
59 | static int get_clock(void *data) | 74 | static int get_clock(void *data) |
60 | { | 75 | { |
61 | struct intel_i2c_chan *chan = data; | 76 | struct intel_gpio *gpio = data; |
62 | struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; | 77 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
63 | u32 val; | 78 | return (I915_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; |
64 | |||
65 | val = I915_READ(chan->reg); | ||
66 | return ((val & GPIO_CLOCK_VAL_IN) != 0); | ||
67 | } | 79 | } |
68 | 80 | ||
69 | static int get_data(void *data) | 81 | static int get_data(void *data) |
70 | { | 82 | { |
71 | struct intel_i2c_chan *chan = data; | 83 | struct intel_gpio *gpio = data; |
72 | struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; | 84 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
73 | u32 val; | 85 | return (I915_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0; |
74 | |||
75 | val = I915_READ(chan->reg); | ||
76 | return ((val & GPIO_DATA_VAL_IN) != 0); | ||
77 | } | 86 | } |
78 | 87 | ||
79 | static void set_clock(void *data, int state_high) | 88 | static void set_clock(void *data, int state_high) |
80 | { | 89 | { |
81 | struct intel_i2c_chan *chan = data; | 90 | struct intel_gpio *gpio = data; |
82 | struct drm_device *dev = chan->drm_dev; | 91 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
83 | struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; | 92 | struct drm_device *dev = dev_priv->dev; |
84 | u32 reserved = 0, clock_bits; | 93 | u32 reserved = 0, clock_bits; |
85 | 94 | ||
86 | /* On most chips, these bits must be preserved in software. */ | 95 | /* On most chips, these bits must be preserved in software. */ |
87 | if (!IS_I830(dev) && !IS_845G(dev)) | 96 | if (!IS_I830(dev) && !IS_845G(dev)) |
88 | reserved = I915_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | | 97 | reserved = I915_READ(gpio->reg) & (GPIO_DATA_PULLUP_DISABLE | |
89 | GPIO_CLOCK_PULLUP_DISABLE); | 98 | GPIO_CLOCK_PULLUP_DISABLE); |
90 | 99 | ||
91 | if (state_high) | 100 | if (state_high) |
@@ -93,20 +102,21 @@ static void set_clock(void *data, int state_high) | |||
93 | else | 102 | else |
94 | clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | | 103 | clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | |
95 | GPIO_CLOCK_VAL_MASK; | 104 | GPIO_CLOCK_VAL_MASK; |
96 | I915_WRITE(chan->reg, reserved | clock_bits); | 105 | |
97 | udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ | 106 | I915_WRITE(gpio->reg, reserved | clock_bits); |
107 | POSTING_READ(gpio->reg); | ||
98 | } | 108 | } |
99 | 109 | ||
100 | static void set_data(void *data, int state_high) | 110 | static void set_data(void *data, int state_high) |
101 | { | 111 | { |
102 | struct intel_i2c_chan *chan = data; | 112 | struct intel_gpio *gpio = data; |
103 | struct drm_device *dev = chan->drm_dev; | 113 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
104 | struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; | 114 | struct drm_device *dev = dev_priv->dev; |
105 | u32 reserved = 0, data_bits; | 115 | u32 reserved = 0, data_bits; |
106 | 116 | ||
107 | /* On most chips, these bits must be preserved in software. */ | 117 | /* On most chips, these bits must be preserved in software. */ |
108 | if (!IS_I830(dev) && !IS_845G(dev)) | 118 | if (!IS_I830(dev) && !IS_845G(dev)) |
109 | reserved = I915_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | | 119 | reserved = I915_READ(gpio->reg) & (GPIO_DATA_PULLUP_DISABLE | |
110 | GPIO_CLOCK_PULLUP_DISABLE); | 120 | GPIO_CLOCK_PULLUP_DISABLE); |
111 | 121 | ||
112 | if (state_high) | 122 | if (state_high) |
@@ -115,109 +125,258 @@ static void set_data(void *data, int state_high) | |||
115 | data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | | 125 | data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | |
116 | GPIO_DATA_VAL_MASK; | 126 | GPIO_DATA_VAL_MASK; |
117 | 127 | ||
118 | I915_WRITE(chan->reg, reserved | data_bits); | 128 | I915_WRITE(gpio->reg, reserved | data_bits); |
119 | udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ | 129 | POSTING_READ(gpio->reg); |
120 | } | 130 | } |
121 | 131 | ||
122 | /* Clears the GMBUS setup. Our driver doesn't make use of the GMBUS I2C | 132 | static struct i2c_adapter * |
123 | * engine, but if the BIOS leaves it enabled, then that can break our use | 133 | intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin) |
124 | * of the bit-banging I2C interfaces. This is notably the case with the | ||
125 | * Mac Mini in EFI mode. | ||
126 | */ | ||
127 | void | ||
128 | intel_i2c_reset_gmbus(struct drm_device *dev) | ||
129 | { | 134 | { |
130 | struct drm_i915_private *dev_priv = dev->dev_private; | 135 | static const int map_pin_to_reg[] = { |
136 | 0, | ||
137 | GPIOB, | ||
138 | GPIOA, | ||
139 | GPIOC, | ||
140 | GPIOD, | ||
141 | GPIOE, | ||
142 | GPIOF, | ||
143 | }; | ||
144 | struct intel_gpio *gpio; | ||
131 | 145 | ||
132 | if (HAS_PCH_SPLIT(dev)) { | 146 | if (pin < 1 || pin > 7) |
133 | I915_WRITE(PCH_GMBUS0, 0); | 147 | return NULL; |
134 | } else { | ||
135 | I915_WRITE(GMBUS0, 0); | ||
136 | } | ||
137 | } | ||
138 | 148 | ||
139 | /** | 149 | gpio = kzalloc(sizeof(struct intel_gpio), GFP_KERNEL); |
140 | * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg | 150 | if (gpio == NULL) |
141 | * @dev: DRM device | 151 | return NULL; |
142 | * @output: driver specific output device | ||
143 | * @reg: GPIO reg to use | ||
144 | * @name: name for this bus | ||
145 | * @slave_addr: slave address (if fixed) | ||
146 | * | ||
147 | * Creates and registers a new i2c bus with the Linux i2c layer, for use | ||
148 | * in output probing and control (e.g. DDC or SDVO control functions). | ||
149 | * | ||
150 | * Possible values for @reg include: | ||
151 | * %GPIOA | ||
152 | * %GPIOB | ||
153 | * %GPIOC | ||
154 | * %GPIOD | ||
155 | * %GPIOE | ||
156 | * %GPIOF | ||
157 | * %GPIOG | ||
158 | * %GPIOH | ||
159 | * see PRM for details on how these different busses are used. | ||
160 | */ | ||
161 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, | ||
162 | const char *name) | ||
163 | { | ||
164 | struct intel_i2c_chan *chan; | ||
165 | 152 | ||
166 | chan = kzalloc(sizeof(struct intel_i2c_chan), GFP_KERNEL); | 153 | gpio->reg = map_pin_to_reg[pin]; |
167 | if (!chan) | 154 | if (HAS_PCH_SPLIT(dev_priv->dev)) |
168 | goto out_free; | 155 | gpio->reg += PCH_GPIOA - GPIOA; |
156 | gpio->dev_priv = dev_priv; | ||
157 | |||
158 | snprintf(gpio->adapter.name, I2C_NAME_SIZE, "GPIO %d", pin); | ||
159 | gpio->adapter.owner = THIS_MODULE; | ||
160 | gpio->adapter.algo_data = &gpio->algo; | ||
161 | gpio->adapter.dev.parent = &dev_priv->dev->pdev->dev; | ||
162 | gpio->algo.setsda = set_data; | ||
163 | gpio->algo.setscl = set_clock; | ||
164 | gpio->algo.getsda = get_data; | ||
165 | gpio->algo.getscl = get_clock; | ||
166 | gpio->algo.udelay = I2C_RISEFALL_TIME; | ||
167 | gpio->algo.timeout = usecs_to_jiffies(2200); | ||
168 | gpio->algo.data = gpio; | ||
169 | 169 | ||
170 | chan->drm_dev = dev; | 170 | if (i2c_bit_add_bus(&gpio->adapter)) |
171 | chan->reg = reg; | ||
172 | snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name); | ||
173 | chan->adapter.owner = THIS_MODULE; | ||
174 | chan->adapter.algo_data = &chan->algo; | ||
175 | chan->adapter.dev.parent = &dev->pdev->dev; | ||
176 | chan->algo.setsda = set_data; | ||
177 | chan->algo.setscl = set_clock; | ||
178 | chan->algo.getsda = get_data; | ||
179 | chan->algo.getscl = get_clock; | ||
180 | chan->algo.udelay = 20; | ||
181 | chan->algo.timeout = usecs_to_jiffies(2200); | ||
182 | chan->algo.data = chan; | ||
183 | |||
184 | i2c_set_adapdata(&chan->adapter, chan); | ||
185 | |||
186 | if(i2c_bit_add_bus(&chan->adapter)) | ||
187 | goto out_free; | 171 | goto out_free; |
188 | 172 | ||
189 | intel_i2c_reset_gmbus(dev); | 173 | intel_i2c_reset(dev_priv->dev); |
190 | 174 | ||
191 | /* JJJ: raise SCL and SDA? */ | 175 | /* JJJ: raise SCL and SDA? */ |
192 | intel_i2c_quirk_set(dev, true); | 176 | intel_i2c_quirk_set(dev_priv, true); |
193 | set_data(chan, 1); | 177 | set_data(gpio, 1); |
194 | set_clock(chan, 1); | 178 | udelay(I2C_RISEFALL_TIME); |
195 | intel_i2c_quirk_set(dev, false); | 179 | set_clock(gpio, 1); |
196 | udelay(20); | 180 | udelay(I2C_RISEFALL_TIME); |
181 | intel_i2c_quirk_set(dev_priv, false); | ||
197 | 182 | ||
198 | return &chan->adapter; | 183 | return &gpio->adapter; |
199 | 184 | ||
200 | out_free: | 185 | out_free: |
201 | kfree(chan); | 186 | kfree(gpio); |
202 | return NULL; | 187 | return NULL; |
203 | } | 188 | } |
204 | 189 | ||
190 | static int | ||
191 | quirk_i2c_transfer(struct drm_i915_private *dev_priv, | ||
192 | struct i2c_adapter *adapter, | ||
193 | struct i2c_msg *msgs, | ||
194 | int num) | ||
195 | { | ||
196 | int ret; | ||
197 | |||
198 | intel_i2c_reset(dev_priv->dev); | ||
199 | |||
200 | intel_i2c_quirk_set(dev_priv, true); | ||
201 | ret = i2c_transfer(adapter, msgs, num); | ||
202 | intel_i2c_quirk_set(dev_priv, false); | ||
203 | |||
204 | return ret; | ||
205 | } | ||
206 | |||
207 | static int | ||
208 | gmbus_xfer(struct i2c_adapter *adapter, | ||
209 | struct i2c_msg *msgs, | ||
210 | int num) | ||
211 | { | ||
212 | struct intel_gmbus *bus = container_of(adapter, | ||
213 | struct intel_gmbus, | ||
214 | adapter); | ||
215 | struct drm_i915_private *dev_priv = adapter->algo_data; | ||
216 | int i, speed, reg_offset; | ||
217 | |||
218 | if (bus->force_bitbanging) | ||
219 | return quirk_i2c_transfer(dev_priv, bus->force_bitbanging, msgs, num); | ||
220 | |||
221 | reg_offset = HAS_PCH_SPLIT(dev_priv->dev) ? PCH_GMBUS0 - GMBUS0 : 0; | ||
222 | |||
223 | speed = GMBUS_RATE_100KHZ; | ||
224 | if (INTEL_INFO(dev_priv->dev)->gen > 4 || IS_G4X(dev_priv->dev)) { | ||
225 | if (bus->pin == GMBUS_PORT_DPB) /* SDVO only? */ | ||
226 | speed = GMBUS_RATE_1MHZ; | ||
227 | else | ||
228 | speed = GMBUS_RATE_400KHZ; | ||
229 | } | ||
230 | I915_WRITE(GMBUS0 + reg_offset, speed | bus->pin); | ||
231 | |||
232 | for (i = 0; i < num; i++) { | ||
233 | u16 len = msgs[i].len; | ||
234 | u8 *buf = msgs[i].buf; | ||
235 | |||
236 | if (msgs[i].flags & I2C_M_RD) { | ||
237 | I915_WRITE(GMBUS1 + reg_offset, | ||
238 | GMBUS_CYCLE_WAIT | (i + 1 == num ? GMBUS_CYCLE_STOP : 0) | | ||
239 | (len << GMBUS_BYTE_COUNT_SHIFT) | | ||
240 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | | ||
241 | GMBUS_SLAVE_READ | GMBUS_SW_RDY); | ||
242 | do { | ||
243 | u32 val, loop = 0; | ||
244 | |||
245 | if (wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) | ||
246 | goto timeout; | ||
247 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | ||
248 | return 0; | ||
249 | |||
250 | val = I915_READ(GMBUS3 + reg_offset); | ||
251 | do { | ||
252 | *buf++ = val & 0xff; | ||
253 | val >>= 8; | ||
254 | } while (--len && ++loop < 4); | ||
255 | } while (len); | ||
256 | } else { | ||
257 | u32 val = 0, loop = 0; | ||
258 | |||
259 | BUG_ON(msgs[i].len > 4); | ||
260 | |||
261 | do { | ||
262 | val |= *buf++ << (loop*8); | ||
263 | } while (--len && +loop < 4); | ||
264 | |||
265 | I915_WRITE(GMBUS3 + reg_offset, val); | ||
266 | I915_WRITE(GMBUS1 + reg_offset, | ||
267 | (i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT ) | | ||
268 | (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) | | ||
269 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | | ||
270 | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); | ||
271 | } | ||
272 | |||
273 | if (i + 1 < num && wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50)) | ||
274 | goto timeout; | ||
275 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | return num; | ||
280 | |||
281 | timeout: | ||
282 | DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d\n", bus->pin); | ||
283 | /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ | ||
284 | bus->force_bitbanging = intel_gpio_create(dev_priv, bus->pin); | ||
285 | if (!bus->force_bitbanging) | ||
286 | return -ENOMEM; | ||
287 | |||
288 | return quirk_i2c_transfer(dev_priv, bus->force_bitbanging, msgs, num); | ||
289 | } | ||
290 | |||
291 | static u32 gmbus_func(struct i2c_adapter *adapter) | ||
292 | { | ||
293 | return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | | ||
294 | /* I2C_FUNC_10BIT_ADDR | */ | ||
295 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | | ||
296 | I2C_FUNC_SMBUS_BLOCK_PROC_CALL); | ||
297 | } | ||
298 | |||
299 | static const struct i2c_algorithm gmbus_algorithm = { | ||
300 | .master_xfer = gmbus_xfer, | ||
301 | .functionality = gmbus_func | ||
302 | }; | ||
303 | |||
205 | /** | 304 | /** |
206 | * intel_i2c_destroy - unregister and free i2c bus resources | 305 | * intel_gmbus_setup - instantiate all Intel i2c GMBuses |
207 | * @output: channel to free | 306 | * @dev: DRM device |
208 | * | ||
209 | * Unregister the adapter from the i2c layer, then free the structure. | ||
210 | */ | 307 | */ |
211 | void intel_i2c_destroy(struct i2c_adapter *adapter) | 308 | int intel_setup_gmbus(struct drm_device *dev) |
212 | { | 309 | { |
213 | struct intel_i2c_chan *chan; | 310 | static const char *names[] = { |
311 | "disabled", | ||
312 | "ssc", | ||
313 | "vga", | ||
314 | "panel", | ||
315 | "dpc", | ||
316 | "dpb", | ||
317 | "dpd", | ||
318 | "reserved" | ||
319 | }; | ||
320 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
321 | int ret, i; | ||
322 | |||
323 | dev_priv->gmbus = kcalloc(sizeof(struct intel_gmbus), GMBUS_NUM_PORTS, | ||
324 | GFP_KERNEL); | ||
325 | if (dev_priv->gmbus == NULL) | ||
326 | return -ENOMEM; | ||
327 | |||
328 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { | ||
329 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; | ||
330 | |||
331 | bus->adapter.owner = THIS_MODULE; | ||
332 | bus->adapter.class = I2C_CLASS_DDC; | ||
333 | snprintf(bus->adapter.name, | ||
334 | I2C_NAME_SIZE, | ||
335 | "gmbus %s", | ||
336 | names[i]); | ||
337 | |||
338 | bus->adapter.dev.parent = &dev->pdev->dev; | ||
339 | bus->adapter.algo_data = dev_priv; | ||
340 | |||
341 | bus->adapter.algo = &gmbus_algorithm; | ||
342 | ret = i2c_add_adapter(&bus->adapter); | ||
343 | if (ret) | ||
344 | goto err; | ||
345 | |||
346 | bus->pin = i; | ||
347 | } | ||
214 | 348 | ||
215 | if (!adapter) | 349 | intel_i2c_reset(dev_priv->dev); |
350 | |||
351 | return 0; | ||
352 | |||
353 | err: | ||
354 | while (--i) { | ||
355 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; | ||
356 | i2c_del_adapter(&bus->adapter); | ||
357 | } | ||
358 | kfree(dev_priv->gmbus); | ||
359 | dev_priv->gmbus = NULL; | ||
360 | return ret; | ||
361 | } | ||
362 | |||
363 | void intel_teardown_gmbus(struct drm_device *dev) | ||
364 | { | ||
365 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
366 | int i; | ||
367 | |||
368 | if (dev_priv->gmbus == NULL) | ||
216 | return; | 369 | return; |
217 | 370 | ||
218 | chan = container_of(adapter, | 371 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { |
219 | struct intel_i2c_chan, | 372 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; |
220 | adapter); | 373 | if (bus->force_bitbanging) { |
221 | i2c_del_adapter(&chan->adapter); | 374 | i2c_del_adapter(bus->force_bitbanging); |
222 | kfree(chan); | 375 | kfree(bus->force_bitbanging); |
376 | } | ||
377 | i2c_del_adapter(&bus->adapter); | ||
378 | } | ||
379 | |||
380 | kfree(dev_priv->gmbus); | ||
381 | dev_priv->gmbus = NULL; | ||
223 | } | 382 | } |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 6ec39a86ed06..f6a72cbb152d 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -43,102 +43,75 @@ | |||
43 | /* Private structure for the integrated LVDS support */ | 43 | /* Private structure for the integrated LVDS support */ |
44 | struct intel_lvds { | 44 | struct intel_lvds { |
45 | struct intel_encoder base; | 45 | struct intel_encoder base; |
46 | |||
47 | bool edid_good; | ||
48 | |||
46 | int fitting_mode; | 49 | int fitting_mode; |
47 | u32 pfit_control; | 50 | u32 pfit_control; |
48 | u32 pfit_pgm_ratios; | 51 | u32 pfit_pgm_ratios; |
52 | bool pfit_dirty; | ||
53 | |||
54 | struct drm_display_mode *fixed_mode; | ||
49 | }; | 55 | }; |
50 | 56 | ||
51 | static struct intel_lvds *enc_to_intel_lvds(struct drm_encoder *encoder) | 57 | static struct intel_lvds *to_intel_lvds(struct drm_encoder *encoder) |
52 | { | 58 | { |
53 | return container_of(enc_to_intel_encoder(encoder), struct intel_lvds, base); | 59 | return container_of(encoder, struct intel_lvds, base.base); |
54 | } | 60 | } |
55 | 61 | ||
56 | /** | 62 | static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) |
57 | * Sets the backlight level. | ||
58 | * | ||
59 | * \param level backlight level, from 0 to intel_lvds_get_max_backlight(). | ||
60 | */ | ||
61 | static void intel_lvds_set_backlight(struct drm_device *dev, int level) | ||
62 | { | 63 | { |
63 | struct drm_i915_private *dev_priv = dev->dev_private; | 64 | return container_of(intel_attached_encoder(connector), |
64 | u32 blc_pwm_ctl, reg; | 65 | struct intel_lvds, base); |
65 | |||
66 | if (HAS_PCH_SPLIT(dev)) | ||
67 | reg = BLC_PWM_CPU_CTL; | ||
68 | else | ||
69 | reg = BLC_PWM_CTL; | ||
70 | |||
71 | blc_pwm_ctl = I915_READ(reg) & ~BACKLIGHT_DUTY_CYCLE_MASK; | ||
72 | I915_WRITE(reg, (blc_pwm_ctl | | ||
73 | (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); | ||
74 | } | ||
75 | |||
76 | /** | ||
77 | * Returns the maximum level of the backlight duty cycle field. | ||
78 | */ | ||
79 | static u32 intel_lvds_get_max_backlight(struct drm_device *dev) | ||
80 | { | ||
81 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
82 | u32 reg; | ||
83 | |||
84 | if (HAS_PCH_SPLIT(dev)) | ||
85 | reg = BLC_PWM_PCH_CTL2; | ||
86 | else | ||
87 | reg = BLC_PWM_CTL; | ||
88 | |||
89 | return ((I915_READ(reg) & BACKLIGHT_MODULATION_FREQ_MASK) >> | ||
90 | BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; | ||
91 | } | 66 | } |
92 | 67 | ||
93 | /** | 68 | /** |
94 | * Sets the power state for the panel. | 69 | * Sets the power state for the panel. |
95 | */ | 70 | */ |
96 | static void intel_lvds_set_power(struct drm_device *dev, bool on) | 71 | static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) |
97 | { | 72 | { |
73 | struct drm_device *dev = intel_lvds->base.base.dev; | ||
98 | struct drm_i915_private *dev_priv = dev->dev_private; | 74 | struct drm_i915_private *dev_priv = dev->dev_private; |
99 | u32 ctl_reg, status_reg, lvds_reg; | 75 | u32 ctl_reg, lvds_reg; |
100 | 76 | ||
101 | if (HAS_PCH_SPLIT(dev)) { | 77 | if (HAS_PCH_SPLIT(dev)) { |
102 | ctl_reg = PCH_PP_CONTROL; | 78 | ctl_reg = PCH_PP_CONTROL; |
103 | status_reg = PCH_PP_STATUS; | ||
104 | lvds_reg = PCH_LVDS; | 79 | lvds_reg = PCH_LVDS; |
105 | } else { | 80 | } else { |
106 | ctl_reg = PP_CONTROL; | 81 | ctl_reg = PP_CONTROL; |
107 | status_reg = PP_STATUS; | ||
108 | lvds_reg = LVDS; | 82 | lvds_reg = LVDS; |
109 | } | 83 | } |
110 | 84 | ||
111 | if (on) { | 85 | if (on) { |
112 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); | 86 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); |
113 | POSTING_READ(lvds_reg); | 87 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); |
114 | 88 | intel_panel_set_backlight(dev, dev_priv->backlight_level); | |
115 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | | ||
116 | POWER_TARGET_ON); | ||
117 | if (wait_for(I915_READ(status_reg) & PP_ON, 1000, 0)) | ||
118 | DRM_ERROR("timed out waiting to enable LVDS pipe"); | ||
119 | |||
120 | intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle); | ||
121 | } else { | 89 | } else { |
122 | intel_lvds_set_backlight(dev, 0); | 90 | dev_priv->backlight_level = intel_panel_get_backlight(dev); |
123 | 91 | ||
124 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & | 92 | intel_panel_set_backlight(dev, 0); |
125 | ~POWER_TARGET_ON); | 93 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); |
126 | if (wait_for((I915_READ(status_reg) & PP_ON) == 0, 1000, 0)) | 94 | |
127 | DRM_ERROR("timed out waiting for LVDS pipe to turn off"); | 95 | if (intel_lvds->pfit_control) { |
96 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | ||
97 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
98 | I915_WRITE(PFIT_CONTROL, 0); | ||
99 | intel_lvds->pfit_control = 0; | ||
100 | } | ||
128 | 101 | ||
129 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | 102 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); |
130 | POSTING_READ(lvds_reg); | ||
131 | } | 103 | } |
104 | POSTING_READ(lvds_reg); | ||
132 | } | 105 | } |
133 | 106 | ||
134 | static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) | 107 | static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) |
135 | { | 108 | { |
136 | struct drm_device *dev = encoder->dev; | 109 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
137 | 110 | ||
138 | if (mode == DRM_MODE_DPMS_ON) | 111 | if (mode == DRM_MODE_DPMS_ON) |
139 | intel_lvds_set_power(dev, true); | 112 | intel_lvds_set_power(intel_lvds, true); |
140 | else | 113 | else |
141 | intel_lvds_set_power(dev, false); | 114 | intel_lvds_set_power(intel_lvds, false); |
142 | 115 | ||
143 | /* XXX: We never power down the LVDS pairs. */ | 116 | /* XXX: We never power down the LVDS pairs. */ |
144 | } | 117 | } |
@@ -146,16 +119,13 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
146 | static int intel_lvds_mode_valid(struct drm_connector *connector, | 119 | static int intel_lvds_mode_valid(struct drm_connector *connector, |
147 | struct drm_display_mode *mode) | 120 | struct drm_display_mode *mode) |
148 | { | 121 | { |
149 | struct drm_device *dev = connector->dev; | 122 | struct intel_lvds *intel_lvds = intel_attached_lvds(connector); |
150 | struct drm_i915_private *dev_priv = dev->dev_private; | 123 | struct drm_display_mode *fixed_mode = intel_lvds->fixed_mode; |
151 | struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode; | ||
152 | 124 | ||
153 | if (fixed_mode) { | 125 | if (mode->hdisplay > fixed_mode->hdisplay) |
154 | if (mode->hdisplay > fixed_mode->hdisplay) | 126 | return MODE_PANEL; |
155 | return MODE_PANEL; | 127 | if (mode->vdisplay > fixed_mode->vdisplay) |
156 | if (mode->vdisplay > fixed_mode->vdisplay) | 128 | return MODE_PANEL; |
157 | return MODE_PANEL; | ||
158 | } | ||
159 | 129 | ||
160 | return MODE_OK; | 130 | return MODE_OK; |
161 | } | 131 | } |
@@ -223,7 +193,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
223 | struct drm_device *dev = encoder->dev; | 193 | struct drm_device *dev = encoder->dev; |
224 | struct drm_i915_private *dev_priv = dev->dev_private; | 194 | struct drm_i915_private *dev_priv = dev->dev_private; |
225 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 195 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
226 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); | 196 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
227 | struct drm_encoder *tmp_encoder; | 197 | struct drm_encoder *tmp_encoder; |
228 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; | 198 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
229 | 199 | ||
@@ -241,9 +211,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
241 | return false; | 211 | return false; |
242 | } | 212 | } |
243 | } | 213 | } |
244 | /* If we don't have a panel mode, there is nothing we can do */ | ||
245 | if (dev_priv->panel_fixed_mode == NULL) | ||
246 | return true; | ||
247 | 214 | ||
248 | /* | 215 | /* |
249 | * We have timings from the BIOS for the panel, put them in | 216 | * We have timings from the BIOS for the panel, put them in |
@@ -251,7 +218,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
251 | * with the panel scaling set up to source from the H/VDisplay | 218 | * with the panel scaling set up to source from the H/VDisplay |
252 | * of the original mode. | 219 | * of the original mode. |
253 | */ | 220 | */ |
254 | intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode); | 221 | intel_fixed_panel_mode(intel_lvds->fixed_mode, adjusted_mode); |
255 | 222 | ||
256 | if (HAS_PCH_SPLIT(dev)) { | 223 | if (HAS_PCH_SPLIT(dev)) { |
257 | intel_pch_panel_fitting(dev, intel_lvds->fitting_mode, | 224 | intel_pch_panel_fitting(dev, intel_lvds->fitting_mode, |
@@ -369,8 +336,12 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
369 | } | 336 | } |
370 | 337 | ||
371 | out: | 338 | out: |
372 | intel_lvds->pfit_control = pfit_control; | 339 | if (pfit_control != intel_lvds->pfit_control || |
373 | intel_lvds->pfit_pgm_ratios = pfit_pgm_ratios; | 340 | pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) { |
341 | intel_lvds->pfit_control = pfit_control; | ||
342 | intel_lvds->pfit_pgm_ratios = pfit_pgm_ratios; | ||
343 | intel_lvds->pfit_dirty = true; | ||
344 | } | ||
374 | dev_priv->lvds_border_bits = border; | 345 | dev_priv->lvds_border_bits = border; |
375 | 346 | ||
376 | /* | 347 | /* |
@@ -386,30 +357,60 @@ static void intel_lvds_prepare(struct drm_encoder *encoder) | |||
386 | { | 357 | { |
387 | struct drm_device *dev = encoder->dev; | 358 | struct drm_device *dev = encoder->dev; |
388 | struct drm_i915_private *dev_priv = dev->dev_private; | 359 | struct drm_i915_private *dev_priv = dev->dev_private; |
389 | u32 reg; | 360 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
390 | 361 | ||
391 | if (HAS_PCH_SPLIT(dev)) | 362 | dev_priv->backlight_level = intel_panel_get_backlight(dev); |
392 | reg = BLC_PWM_CPU_CTL; | 363 | |
393 | else | 364 | /* We try to do the minimum that is necessary in order to unlock |
394 | reg = BLC_PWM_CTL; | 365 | * the registers for mode setting. |
395 | 366 | * | |
396 | dev_priv->saveBLC_PWM_CTL = I915_READ(reg); | 367 | * On Ironlake, this is quite simple as we just set the unlock key |
397 | dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL & | 368 | * and ignore all subtleties. (This may cause some issues...) |
398 | BACKLIGHT_DUTY_CYCLE_MASK); | 369 | * |
370 | * Prior to Ironlake, we must disable the pipe if we want to adjust | ||
371 | * the panel fitter. However at all other times we can just reset | ||
372 | * the registers regardless. | ||
373 | */ | ||
399 | 374 | ||
400 | intel_lvds_set_power(dev, false); | 375 | if (HAS_PCH_SPLIT(dev)) { |
376 | I915_WRITE(PCH_PP_CONTROL, | ||
377 | I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
378 | } else if (intel_lvds->pfit_dirty) { | ||
379 | I915_WRITE(PP_CONTROL, | ||
380 | I915_READ(PP_CONTROL) & ~POWER_TARGET_ON); | ||
381 | I915_WRITE(LVDS, I915_READ(LVDS) & ~LVDS_PORT_EN); | ||
382 | } else { | ||
383 | I915_WRITE(PP_CONTROL, | ||
384 | I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); | ||
385 | } | ||
401 | } | 386 | } |
402 | 387 | ||
403 | static void intel_lvds_commit( struct drm_encoder *encoder) | 388 | static void intel_lvds_commit(struct drm_encoder *encoder) |
404 | { | 389 | { |
405 | struct drm_device *dev = encoder->dev; | 390 | struct drm_device *dev = encoder->dev; |
406 | struct drm_i915_private *dev_priv = dev->dev_private; | 391 | struct drm_i915_private *dev_priv = dev->dev_private; |
392 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | ||
407 | 393 | ||
408 | if (dev_priv->backlight_duty_cycle == 0) | 394 | if (dev_priv->backlight_level == 0) |
409 | dev_priv->backlight_duty_cycle = | 395 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); |
410 | intel_lvds_get_max_backlight(dev); | ||
411 | 396 | ||
412 | intel_lvds_set_power(dev, true); | 397 | /* Undo any unlocking done in prepare to prevent accidental |
398 | * adjustment of the registers. | ||
399 | */ | ||
400 | if (HAS_PCH_SPLIT(dev)) { | ||
401 | u32 val = I915_READ(PCH_PP_CONTROL); | ||
402 | if ((val & PANEL_UNLOCK_REGS) == PANEL_UNLOCK_REGS) | ||
403 | I915_WRITE(PCH_PP_CONTROL, val & 0x3); | ||
404 | } else { | ||
405 | u32 val = I915_READ(PP_CONTROL); | ||
406 | if ((val & PANEL_UNLOCK_REGS) == PANEL_UNLOCK_REGS) | ||
407 | I915_WRITE(PP_CONTROL, val & 0x3); | ||
408 | } | ||
409 | |||
410 | /* Always do a full power on as we do not know what state | ||
411 | * we were left in. | ||
412 | */ | ||
413 | intel_lvds_set_power(intel_lvds, true); | ||
413 | } | 414 | } |
414 | 415 | ||
415 | static void intel_lvds_mode_set(struct drm_encoder *encoder, | 416 | static void intel_lvds_mode_set(struct drm_encoder *encoder, |
@@ -418,7 +419,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
418 | { | 419 | { |
419 | struct drm_device *dev = encoder->dev; | 420 | struct drm_device *dev = encoder->dev; |
420 | struct drm_i915_private *dev_priv = dev->dev_private; | 421 | struct drm_i915_private *dev_priv = dev->dev_private; |
421 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); | 422 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
422 | 423 | ||
423 | /* | 424 | /* |
424 | * The LVDS pin pair will already have been turned on in the | 425 | * The LVDS pin pair will already have been turned on in the |
@@ -429,13 +430,20 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
429 | if (HAS_PCH_SPLIT(dev)) | 430 | if (HAS_PCH_SPLIT(dev)) |
430 | return; | 431 | return; |
431 | 432 | ||
433 | if (!intel_lvds->pfit_dirty) | ||
434 | return; | ||
435 | |||
432 | /* | 436 | /* |
433 | * Enable automatic panel scaling so that non-native modes fill the | 437 | * Enable automatic panel scaling so that non-native modes fill the |
434 | * screen. Should be enabled before the pipe is enabled, according to | 438 | * screen. Should be enabled before the pipe is enabled, according to |
435 | * register description and PRM. | 439 | * register description and PRM. |
436 | */ | 440 | */ |
441 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | ||
442 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
443 | |||
437 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); | 444 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); |
438 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); | 445 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); |
446 | intel_lvds->pfit_dirty = false; | ||
439 | } | 447 | } |
440 | 448 | ||
441 | /** | 449 | /** |
@@ -465,38 +473,24 @@ intel_lvds_detect(struct drm_connector *connector, bool force) | |||
465 | */ | 473 | */ |
466 | static int intel_lvds_get_modes(struct drm_connector *connector) | 474 | static int intel_lvds_get_modes(struct drm_connector *connector) |
467 | { | 475 | { |
476 | struct intel_lvds *intel_lvds = intel_attached_lvds(connector); | ||
468 | struct drm_device *dev = connector->dev; | 477 | struct drm_device *dev = connector->dev; |
469 | struct drm_encoder *encoder = intel_attached_encoder(connector); | ||
470 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
471 | struct drm_i915_private *dev_priv = dev->dev_private; | 478 | struct drm_i915_private *dev_priv = dev->dev_private; |
472 | int ret = 0; | 479 | struct drm_display_mode *mode; |
473 | |||
474 | if (dev_priv->lvds_edid_good) { | ||
475 | ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | ||
476 | 480 | ||
481 | if (intel_lvds->edid_good) { | ||
482 | int ret = intel_ddc_get_modes(connector, | ||
483 | &dev_priv->gmbus[GMBUS_PORT_PANEL].adapter); | ||
477 | if (ret) | 484 | if (ret) |
478 | return ret; | 485 | return ret; |
479 | } | 486 | } |
480 | 487 | ||
481 | /* Didn't get an EDID, so | 488 | mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode); |
482 | * Set wide sync ranges so we get all modes | 489 | if (mode == 0) |
483 | * handed to valid_mode for checking | 490 | return 0; |
484 | */ | ||
485 | connector->display_info.min_vfreq = 0; | ||
486 | connector->display_info.max_vfreq = 200; | ||
487 | connector->display_info.min_hfreq = 0; | ||
488 | connector->display_info.max_hfreq = 200; | ||
489 | |||
490 | if (dev_priv->panel_fixed_mode != NULL) { | ||
491 | struct drm_display_mode *mode; | ||
492 | |||
493 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); | ||
494 | drm_mode_probed_add(connector, mode); | ||
495 | |||
496 | return 1; | ||
497 | } | ||
498 | 491 | ||
499 | return 0; | 492 | drm_mode_probed_add(connector, mode); |
493 | return 1; | ||
500 | } | 494 | } |
501 | 495 | ||
502 | static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id) | 496 | static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id) |
@@ -587,18 +581,17 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
587 | struct drm_property *property, | 581 | struct drm_property *property, |
588 | uint64_t value) | 582 | uint64_t value) |
589 | { | 583 | { |
584 | struct intel_lvds *intel_lvds = intel_attached_lvds(connector); | ||
590 | struct drm_device *dev = connector->dev; | 585 | struct drm_device *dev = connector->dev; |
591 | 586 | ||
592 | if (property == dev->mode_config.scaling_mode_property && | 587 | if (property == dev->mode_config.scaling_mode_property) { |
593 | connector->encoder) { | 588 | struct drm_crtc *crtc = intel_lvds->base.base.crtc; |
594 | struct drm_crtc *crtc = connector->encoder->crtc; | ||
595 | struct drm_encoder *encoder = connector->encoder; | ||
596 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); | ||
597 | 589 | ||
598 | if (value == DRM_MODE_SCALE_NONE) { | 590 | if (value == DRM_MODE_SCALE_NONE) { |
599 | DRM_DEBUG_KMS("no scaling not supported\n"); | 591 | DRM_DEBUG_KMS("no scaling not supported\n"); |
600 | return 0; | 592 | return -EINVAL; |
601 | } | 593 | } |
594 | |||
602 | if (intel_lvds->fitting_mode == value) { | 595 | if (intel_lvds->fitting_mode == value) { |
603 | /* the LVDS scaling property is not changed */ | 596 | /* the LVDS scaling property is not changed */ |
604 | return 0; | 597 | return 0; |
@@ -628,7 +621,7 @@ static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { | |||
628 | static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { | 621 | static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { |
629 | .get_modes = intel_lvds_get_modes, | 622 | .get_modes = intel_lvds_get_modes, |
630 | .mode_valid = intel_lvds_mode_valid, | 623 | .mode_valid = intel_lvds_mode_valid, |
631 | .best_encoder = intel_attached_encoder, | 624 | .best_encoder = intel_best_encoder, |
632 | }; | 625 | }; |
633 | 626 | ||
634 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { | 627 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { |
@@ -726,16 +719,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
726 | * Find the reduced downclock for LVDS in EDID. | 719 | * Find the reduced downclock for LVDS in EDID. |
727 | */ | 720 | */ |
728 | static void intel_find_lvds_downclock(struct drm_device *dev, | 721 | static void intel_find_lvds_downclock(struct drm_device *dev, |
729 | struct drm_connector *connector) | 722 | struct drm_display_mode *fixed_mode, |
723 | struct drm_connector *connector) | ||
730 | { | 724 | { |
731 | struct drm_i915_private *dev_priv = dev->dev_private; | 725 | struct drm_i915_private *dev_priv = dev->dev_private; |
732 | struct drm_display_mode *scan, *panel_fixed_mode; | 726 | struct drm_display_mode *scan; |
733 | int temp_downclock; | 727 | int temp_downclock; |
734 | 728 | ||
735 | panel_fixed_mode = dev_priv->panel_fixed_mode; | 729 | temp_downclock = fixed_mode->clock; |
736 | temp_downclock = panel_fixed_mode->clock; | ||
737 | |||
738 | mutex_lock(&dev->mode_config.mutex); | ||
739 | list_for_each_entry(scan, &connector->probed_modes, head) { | 730 | list_for_each_entry(scan, &connector->probed_modes, head) { |
740 | /* | 731 | /* |
741 | * If one mode has the same resolution with the fixed_panel | 732 | * If one mode has the same resolution with the fixed_panel |
@@ -744,14 +735,14 @@ static void intel_find_lvds_downclock(struct drm_device *dev, | |||
744 | * case we can set the different FPx0/1 to dynamically select | 735 | * case we can set the different FPx0/1 to dynamically select |
745 | * between low and high frequency. | 736 | * between low and high frequency. |
746 | */ | 737 | */ |
747 | if (scan->hdisplay == panel_fixed_mode->hdisplay && | 738 | if (scan->hdisplay == fixed_mode->hdisplay && |
748 | scan->hsync_start == panel_fixed_mode->hsync_start && | 739 | scan->hsync_start == fixed_mode->hsync_start && |
749 | scan->hsync_end == panel_fixed_mode->hsync_end && | 740 | scan->hsync_end == fixed_mode->hsync_end && |
750 | scan->htotal == panel_fixed_mode->htotal && | 741 | scan->htotal == fixed_mode->htotal && |
751 | scan->vdisplay == panel_fixed_mode->vdisplay && | 742 | scan->vdisplay == fixed_mode->vdisplay && |
752 | scan->vsync_start == panel_fixed_mode->vsync_start && | 743 | scan->vsync_start == fixed_mode->vsync_start && |
753 | scan->vsync_end == panel_fixed_mode->vsync_end && | 744 | scan->vsync_end == fixed_mode->vsync_end && |
754 | scan->vtotal == panel_fixed_mode->vtotal) { | 745 | scan->vtotal == fixed_mode->vtotal) { |
755 | if (scan->clock < temp_downclock) { | 746 | if (scan->clock < temp_downclock) { |
756 | /* | 747 | /* |
757 | * The downclock is already found. But we | 748 | * The downclock is already found. But we |
@@ -761,17 +752,14 @@ static void intel_find_lvds_downclock(struct drm_device *dev, | |||
761 | } | 752 | } |
762 | } | 753 | } |
763 | } | 754 | } |
764 | mutex_unlock(&dev->mode_config.mutex); | 755 | if (temp_downclock < fixed_mode->clock && i915_lvds_downclock) { |
765 | if (temp_downclock < panel_fixed_mode->clock && | ||
766 | i915_lvds_downclock) { | ||
767 | /* We found the downclock for LVDS. */ | 756 | /* We found the downclock for LVDS. */ |
768 | dev_priv->lvds_downclock_avail = 1; | 757 | dev_priv->lvds_downclock_avail = 1; |
769 | dev_priv->lvds_downclock = temp_downclock; | 758 | dev_priv->lvds_downclock = temp_downclock; |
770 | DRM_DEBUG_KMS("LVDS downclock is found in EDID. " | 759 | DRM_DEBUG_KMS("LVDS downclock is found in EDID. " |
771 | "Normal clock %dKhz, downclock %dKhz\n", | 760 | "Normal clock %dKhz, downclock %dKhz\n", |
772 | panel_fixed_mode->clock, temp_downclock); | 761 | fixed_mode->clock, temp_downclock); |
773 | } | 762 | } |
774 | return; | ||
775 | } | 763 | } |
776 | 764 | ||
777 | /* | 765 | /* |
@@ -780,38 +768,44 @@ static void intel_find_lvds_downclock(struct drm_device *dev, | |||
780 | * If it is present, return 1. | 768 | * If it is present, return 1. |
781 | * If it is not present, return false. | 769 | * If it is not present, return false. |
782 | * If no child dev is parsed from VBT, it assumes that the LVDS is present. | 770 | * If no child dev is parsed from VBT, it assumes that the LVDS is present. |
783 | * Note: The addin_offset should also be checked for LVDS panel. | ||
784 | * Only when it is non-zero, it is assumed that it is present. | ||
785 | */ | 771 | */ |
786 | static int lvds_is_present_in_vbt(struct drm_device *dev) | 772 | static bool lvds_is_present_in_vbt(struct drm_device *dev) |
787 | { | 773 | { |
788 | struct drm_i915_private *dev_priv = dev->dev_private; | 774 | struct drm_i915_private *dev_priv = dev->dev_private; |
789 | struct child_device_config *p_child; | 775 | int i; |
790 | int i, ret; | ||
791 | 776 | ||
792 | if (!dev_priv->child_dev_num) | 777 | if (!dev_priv->child_dev_num) |
793 | return 1; | 778 | return true; |
794 | 779 | ||
795 | ret = 0; | ||
796 | for (i = 0; i < dev_priv->child_dev_num; i++) { | 780 | for (i = 0; i < dev_priv->child_dev_num; i++) { |
797 | p_child = dev_priv->child_dev + i; | 781 | struct child_device_config *child = dev_priv->child_dev + i; |
798 | /* | 782 | |
799 | * If the device type is not LFP, continue. | 783 | /* If the device type is not LFP, continue. |
800 | * If the device type is 0x22, it is also regarded as LFP. | 784 | * We have to check both the new identifiers as well as the |
785 | * old for compatibility with some BIOSes. | ||
801 | */ | 786 | */ |
802 | if (p_child->device_type != DEVICE_TYPE_INT_LFP && | 787 | if (child->device_type != DEVICE_TYPE_INT_LFP && |
803 | p_child->device_type != DEVICE_TYPE_LFP) | 788 | child->device_type != DEVICE_TYPE_LFP) |
804 | continue; | 789 | continue; |
805 | 790 | ||
806 | /* The addin_offset should be checked. Only when it is | 791 | /* However, we cannot trust the BIOS writers to populate |
807 | * non-zero, it is regarded as present. | 792 | * the VBT correctly. Since LVDS requires additional |
793 | * information from AIM blocks, a non-zero addin offset is | ||
794 | * a good indicator that the LVDS is actually present. | ||
808 | */ | 795 | */ |
809 | if (p_child->addin_offset) { | 796 | if (child->addin_offset) |
810 | ret = 1; | 797 | return true; |
811 | break; | 798 | |
812 | } | 799 | /* But even then some BIOS writers perform some black magic |
800 | * and instantiate the device without reference to any | ||
801 | * additional data. Trust that if the VBT was written into | ||
802 | * the OpRegion then they have validated the LVDS's existence. | ||
803 | */ | ||
804 | if (dev_priv->opregion.vbt) | ||
805 | return true; | ||
813 | } | 806 | } |
814 | return ret; | 807 | |
808 | return false; | ||
815 | } | 809 | } |
816 | 810 | ||
817 | /** | 811 | /** |
@@ -864,16 +858,20 @@ void intel_lvds_init(struct drm_device *dev) | |||
864 | return; | 858 | return; |
865 | } | 859 | } |
866 | 860 | ||
861 | if (!HAS_PCH_SPLIT(dev)) { | ||
862 | intel_lvds->pfit_control = I915_READ(PFIT_CONTROL); | ||
863 | } | ||
864 | |||
867 | intel_encoder = &intel_lvds->base; | 865 | intel_encoder = &intel_lvds->base; |
868 | encoder = &intel_encoder->enc; | 866 | encoder = &intel_encoder->base; |
869 | connector = &intel_connector->base; | 867 | connector = &intel_connector->base; |
870 | drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, | 868 | drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, |
871 | DRM_MODE_CONNECTOR_LVDS); | 869 | DRM_MODE_CONNECTOR_LVDS); |
872 | 870 | ||
873 | drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs, | 871 | drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs, |
874 | DRM_MODE_ENCODER_LVDS); | 872 | DRM_MODE_ENCODER_LVDS); |
875 | 873 | ||
876 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); | 874 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
877 | intel_encoder->type = INTEL_OUTPUT_LVDS; | 875 | intel_encoder->type = INTEL_OUTPUT_LVDS; |
878 | 876 | ||
879 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); | 877 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); |
@@ -904,43 +902,42 @@ void intel_lvds_init(struct drm_device *dev) | |||
904 | * if closed, act like it's not there for now | 902 | * if closed, act like it's not there for now |
905 | */ | 903 | */ |
906 | 904 | ||
907 | /* Set up the DDC bus. */ | ||
908 | intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C"); | ||
909 | if (!intel_encoder->ddc_bus) { | ||
910 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " | ||
911 | "failed.\n"); | ||
912 | goto failed; | ||
913 | } | ||
914 | |||
915 | /* | 905 | /* |
916 | * Attempt to get the fixed panel mode from DDC. Assume that the | 906 | * Attempt to get the fixed panel mode from DDC. Assume that the |
917 | * preferred mode is the right one. | 907 | * preferred mode is the right one. |
918 | */ | 908 | */ |
919 | dev_priv->lvds_edid_good = true; | 909 | intel_lvds->edid_good = true; |
920 | 910 | if (!intel_ddc_get_modes(connector, &dev_priv->gmbus[GMBUS_PORT_PANEL].adapter)) | |
921 | if (!intel_ddc_get_modes(connector, intel_encoder->ddc_bus)) | 911 | intel_lvds->edid_good = false; |
922 | dev_priv->lvds_edid_good = false; | 912 | |
913 | if (!intel_lvds->edid_good) { | ||
914 | /* Didn't get an EDID, so | ||
915 | * Set wide sync ranges so we get all modes | ||
916 | * handed to valid_mode for checking | ||
917 | */ | ||
918 | connector->display_info.min_vfreq = 0; | ||
919 | connector->display_info.max_vfreq = 200; | ||
920 | connector->display_info.min_hfreq = 0; | ||
921 | connector->display_info.max_hfreq = 200; | ||
922 | } | ||
923 | 923 | ||
924 | list_for_each_entry(scan, &connector->probed_modes, head) { | 924 | list_for_each_entry(scan, &connector->probed_modes, head) { |
925 | mutex_lock(&dev->mode_config.mutex); | ||
926 | if (scan->type & DRM_MODE_TYPE_PREFERRED) { | 925 | if (scan->type & DRM_MODE_TYPE_PREFERRED) { |
927 | dev_priv->panel_fixed_mode = | 926 | intel_lvds->fixed_mode = |
928 | drm_mode_duplicate(dev, scan); | 927 | drm_mode_duplicate(dev, scan); |
929 | mutex_unlock(&dev->mode_config.mutex); | 928 | intel_find_lvds_downclock(dev, |
930 | intel_find_lvds_downclock(dev, connector); | 929 | intel_lvds->fixed_mode, |
930 | connector); | ||
931 | goto out; | 931 | goto out; |
932 | } | 932 | } |
933 | mutex_unlock(&dev->mode_config.mutex); | ||
934 | } | 933 | } |
935 | 934 | ||
936 | /* Failed to get EDID, what about VBT? */ | 935 | /* Failed to get EDID, what about VBT? */ |
937 | if (dev_priv->lfp_lvds_vbt_mode) { | 936 | if (dev_priv->lfp_lvds_vbt_mode) { |
938 | mutex_lock(&dev->mode_config.mutex); | 937 | intel_lvds->fixed_mode = |
939 | dev_priv->panel_fixed_mode = | ||
940 | drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); | 938 | drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); |
941 | mutex_unlock(&dev->mode_config.mutex); | 939 | if (intel_lvds->fixed_mode) { |
942 | if (dev_priv->panel_fixed_mode) { | 940 | intel_lvds->fixed_mode->type |= |
943 | dev_priv->panel_fixed_mode->type |= | ||
944 | DRM_MODE_TYPE_PREFERRED; | 941 | DRM_MODE_TYPE_PREFERRED; |
945 | goto out; | 942 | goto out; |
946 | } | 943 | } |
@@ -958,19 +955,19 @@ void intel_lvds_init(struct drm_device *dev) | |||
958 | 955 | ||
959 | lvds = I915_READ(LVDS); | 956 | lvds = I915_READ(LVDS); |
960 | pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; | 957 | pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; |
961 | crtc = intel_get_crtc_from_pipe(dev, pipe); | 958 | crtc = intel_get_crtc_for_pipe(dev, pipe); |
962 | 959 | ||
963 | if (crtc && (lvds & LVDS_PORT_EN)) { | 960 | if (crtc && (lvds & LVDS_PORT_EN)) { |
964 | dev_priv->panel_fixed_mode = intel_crtc_mode_get(dev, crtc); | 961 | intel_lvds->fixed_mode = intel_crtc_mode_get(dev, crtc); |
965 | if (dev_priv->panel_fixed_mode) { | 962 | if (intel_lvds->fixed_mode) { |
966 | dev_priv->panel_fixed_mode->type |= | 963 | intel_lvds->fixed_mode->type |= |
967 | DRM_MODE_TYPE_PREFERRED; | 964 | DRM_MODE_TYPE_PREFERRED; |
968 | goto out; | 965 | goto out; |
969 | } | 966 | } |
970 | } | 967 | } |
971 | 968 | ||
972 | /* If we still don't have a mode after all that, give up. */ | 969 | /* If we still don't have a mode after all that, give up. */ |
973 | if (!dev_priv->panel_fixed_mode) | 970 | if (!intel_lvds->fixed_mode) |
974 | goto failed; | 971 | goto failed; |
975 | 972 | ||
976 | out: | 973 | out: |
@@ -997,8 +994,6 @@ out: | |||
997 | 994 | ||
998 | failed: | 995 | failed: |
999 | DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); | 996 | DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); |
1000 | if (intel_encoder->ddc_bus) | ||
1001 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
1002 | drm_connector_cleanup(connector); | 997 | drm_connector_cleanup(connector); |
1003 | drm_encoder_cleanup(encoder); | 998 | drm_encoder_cleanup(encoder); |
1004 | kfree(intel_lvds); | 999 | kfree(intel_lvds); |
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 4b1fd3d9c73c..f70b7cf32bff 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> | 2 | * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> |
3 | * Copyright (c) 2007 Intel Corporation | 3 | * Copyright (c) 2007, 2010 Intel Corporation |
4 | * Jesse Barnes <jesse.barnes@intel.com> | 4 | * Jesse Barnes <jesse.barnes@intel.com> |
5 | * | 5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a | 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
@@ -34,11 +34,11 @@ | |||
34 | * intel_ddc_probe | 34 | * intel_ddc_probe |
35 | * | 35 | * |
36 | */ | 36 | */ |
37 | bool intel_ddc_probe(struct intel_encoder *intel_encoder) | 37 | bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus) |
38 | { | 38 | { |
39 | struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private; | ||
39 | u8 out_buf[] = { 0x0, 0x0}; | 40 | u8 out_buf[] = { 0x0, 0x0}; |
40 | u8 buf[2]; | 41 | u8 buf[2]; |
41 | int ret; | ||
42 | struct i2c_msg msgs[] = { | 42 | struct i2c_msg msgs[] = { |
43 | { | 43 | { |
44 | .addr = 0x50, | 44 | .addr = 0x50, |
@@ -54,13 +54,7 @@ bool intel_ddc_probe(struct intel_encoder *intel_encoder) | |||
54 | } | 54 | } |
55 | }; | 55 | }; |
56 | 56 | ||
57 | intel_i2c_quirk_set(intel_encoder->enc.dev, true); | 57 | return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 2) == 2; |
58 | ret = i2c_transfer(intel_encoder->ddc_bus, msgs, 2); | ||
59 | intel_i2c_quirk_set(intel_encoder->enc.dev, false); | ||
60 | if (ret == 2) | ||
61 | return true; | ||
62 | |||
63 | return false; | ||
64 | } | 58 | } |
65 | 59 | ||
66 | /** | 60 | /** |
@@ -76,9 +70,7 @@ int intel_ddc_get_modes(struct drm_connector *connector, | |||
76 | struct edid *edid; | 70 | struct edid *edid; |
77 | int ret = 0; | 71 | int ret = 0; |
78 | 72 | ||
79 | intel_i2c_quirk_set(connector->dev, true); | ||
80 | edid = drm_get_edid(connector, adapter); | 73 | edid = drm_get_edid(connector, adapter); |
81 | intel_i2c_quirk_set(connector->dev, false); | ||
82 | if (edid) { | 74 | if (edid) { |
83 | drm_mode_connector_update_edid_property(connector, edid); | 75 | drm_mode_connector_update_edid_property(connector, edid); |
84 | ret = drm_add_edid_modes(connector, edid); | 76 | ret = drm_add_edid_modes(connector, edid); |
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index ea5d3fea4b61..917c7dc3cd6b 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
@@ -31,17 +31,16 @@ | |||
31 | #include "drmP.h" | 31 | #include "drmP.h" |
32 | #include "i915_drm.h" | 32 | #include "i915_drm.h" |
33 | #include "i915_drv.h" | 33 | #include "i915_drv.h" |
34 | #include "intel_drv.h" | ||
34 | 35 | ||
35 | #define PCI_ASLE 0xe4 | 36 | #define PCI_ASLE 0xe4 |
36 | #define PCI_LBPC 0xf4 | ||
37 | #define PCI_ASLS 0xfc | 37 | #define PCI_ASLS 0xfc |
38 | 38 | ||
39 | #define OPREGION_SZ (8*1024) | ||
40 | #define OPREGION_HEADER_OFFSET 0 | 39 | #define OPREGION_HEADER_OFFSET 0 |
41 | #define OPREGION_ACPI_OFFSET 0x100 | 40 | #define OPREGION_ACPI_OFFSET 0x100 |
42 | #define OPREGION_SWSCI_OFFSET 0x200 | 41 | #define OPREGION_SWSCI_OFFSET 0x200 |
43 | #define OPREGION_ASLE_OFFSET 0x300 | 42 | #define OPREGION_ASLE_OFFSET 0x300 |
44 | #define OPREGION_VBT_OFFSET 0x1000 | 43 | #define OPREGION_VBT_OFFSET 0x400 |
45 | 44 | ||
46 | #define OPREGION_SIGNATURE "IntelGraphicsMem" | 45 | #define OPREGION_SIGNATURE "IntelGraphicsMem" |
47 | #define MBOX_ACPI (1<<0) | 46 | #define MBOX_ACPI (1<<0) |
@@ -143,40 +142,22 @@ struct opregion_asle { | |||
143 | #define ACPI_DIGITAL_OUTPUT (3<<8) | 142 | #define ACPI_DIGITAL_OUTPUT (3<<8) |
144 | #define ACPI_LVDS_OUTPUT (4<<8) | 143 | #define ACPI_LVDS_OUTPUT (4<<8) |
145 | 144 | ||
145 | #ifdef CONFIG_ACPI | ||
146 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | 146 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) |
147 | { | 147 | { |
148 | struct drm_i915_private *dev_priv = dev->dev_private; | 148 | struct drm_i915_private *dev_priv = dev->dev_private; |
149 | struct opregion_asle *asle = dev_priv->opregion.asle; | 149 | struct opregion_asle *asle = dev_priv->opregion.asle; |
150 | u32 blc_pwm_ctl, blc_pwm_ctl2; | 150 | u32 max; |
151 | u32 max_backlight, level, shift; | ||
152 | 151 | ||
153 | if (!(bclp & ASLE_BCLP_VALID)) | 152 | if (!(bclp & ASLE_BCLP_VALID)) |
154 | return ASLE_BACKLIGHT_FAILED; | 153 | return ASLE_BACKLIGHT_FAILED; |
155 | 154 | ||
156 | bclp &= ASLE_BCLP_MSK; | 155 | bclp &= ASLE_BCLP_MSK; |
157 | if (bclp < 0 || bclp > 255) | 156 | if (bclp > 255) |
158 | return ASLE_BACKLIGHT_FAILED; | 157 | return ASLE_BACKLIGHT_FAILED; |
159 | 158 | ||
160 | blc_pwm_ctl = I915_READ(BLC_PWM_CTL); | 159 | max = intel_panel_get_max_backlight(dev); |
161 | blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); | 160 | intel_panel_set_backlight(dev, bclp * max / 255); |
162 | |||
163 | if (IS_I965G(dev) && (blc_pwm_ctl2 & BLM_COMBINATION_MODE)) | ||
164 | pci_write_config_dword(dev->pdev, PCI_LBPC, bclp); | ||
165 | else { | ||
166 | if (IS_PINEVIEW(dev)) { | ||
167 | blc_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1); | ||
168 | max_backlight = (blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> | ||
169 | BACKLIGHT_MODULATION_FREQ_SHIFT; | ||
170 | shift = BACKLIGHT_DUTY_CYCLE_SHIFT + 1; | ||
171 | } else { | ||
172 | blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; | ||
173 | max_backlight = ((blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> | ||
174 | BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; | ||
175 | shift = BACKLIGHT_DUTY_CYCLE_SHIFT; | ||
176 | } | ||
177 | level = (bclp * max_backlight) / 255; | ||
178 | I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | (level << shift)); | ||
179 | } | ||
180 | asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID; | 161 | asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID; |
181 | 162 | ||
182 | return 0; | 163 | return 0; |
@@ -211,7 +192,7 @@ static u32 asle_set_pfit(struct drm_device *dev, u32 pfit) | |||
211 | return 0; | 192 | return 0; |
212 | } | 193 | } |
213 | 194 | ||
214 | void opregion_asle_intr(struct drm_device *dev) | 195 | void intel_opregion_asle_intr(struct drm_device *dev) |
215 | { | 196 | { |
216 | struct drm_i915_private *dev_priv = dev->dev_private; | 197 | struct drm_i915_private *dev_priv = dev->dev_private; |
217 | struct opregion_asle *asle = dev_priv->opregion.asle; | 198 | struct opregion_asle *asle = dev_priv->opregion.asle; |
@@ -243,37 +224,8 @@ void opregion_asle_intr(struct drm_device *dev) | |||
243 | asle->aslc = asle_stat; | 224 | asle->aslc = asle_stat; |
244 | } | 225 | } |
245 | 226 | ||
246 | static u32 asle_set_backlight_ironlake(struct drm_device *dev, u32 bclp) | 227 | /* Only present on Ironlake+ */ |
247 | { | 228 | void intel_opregion_gse_intr(struct drm_device *dev) |
248 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
249 | struct opregion_asle *asle = dev_priv->opregion.asle; | ||
250 | u32 cpu_pwm_ctl, pch_pwm_ctl2; | ||
251 | u32 max_backlight, level; | ||
252 | |||
253 | if (!(bclp & ASLE_BCLP_VALID)) | ||
254 | return ASLE_BACKLIGHT_FAILED; | ||
255 | |||
256 | bclp &= ASLE_BCLP_MSK; | ||
257 | if (bclp < 0 || bclp > 255) | ||
258 | return ASLE_BACKLIGHT_FAILED; | ||
259 | |||
260 | cpu_pwm_ctl = I915_READ(BLC_PWM_CPU_CTL); | ||
261 | pch_pwm_ctl2 = I915_READ(BLC_PWM_PCH_CTL2); | ||
262 | /* get the max PWM frequency */ | ||
263 | max_backlight = (pch_pwm_ctl2 >> 16) & BACKLIGHT_DUTY_CYCLE_MASK; | ||
264 | /* calculate the expected PMW frequency */ | ||
265 | level = (bclp * max_backlight) / 255; | ||
266 | /* reserve the high 16 bits */ | ||
267 | cpu_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK); | ||
268 | /* write the updated PWM frequency */ | ||
269 | I915_WRITE(BLC_PWM_CPU_CTL, cpu_pwm_ctl | level); | ||
270 | |||
271 | asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID; | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | void ironlake_opregion_gse_intr(struct drm_device *dev) | ||
277 | { | 229 | { |
278 | struct drm_i915_private *dev_priv = dev->dev_private; | 230 | struct drm_i915_private *dev_priv = dev->dev_private; |
279 | struct opregion_asle *asle = dev_priv->opregion.asle; | 231 | struct opregion_asle *asle = dev_priv->opregion.asle; |
@@ -296,7 +248,7 @@ void ironlake_opregion_gse_intr(struct drm_device *dev) | |||
296 | } | 248 | } |
297 | 249 | ||
298 | if (asle_req & ASLE_SET_BACKLIGHT) | 250 | if (asle_req & ASLE_SET_BACKLIGHT) |
299 | asle_stat |= asle_set_backlight_ironlake(dev, asle->bclp); | 251 | asle_stat |= asle_set_backlight(dev, asle->bclp); |
300 | 252 | ||
301 | if (asle_req & ASLE_SET_PFIT) { | 253 | if (asle_req & ASLE_SET_PFIT) { |
302 | DRM_DEBUG_DRIVER("Pfit is not supported\n"); | 254 | DRM_DEBUG_DRIVER("Pfit is not supported\n"); |
@@ -315,7 +267,7 @@ void ironlake_opregion_gse_intr(struct drm_device *dev) | |||
315 | #define ASLE_PFIT_EN (1<<2) | 267 | #define ASLE_PFIT_EN (1<<2) |
316 | #define ASLE_PFMB_EN (1<<3) | 268 | #define ASLE_PFMB_EN (1<<3) |
317 | 269 | ||
318 | void opregion_enable_asle(struct drm_device *dev) | 270 | void intel_opregion_enable_asle(struct drm_device *dev) |
319 | { | 271 | { |
320 | struct drm_i915_private *dev_priv = dev->dev_private; | 272 | struct drm_i915_private *dev_priv = dev->dev_private; |
321 | struct opregion_asle *asle = dev_priv->opregion.asle; | 273 | struct opregion_asle *asle = dev_priv->opregion.asle; |
@@ -464,7 +416,58 @@ blind_set: | |||
464 | goto end; | 416 | goto end; |
465 | } | 417 | } |
466 | 418 | ||
467 | int intel_opregion_init(struct drm_device *dev, int resume) | 419 | void intel_opregion_init(struct drm_device *dev) |
420 | { | ||
421 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
422 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
423 | |||
424 | if (!opregion->header) | ||
425 | return; | ||
426 | |||
427 | if (opregion->acpi) { | ||
428 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
429 | intel_didl_outputs(dev); | ||
430 | |||
431 | /* Notify BIOS we are ready to handle ACPI video ext notifs. | ||
432 | * Right now, all the events are handled by the ACPI video module. | ||
433 | * We don't actually need to do anything with them. */ | ||
434 | opregion->acpi->csts = 0; | ||
435 | opregion->acpi->drdy = 1; | ||
436 | |||
437 | system_opregion = opregion; | ||
438 | register_acpi_notifier(&intel_opregion_notifier); | ||
439 | } | ||
440 | |||
441 | if (opregion->asle) | ||
442 | intel_opregion_enable_asle(dev); | ||
443 | } | ||
444 | |||
445 | void intel_opregion_fini(struct drm_device *dev) | ||
446 | { | ||
447 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
448 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
449 | |||
450 | if (!opregion->header) | ||
451 | return; | ||
452 | |||
453 | if (opregion->acpi) { | ||
454 | opregion->acpi->drdy = 0; | ||
455 | |||
456 | system_opregion = NULL; | ||
457 | unregister_acpi_notifier(&intel_opregion_notifier); | ||
458 | } | ||
459 | |||
460 | /* just clear all opregion memory pointers now */ | ||
461 | iounmap(opregion->header); | ||
462 | opregion->header = NULL; | ||
463 | opregion->acpi = NULL; | ||
464 | opregion->swsci = NULL; | ||
465 | opregion->asle = NULL; | ||
466 | opregion->vbt = NULL; | ||
467 | } | ||
468 | #endif | ||
469 | |||
470 | int intel_opregion_setup(struct drm_device *dev) | ||
468 | { | 471 | { |
469 | struct drm_i915_private *dev_priv = dev->dev_private; | 472 | struct drm_i915_private *dev_priv = dev->dev_private; |
470 | struct intel_opregion *opregion = &dev_priv->opregion; | 473 | struct intel_opregion *opregion = &dev_priv->opregion; |
@@ -479,29 +482,23 @@ int intel_opregion_init(struct drm_device *dev, int resume) | |||
479 | return -ENOTSUPP; | 482 | return -ENOTSUPP; |
480 | } | 483 | } |
481 | 484 | ||
482 | base = ioremap(asls, OPREGION_SZ); | 485 | base = ioremap(asls, OPREGION_SIZE); |
483 | if (!base) | 486 | if (!base) |
484 | return -ENOMEM; | 487 | return -ENOMEM; |
485 | 488 | ||
486 | opregion->header = base; | 489 | if (memcmp(base, OPREGION_SIGNATURE, 16)) { |
487 | if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) { | ||
488 | DRM_DEBUG_DRIVER("opregion signature mismatch\n"); | 490 | DRM_DEBUG_DRIVER("opregion signature mismatch\n"); |
489 | err = -EINVAL; | 491 | err = -EINVAL; |
490 | goto err_out; | 492 | goto err_out; |
491 | } | 493 | } |
494 | opregion->header = base; | ||
495 | opregion->vbt = base + OPREGION_VBT_OFFSET; | ||
492 | 496 | ||
493 | mboxes = opregion->header->mboxes; | 497 | mboxes = opregion->header->mboxes; |
494 | if (mboxes & MBOX_ACPI) { | 498 | if (mboxes & MBOX_ACPI) { |
495 | DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); | 499 | DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); |
496 | opregion->acpi = base + OPREGION_ACPI_OFFSET; | 500 | opregion->acpi = base + OPREGION_ACPI_OFFSET; |
497 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
498 | intel_didl_outputs(dev); | ||
499 | } else { | ||
500 | DRM_DEBUG_DRIVER("Public ACPI methods not supported\n"); | ||
501 | err = -ENOTSUPP; | ||
502 | goto err_out; | ||
503 | } | 501 | } |
504 | opregion->enabled = 1; | ||
505 | 502 | ||
506 | if (mboxes & MBOX_SWSCI) { | 503 | if (mboxes & MBOX_SWSCI) { |
507 | DRM_DEBUG_DRIVER("SWSCI supported\n"); | 504 | DRM_DEBUG_DRIVER("SWSCI supported\n"); |
@@ -510,53 +507,11 @@ int intel_opregion_init(struct drm_device *dev, int resume) | |||
510 | if (mboxes & MBOX_ASLE) { | 507 | if (mboxes & MBOX_ASLE) { |
511 | DRM_DEBUG_DRIVER("ASLE supported\n"); | 508 | DRM_DEBUG_DRIVER("ASLE supported\n"); |
512 | opregion->asle = base + OPREGION_ASLE_OFFSET; | 509 | opregion->asle = base + OPREGION_ASLE_OFFSET; |
513 | opregion_enable_asle(dev); | ||
514 | } | 510 | } |
515 | 511 | ||
516 | if (!resume) | ||
517 | acpi_video_register(); | ||
518 | |||
519 | |||
520 | /* Notify BIOS we are ready to handle ACPI video ext notifs. | ||
521 | * Right now, all the events are handled by the ACPI video module. | ||
522 | * We don't actually need to do anything with them. */ | ||
523 | opregion->acpi->csts = 0; | ||
524 | opregion->acpi->drdy = 1; | ||
525 | |||
526 | system_opregion = opregion; | ||
527 | register_acpi_notifier(&intel_opregion_notifier); | ||
528 | |||
529 | return 0; | 512 | return 0; |
530 | 513 | ||
531 | err_out: | 514 | err_out: |
532 | iounmap(opregion->header); | 515 | iounmap(opregion->header); |
533 | opregion->header = NULL; | ||
534 | acpi_video_register(); | ||
535 | return err; | 516 | return err; |
536 | } | 517 | } |
537 | |||
538 | void intel_opregion_free(struct drm_device *dev, int suspend) | ||
539 | { | ||
540 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
541 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
542 | |||
543 | if (!opregion->enabled) | ||
544 | return; | ||
545 | |||
546 | if (!suspend) | ||
547 | acpi_video_unregister(); | ||
548 | |||
549 | opregion->acpi->drdy = 0; | ||
550 | |||
551 | system_opregion = NULL; | ||
552 | unregister_acpi_notifier(&intel_opregion_notifier); | ||
553 | |||
554 | /* just clear all opregion memory pointers now */ | ||
555 | iounmap(opregion->header); | ||
556 | opregion->header = NULL; | ||
557 | opregion->acpi = NULL; | ||
558 | opregion->swsci = NULL; | ||
559 | opregion->asle = NULL; | ||
560 | |||
561 | opregion->enabled = 0; | ||
562 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 1d306a458be6..c4699c916698 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -170,57 +170,143 @@ struct overlay_registers { | |||
170 | u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES]; | 170 | u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES]; |
171 | }; | 171 | }; |
172 | 172 | ||
173 | /* overlay flip addr flag */ | 173 | struct intel_overlay { |
174 | #define OFC_UPDATE 0x1 | 174 | struct drm_device *dev; |
175 | 175 | struct intel_crtc *crtc; | |
176 | #define OVERLAY_NONPHYSICAL(dev) (IS_G33(dev) || IS_I965G(dev)) | 176 | struct drm_i915_gem_object *vid_bo; |
177 | #define OVERLAY_EXISTS(dev) (!IS_G4X(dev) && !IS_IRONLAKE(dev) && !IS_GEN6(dev)) | 177 | struct drm_i915_gem_object *old_vid_bo; |
178 | 178 | int active; | |
179 | int pfit_active; | ||
180 | u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */ | ||
181 | u32 color_key; | ||
182 | u32 brightness, contrast, saturation; | ||
183 | u32 old_xscale, old_yscale; | ||
184 | /* register access */ | ||
185 | u32 flip_addr; | ||
186 | struct drm_i915_gem_object *reg_bo; | ||
187 | /* flip handling */ | ||
188 | uint32_t last_flip_req; | ||
189 | void (*flip_tail)(struct intel_overlay *); | ||
190 | }; | ||
179 | 191 | ||
180 | static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_overlay *overlay) | 192 | static struct overlay_registers * |
193 | intel_overlay_map_regs(struct intel_overlay *overlay) | ||
181 | { | 194 | { |
182 | drm_i915_private_t *dev_priv = overlay->dev->dev_private; | 195 | drm_i915_private_t *dev_priv = overlay->dev->dev_private; |
183 | struct overlay_registers *regs; | 196 | struct overlay_registers *regs; |
184 | 197 | ||
185 | /* no recursive mappings */ | 198 | if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) |
186 | BUG_ON(overlay->virt_addr); | 199 | regs = overlay->reg_bo->phys_obj->handle->vaddr; |
200 | else | ||
201 | regs = io_mapping_map_wc(dev_priv->mm.gtt_mapping, | ||
202 | overlay->reg_bo->gtt_offset); | ||
187 | 203 | ||
188 | if (OVERLAY_NONPHYSICAL(overlay->dev)) { | 204 | return regs; |
189 | regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, | 205 | } |
190 | overlay->reg_bo->gtt_offset, | ||
191 | KM_USER0); | ||
192 | 206 | ||
193 | if (!regs) { | 207 | static void intel_overlay_unmap_regs(struct intel_overlay *overlay, |
194 | DRM_ERROR("failed to map overlay regs in GTT\n"); | 208 | struct overlay_registers *regs) |
195 | return NULL; | 209 | { |
196 | } | 210 | if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev)) |
197 | } else | 211 | io_mapping_unmap(regs); |
198 | regs = overlay->reg_bo->phys_obj->handle->vaddr; | 212 | } |
199 | 213 | ||
200 | return overlay->virt_addr = regs; | 214 | static int intel_overlay_do_wait_request(struct intel_overlay *overlay, |
215 | struct drm_i915_gem_request *request, | ||
216 | bool interruptible, | ||
217 | void (*tail)(struct intel_overlay *)) | ||
218 | { | ||
219 | struct drm_device *dev = overlay->dev; | ||
220 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
221 | int ret; | ||
222 | |||
223 | BUG_ON(overlay->last_flip_req); | ||
224 | overlay->last_flip_req = | ||
225 | i915_add_request(dev, NULL, request, &dev_priv->render_ring); | ||
226 | if (overlay->last_flip_req == 0) | ||
227 | return -ENOMEM; | ||
228 | |||
229 | overlay->flip_tail = tail; | ||
230 | ret = i915_do_wait_request(dev, | ||
231 | overlay->last_flip_req, true, | ||
232 | &dev_priv->render_ring); | ||
233 | if (ret) | ||
234 | return ret; | ||
235 | |||
236 | overlay->last_flip_req = 0; | ||
237 | return 0; | ||
201 | } | 238 | } |
202 | 239 | ||
203 | static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay) | 240 | /* Workaround for i830 bug where pipe a must be enable to change control regs */ |
241 | static int | ||
242 | i830_activate_pipe_a(struct drm_device *dev) | ||
204 | { | 243 | { |
205 | if (OVERLAY_NONPHYSICAL(overlay->dev)) | 244 | drm_i915_private_t *dev_priv = dev->dev_private; |
206 | io_mapping_unmap_atomic(overlay->virt_addr, KM_USER0); | 245 | struct intel_crtc *crtc; |
246 | struct drm_crtc_helper_funcs *crtc_funcs; | ||
247 | struct drm_display_mode vesa_640x480 = { | ||
248 | DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, | ||
249 | 752, 800, 0, 480, 489, 492, 525, 0, | ||
250 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) | ||
251 | }, *mode; | ||
252 | |||
253 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[0]); | ||
254 | if (crtc->dpms_mode == DRM_MODE_DPMS_ON) | ||
255 | return 0; | ||
207 | 256 | ||
208 | overlay->virt_addr = NULL; | 257 | /* most i8xx have pipe a forced on, so don't trust dpms mode */ |
258 | if (I915_READ(PIPEACONF) & PIPECONF_ENABLE) | ||
259 | return 0; | ||
209 | 260 | ||
210 | return; | 261 | crtc_funcs = crtc->base.helper_private; |
262 | if (crtc_funcs->dpms == NULL) | ||
263 | return 0; | ||
264 | |||
265 | DRM_DEBUG_DRIVER("Enabling pipe A in order to enable overlay\n"); | ||
266 | |||
267 | mode = drm_mode_duplicate(dev, &vesa_640x480); | ||
268 | drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); | ||
269 | if(!drm_crtc_helper_set_mode(&crtc->base, mode, | ||
270 | crtc->base.x, crtc->base.y, | ||
271 | crtc->base.fb)) | ||
272 | return 0; | ||
273 | |||
274 | crtc_funcs->dpms(&crtc->base, DRM_MODE_DPMS_ON); | ||
275 | return 1; | ||
276 | } | ||
277 | |||
278 | static void | ||
279 | i830_deactivate_pipe_a(struct drm_device *dev) | ||
280 | { | ||
281 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
282 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0]; | ||
283 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | ||
284 | |||
285 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); | ||
211 | } | 286 | } |
212 | 287 | ||
213 | /* overlay needs to be disable in OCMD reg */ | 288 | /* overlay needs to be disable in OCMD reg */ |
214 | static int intel_overlay_on(struct intel_overlay *overlay) | 289 | static int intel_overlay_on(struct intel_overlay *overlay) |
215 | { | 290 | { |
216 | struct drm_device *dev = overlay->dev; | 291 | struct drm_device *dev = overlay->dev; |
292 | struct drm_i915_gem_request *request; | ||
293 | int pipe_a_quirk = 0; | ||
217 | int ret; | 294 | int ret; |
218 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
219 | 295 | ||
220 | BUG_ON(overlay->active); | 296 | BUG_ON(overlay->active); |
221 | |||
222 | overlay->active = 1; | 297 | overlay->active = 1; |
223 | overlay->hw_wedged = NEEDS_WAIT_FOR_FLIP; | 298 | |
299 | if (IS_I830(dev)) { | ||
300 | pipe_a_quirk = i830_activate_pipe_a(dev); | ||
301 | if (pipe_a_quirk < 0) | ||
302 | return pipe_a_quirk; | ||
303 | } | ||
304 | |||
305 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
306 | if (request == NULL) { | ||
307 | ret = -ENOMEM; | ||
308 | goto out; | ||
309 | } | ||
224 | 310 | ||
225 | BEGIN_LP_RING(4); | 311 | BEGIN_LP_RING(4); |
226 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON); | 312 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON); |
@@ -229,32 +315,30 @@ static int intel_overlay_on(struct intel_overlay *overlay) | |||
229 | OUT_RING(MI_NOOP); | 315 | OUT_RING(MI_NOOP); |
230 | ADVANCE_LP_RING(); | 316 | ADVANCE_LP_RING(); |
231 | 317 | ||
232 | overlay->last_flip_req = | 318 | ret = intel_overlay_do_wait_request(overlay, request, true, NULL); |
233 | i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | 319 | out: |
234 | if (overlay->last_flip_req == 0) | 320 | if (pipe_a_quirk) |
235 | return -ENOMEM; | 321 | i830_deactivate_pipe_a(dev); |
236 | |||
237 | ret = i915_do_wait_request(dev, | ||
238 | overlay->last_flip_req, 1, &dev_priv->render_ring); | ||
239 | if (ret != 0) | ||
240 | return ret; | ||
241 | 322 | ||
242 | overlay->hw_wedged = 0; | 323 | return ret; |
243 | overlay->last_flip_req = 0; | ||
244 | return 0; | ||
245 | } | 324 | } |
246 | 325 | ||
247 | /* overlay needs to be enabled in OCMD reg */ | 326 | /* overlay needs to be enabled in OCMD reg */ |
248 | static void intel_overlay_continue(struct intel_overlay *overlay, | 327 | static int intel_overlay_continue(struct intel_overlay *overlay, |
249 | bool load_polyphase_filter) | 328 | bool load_polyphase_filter) |
250 | { | 329 | { |
251 | struct drm_device *dev = overlay->dev; | 330 | struct drm_device *dev = overlay->dev; |
252 | drm_i915_private_t *dev_priv = dev->dev_private; | 331 | drm_i915_private_t *dev_priv = dev->dev_private; |
332 | struct drm_i915_gem_request *request; | ||
253 | u32 flip_addr = overlay->flip_addr; | 333 | u32 flip_addr = overlay->flip_addr; |
254 | u32 tmp; | 334 | u32 tmp; |
255 | 335 | ||
256 | BUG_ON(!overlay->active); | 336 | BUG_ON(!overlay->active); |
257 | 337 | ||
338 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
339 | if (request == NULL) | ||
340 | return -ENOMEM; | ||
341 | |||
258 | if (load_polyphase_filter) | 342 | if (load_polyphase_filter) |
259 | flip_addr |= OFC_UPDATE; | 343 | flip_addr |= OFC_UPDATE; |
260 | 344 | ||
@@ -269,220 +353,132 @@ static void intel_overlay_continue(struct intel_overlay *overlay, | |||
269 | ADVANCE_LP_RING(); | 353 | ADVANCE_LP_RING(); |
270 | 354 | ||
271 | overlay->last_flip_req = | 355 | overlay->last_flip_req = |
272 | i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | 356 | i915_add_request(dev, NULL, request, &dev_priv->render_ring); |
357 | return 0; | ||
273 | } | 358 | } |
274 | 359 | ||
275 | static int intel_overlay_wait_flip(struct intel_overlay *overlay) | 360 | static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) |
276 | { | 361 | { |
277 | struct drm_device *dev = overlay->dev; | 362 | struct drm_gem_object *obj = &overlay->old_vid_bo->base; |
278 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
279 | int ret; | ||
280 | u32 tmp; | ||
281 | |||
282 | if (overlay->last_flip_req != 0) { | ||
283 | ret = i915_do_wait_request(dev, overlay->last_flip_req, | ||
284 | 1, &dev_priv->render_ring); | ||
285 | if (ret == 0) { | ||
286 | overlay->last_flip_req = 0; | ||
287 | |||
288 | tmp = I915_READ(ISR); | ||
289 | 363 | ||
290 | if (!(tmp & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT)) | 364 | i915_gem_object_unpin(obj); |
291 | return 0; | 365 | drm_gem_object_unreference(obj); |
292 | } | ||
293 | } | ||
294 | 366 | ||
295 | /* synchronous slowpath */ | 367 | overlay->old_vid_bo = NULL; |
296 | overlay->hw_wedged = RELEASE_OLD_VID; | 368 | } |
297 | 369 | ||
298 | BEGIN_LP_RING(2); | 370 | static void intel_overlay_off_tail(struct intel_overlay *overlay) |
299 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 371 | { |
300 | OUT_RING(MI_NOOP); | 372 | struct drm_gem_object *obj; |
301 | ADVANCE_LP_RING(); | ||
302 | 373 | ||
303 | overlay->last_flip_req = | 374 | /* never have the overlay hw on without showing a frame */ |
304 | i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | 375 | BUG_ON(!overlay->vid_bo); |
305 | if (overlay->last_flip_req == 0) | 376 | obj = &overlay->vid_bo->base; |
306 | return -ENOMEM; | ||
307 | 377 | ||
308 | ret = i915_do_wait_request(dev, overlay->last_flip_req, | 378 | i915_gem_object_unpin(obj); |
309 | 1, &dev_priv->render_ring); | 379 | drm_gem_object_unreference(obj); |
310 | if (ret != 0) | 380 | overlay->vid_bo = NULL; |
311 | return ret; | ||
312 | 381 | ||
313 | overlay->hw_wedged = 0; | 382 | overlay->crtc->overlay = NULL; |
314 | overlay->last_flip_req = 0; | 383 | overlay->crtc = NULL; |
315 | return 0; | 384 | overlay->active = 0; |
316 | } | 385 | } |
317 | 386 | ||
318 | /* overlay needs to be disabled in OCMD reg */ | 387 | /* overlay needs to be disabled in OCMD reg */ |
319 | static int intel_overlay_off(struct intel_overlay *overlay) | 388 | static int intel_overlay_off(struct intel_overlay *overlay, |
389 | bool interruptible) | ||
320 | { | 390 | { |
321 | u32 flip_addr = overlay->flip_addr; | ||
322 | struct drm_device *dev = overlay->dev; | 391 | struct drm_device *dev = overlay->dev; |
323 | drm_i915_private_t *dev_priv = dev->dev_private; | 392 | u32 flip_addr = overlay->flip_addr; |
324 | int ret; | 393 | struct drm_i915_gem_request *request; |
325 | 394 | ||
326 | BUG_ON(!overlay->active); | 395 | BUG_ON(!overlay->active); |
327 | 396 | ||
397 | request = kzalloc(sizeof(*request), GFP_KERNEL); | ||
398 | if (request == NULL) | ||
399 | return -ENOMEM; | ||
400 | |||
328 | /* According to intel docs the overlay hw may hang (when switching | 401 | /* According to intel docs the overlay hw may hang (when switching |
329 | * off) without loading the filter coeffs. It is however unclear whether | 402 | * off) without loading the filter coeffs. It is however unclear whether |
330 | * this applies to the disabling of the overlay or to the switching off | 403 | * this applies to the disabling of the overlay or to the switching off |
331 | * of the hw. Do it in both cases */ | 404 | * of the hw. Do it in both cases */ |
332 | flip_addr |= OFC_UPDATE; | 405 | flip_addr |= OFC_UPDATE; |
333 | 406 | ||
407 | BEGIN_LP_RING(6); | ||
334 | /* wait for overlay to go idle */ | 408 | /* wait for overlay to go idle */ |
335 | overlay->hw_wedged = SWITCH_OFF_STAGE_1; | ||
336 | |||
337 | BEGIN_LP_RING(4); | ||
338 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); | 409 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); |
339 | OUT_RING(flip_addr); | 410 | OUT_RING(flip_addr); |
340 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 411 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
341 | OUT_RING(MI_NOOP); | ||
342 | ADVANCE_LP_RING(); | ||
343 | |||
344 | overlay->last_flip_req = | ||
345 | i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | ||
346 | if (overlay->last_flip_req == 0) | ||
347 | return -ENOMEM; | ||
348 | |||
349 | ret = i915_do_wait_request(dev, overlay->last_flip_req, | ||
350 | 1, &dev_priv->render_ring); | ||
351 | if (ret != 0) | ||
352 | return ret; | ||
353 | |||
354 | /* turn overlay off */ | 412 | /* turn overlay off */ |
355 | overlay->hw_wedged = SWITCH_OFF_STAGE_2; | 413 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF); |
356 | |||
357 | BEGIN_LP_RING(4); | ||
358 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF); | ||
359 | OUT_RING(flip_addr); | 414 | OUT_RING(flip_addr); |
360 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | 415 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
361 | OUT_RING(MI_NOOP); | ||
362 | ADVANCE_LP_RING(); | 416 | ADVANCE_LP_RING(); |
363 | 417 | ||
364 | overlay->last_flip_req = | 418 | return intel_overlay_do_wait_request(overlay, request, interruptible, |
365 | i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | 419 | intel_overlay_off_tail); |
366 | if (overlay->last_flip_req == 0) | ||
367 | return -ENOMEM; | ||
368 | |||
369 | ret = i915_do_wait_request(dev, overlay->last_flip_req, | ||
370 | 1, &dev_priv->render_ring); | ||
371 | if (ret != 0) | ||
372 | return ret; | ||
373 | |||
374 | overlay->hw_wedged = 0; | ||
375 | overlay->last_flip_req = 0; | ||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | static void intel_overlay_off_tail(struct intel_overlay *overlay) | ||
380 | { | ||
381 | struct drm_gem_object *obj; | ||
382 | |||
383 | /* never have the overlay hw on without showing a frame */ | ||
384 | BUG_ON(!overlay->vid_bo); | ||
385 | obj = &overlay->vid_bo->base; | ||
386 | |||
387 | i915_gem_object_unpin(obj); | ||
388 | drm_gem_object_unreference(obj); | ||
389 | overlay->vid_bo = NULL; | ||
390 | |||
391 | overlay->crtc->overlay = NULL; | ||
392 | overlay->crtc = NULL; | ||
393 | overlay->active = 0; | ||
394 | } | 420 | } |
395 | 421 | ||
396 | /* recover from an interruption due to a signal | 422 | /* recover from an interruption due to a signal |
397 | * We have to be careful not to repeat work forever an make forward progess. */ | 423 | * We have to be careful not to repeat work forever an make forward progess. */ |
398 | int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, | 424 | static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, |
399 | int interruptible) | 425 | bool interruptible) |
400 | { | 426 | { |
401 | struct drm_device *dev = overlay->dev; | 427 | struct drm_device *dev = overlay->dev; |
402 | struct drm_gem_object *obj; | ||
403 | drm_i915_private_t *dev_priv = dev->dev_private; | 428 | drm_i915_private_t *dev_priv = dev->dev_private; |
404 | u32 flip_addr; | ||
405 | int ret; | 429 | int ret; |
406 | 430 | ||
407 | if (overlay->hw_wedged == HW_WEDGED) | 431 | if (overlay->last_flip_req == 0) |
408 | return -EIO; | 432 | return 0; |
409 | |||
410 | if (overlay->last_flip_req == 0) { | ||
411 | overlay->last_flip_req = | ||
412 | i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | ||
413 | if (overlay->last_flip_req == 0) | ||
414 | return -ENOMEM; | ||
415 | } | ||
416 | 433 | ||
417 | ret = i915_do_wait_request(dev, overlay->last_flip_req, | 434 | ret = i915_do_wait_request(dev, overlay->last_flip_req, |
418 | interruptible, &dev_priv->render_ring); | 435 | interruptible, &dev_priv->render_ring); |
419 | if (ret != 0) | 436 | if (ret) |
420 | return ret; | 437 | return ret; |
421 | 438 | ||
422 | switch (overlay->hw_wedged) { | 439 | if (overlay->flip_tail) |
423 | case RELEASE_OLD_VID: | 440 | overlay->flip_tail(overlay); |
424 | obj = &overlay->old_vid_bo->base; | ||
425 | i915_gem_object_unpin(obj); | ||
426 | drm_gem_object_unreference(obj); | ||
427 | overlay->old_vid_bo = NULL; | ||
428 | break; | ||
429 | case SWITCH_OFF_STAGE_1: | ||
430 | flip_addr = overlay->flip_addr; | ||
431 | flip_addr |= OFC_UPDATE; | ||
432 | |||
433 | overlay->hw_wedged = SWITCH_OFF_STAGE_2; | ||
434 | |||
435 | BEGIN_LP_RING(4); | ||
436 | OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF); | ||
437 | OUT_RING(flip_addr); | ||
438 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | ||
439 | OUT_RING(MI_NOOP); | ||
440 | ADVANCE_LP_RING(); | ||
441 | |||
442 | overlay->last_flip_req = i915_add_request(dev, NULL, | ||
443 | 0, &dev_priv->render_ring); | ||
444 | if (overlay->last_flip_req == 0) | ||
445 | return -ENOMEM; | ||
446 | |||
447 | ret = i915_do_wait_request(dev, overlay->last_flip_req, | ||
448 | interruptible, &dev_priv->render_ring); | ||
449 | if (ret != 0) | ||
450 | return ret; | ||
451 | |||
452 | case SWITCH_OFF_STAGE_2: | ||
453 | intel_overlay_off_tail(overlay); | ||
454 | break; | ||
455 | default: | ||
456 | BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP); | ||
457 | } | ||
458 | 441 | ||
459 | overlay->hw_wedged = 0; | ||
460 | overlay->last_flip_req = 0; | 442 | overlay->last_flip_req = 0; |
461 | return 0; | 443 | return 0; |
462 | } | 444 | } |
463 | 445 | ||
464 | /* Wait for pending overlay flip and release old frame. | 446 | /* Wait for pending overlay flip and release old frame. |
465 | * Needs to be called before the overlay register are changed | 447 | * Needs to be called before the overlay register are changed |
466 | * via intel_overlay_(un)map_regs_atomic */ | 448 | * via intel_overlay_(un)map_regs |
449 | */ | ||
467 | static int intel_overlay_release_old_vid(struct intel_overlay *overlay) | 450 | static int intel_overlay_release_old_vid(struct intel_overlay *overlay) |
468 | { | 451 | { |
452 | struct drm_device *dev = overlay->dev; | ||
453 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
469 | int ret; | 454 | int ret; |
470 | struct drm_gem_object *obj; | ||
471 | 455 | ||
472 | /* only wait if there is actually an old frame to release to | 456 | /* Only wait if there is actually an old frame to release to |
473 | * guarantee forward progress */ | 457 | * guarantee forward progress. |
458 | */ | ||
474 | if (!overlay->old_vid_bo) | 459 | if (!overlay->old_vid_bo) |
475 | return 0; | 460 | return 0; |
476 | 461 | ||
477 | ret = intel_overlay_wait_flip(overlay); | 462 | if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) { |
478 | if (ret != 0) | 463 | struct drm_i915_gem_request *request; |
479 | return ret; | ||
480 | 464 | ||
481 | obj = &overlay->old_vid_bo->base; | 465 | /* synchronous slowpath */ |
482 | i915_gem_object_unpin(obj); | 466 | request = kzalloc(sizeof(*request), GFP_KERNEL); |
483 | drm_gem_object_unreference(obj); | 467 | if (request == NULL) |
484 | overlay->old_vid_bo = NULL; | 468 | return -ENOMEM; |
469 | |||
470 | BEGIN_LP_RING(2); | ||
471 | OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | ||
472 | OUT_RING(MI_NOOP); | ||
473 | ADVANCE_LP_RING(); | ||
474 | |||
475 | ret = intel_overlay_do_wait_request(overlay, request, true, | ||
476 | intel_overlay_release_old_vid_tail); | ||
477 | if (ret) | ||
478 | return ret; | ||
479 | } | ||
485 | 480 | ||
481 | intel_overlay_release_old_vid_tail(overlay); | ||
486 | return 0; | 482 | return 0; |
487 | } | 483 | } |
488 | 484 | ||
@@ -506,50 +502,50 @@ struct put_image_params { | |||
506 | static int packed_depth_bytes(u32 format) | 502 | static int packed_depth_bytes(u32 format) |
507 | { | 503 | { |
508 | switch (format & I915_OVERLAY_DEPTH_MASK) { | 504 | switch (format & I915_OVERLAY_DEPTH_MASK) { |
509 | case I915_OVERLAY_YUV422: | 505 | case I915_OVERLAY_YUV422: |
510 | return 4; | 506 | return 4; |
511 | case I915_OVERLAY_YUV411: | 507 | case I915_OVERLAY_YUV411: |
512 | /* return 6; not implemented */ | 508 | /* return 6; not implemented */ |
513 | default: | 509 | default: |
514 | return -EINVAL; | 510 | return -EINVAL; |
515 | } | 511 | } |
516 | } | 512 | } |
517 | 513 | ||
518 | static int packed_width_bytes(u32 format, short width) | 514 | static int packed_width_bytes(u32 format, short width) |
519 | { | 515 | { |
520 | switch (format & I915_OVERLAY_DEPTH_MASK) { | 516 | switch (format & I915_OVERLAY_DEPTH_MASK) { |
521 | case I915_OVERLAY_YUV422: | 517 | case I915_OVERLAY_YUV422: |
522 | return width << 1; | 518 | return width << 1; |
523 | default: | 519 | default: |
524 | return -EINVAL; | 520 | return -EINVAL; |
525 | } | 521 | } |
526 | } | 522 | } |
527 | 523 | ||
528 | static int uv_hsubsampling(u32 format) | 524 | static int uv_hsubsampling(u32 format) |
529 | { | 525 | { |
530 | switch (format & I915_OVERLAY_DEPTH_MASK) { | 526 | switch (format & I915_OVERLAY_DEPTH_MASK) { |
531 | case I915_OVERLAY_YUV422: | 527 | case I915_OVERLAY_YUV422: |
532 | case I915_OVERLAY_YUV420: | 528 | case I915_OVERLAY_YUV420: |
533 | return 2; | 529 | return 2; |
534 | case I915_OVERLAY_YUV411: | 530 | case I915_OVERLAY_YUV411: |
535 | case I915_OVERLAY_YUV410: | 531 | case I915_OVERLAY_YUV410: |
536 | return 4; | 532 | return 4; |
537 | default: | 533 | default: |
538 | return -EINVAL; | 534 | return -EINVAL; |
539 | } | 535 | } |
540 | } | 536 | } |
541 | 537 | ||
542 | static int uv_vsubsampling(u32 format) | 538 | static int uv_vsubsampling(u32 format) |
543 | { | 539 | { |
544 | switch (format & I915_OVERLAY_DEPTH_MASK) { | 540 | switch (format & I915_OVERLAY_DEPTH_MASK) { |
545 | case I915_OVERLAY_YUV420: | 541 | case I915_OVERLAY_YUV420: |
546 | case I915_OVERLAY_YUV410: | 542 | case I915_OVERLAY_YUV410: |
547 | return 2; | 543 | return 2; |
548 | case I915_OVERLAY_YUV422: | 544 | case I915_OVERLAY_YUV422: |
549 | case I915_OVERLAY_YUV411: | 545 | case I915_OVERLAY_YUV411: |
550 | return 1; | 546 | return 1; |
551 | default: | 547 | default: |
552 | return -EINVAL; | 548 | return -EINVAL; |
553 | } | 549 | } |
554 | } | 550 | } |
555 | 551 | ||
@@ -587,7 +583,9 @@ static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = { | |||
587 | 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060, | 583 | 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060, |
588 | 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040, | 584 | 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040, |
589 | 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020, | 585 | 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020, |
590 | 0xb000, 0x3000, 0x0800, 0x3000, 0xb000}; | 586 | 0xb000, 0x3000, 0x0800, 0x3000, 0xb000 |
587 | }; | ||
588 | |||
591 | static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = { | 589 | static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = { |
592 | 0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60, | 590 | 0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60, |
593 | 0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40, | 591 | 0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40, |
@@ -597,7 +595,8 @@ static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = { | |||
597 | 0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0, | 595 | 0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0, |
598 | 0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240, | 596 | 0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240, |
599 | 0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0, | 597 | 0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0, |
600 | 0x3000, 0x0800, 0x3000}; | 598 | 0x3000, 0x0800, 0x3000 |
599 | }; | ||
601 | 600 | ||
602 | static void update_polyphase_filter(struct overlay_registers *regs) | 601 | static void update_polyphase_filter(struct overlay_registers *regs) |
603 | { | 602 | { |
@@ -630,29 +629,31 @@ static bool update_scaling_factors(struct intel_overlay *overlay, | |||
630 | yscale = 1 << FP_SHIFT; | 629 | yscale = 1 << FP_SHIFT; |
631 | 630 | ||
632 | /*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/ | 631 | /*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/ |
633 | xscale_UV = xscale/uv_hscale; | 632 | xscale_UV = xscale/uv_hscale; |
634 | yscale_UV = yscale/uv_vscale; | 633 | yscale_UV = yscale/uv_vscale; |
635 | /* make the Y scale to UV scale ratio an exact multiply */ | 634 | /* make the Y scale to UV scale ratio an exact multiply */ |
636 | xscale = xscale_UV * uv_hscale; | 635 | xscale = xscale_UV * uv_hscale; |
637 | yscale = yscale_UV * uv_vscale; | 636 | yscale = yscale_UV * uv_vscale; |
638 | /*} else { | 637 | /*} else { |
639 | xscale_UV = 0; | 638 | xscale_UV = 0; |
640 | yscale_UV = 0; | 639 | yscale_UV = 0; |
641 | }*/ | 640 | }*/ |
642 | 641 | ||
643 | if (xscale != overlay->old_xscale || yscale != overlay->old_yscale) | 642 | if (xscale != overlay->old_xscale || yscale != overlay->old_yscale) |
644 | scale_changed = true; | 643 | scale_changed = true; |
645 | overlay->old_xscale = xscale; | 644 | overlay->old_xscale = xscale; |
646 | overlay->old_yscale = yscale; | 645 | overlay->old_yscale = yscale; |
647 | 646 | ||
648 | regs->YRGBSCALE = ((yscale & FRACT_MASK) << 20) | 647 | regs->YRGBSCALE = (((yscale & FRACT_MASK) << 20) | |
649 | | ((xscale >> FP_SHIFT) << 16) | 648 | ((xscale >> FP_SHIFT) << 16) | |
650 | | ((xscale & FRACT_MASK) << 3); | 649 | ((xscale & FRACT_MASK) << 3)); |
651 | regs->UVSCALE = ((yscale_UV & FRACT_MASK) << 20) | 650 | |
652 | | ((xscale_UV >> FP_SHIFT) << 16) | 651 | regs->UVSCALE = (((yscale_UV & FRACT_MASK) << 20) | |
653 | | ((xscale_UV & FRACT_MASK) << 3); | 652 | ((xscale_UV >> FP_SHIFT) << 16) | |
654 | regs->UVSCALEV = ((yscale >> FP_SHIFT) << 16) | 653 | ((xscale_UV & FRACT_MASK) << 3)); |
655 | | ((yscale_UV >> FP_SHIFT) << 0); | 654 | |
655 | regs->UVSCALEV = ((((yscale >> FP_SHIFT) << 16) | | ||
656 | ((yscale_UV >> FP_SHIFT) << 0))); | ||
656 | 657 | ||
657 | if (scale_changed) | 658 | if (scale_changed) |
658 | update_polyphase_filter(regs); | 659 | update_polyphase_filter(regs); |
@@ -664,22 +665,28 @@ static void update_colorkey(struct intel_overlay *overlay, | |||
664 | struct overlay_registers *regs) | 665 | struct overlay_registers *regs) |
665 | { | 666 | { |
666 | u32 key = overlay->color_key; | 667 | u32 key = overlay->color_key; |
668 | |||
667 | switch (overlay->crtc->base.fb->bits_per_pixel) { | 669 | switch (overlay->crtc->base.fb->bits_per_pixel) { |
668 | case 8: | 670 | case 8: |
669 | regs->DCLRKV = 0; | 671 | regs->DCLRKV = 0; |
670 | regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE; | 672 | regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE; |
671 | case 16: | 673 | break; |
672 | if (overlay->crtc->base.fb->depth == 15) { | 674 | |
673 | regs->DCLRKV = RGB15_TO_COLORKEY(key); | 675 | case 16: |
674 | regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE; | 676 | if (overlay->crtc->base.fb->depth == 15) { |
675 | } else { | 677 | regs->DCLRKV = RGB15_TO_COLORKEY(key); |
676 | regs->DCLRKV = RGB16_TO_COLORKEY(key); | 678 | regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE; |
677 | regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE; | 679 | } else { |
678 | } | 680 | regs->DCLRKV = RGB16_TO_COLORKEY(key); |
679 | case 24: | 681 | regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE; |
680 | case 32: | 682 | } |
681 | regs->DCLRKV = key; | 683 | break; |
682 | regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE; | 684 | |
685 | case 24: | ||
686 | case 32: | ||
687 | regs->DCLRKV = key; | ||
688 | regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE; | ||
689 | break; | ||
683 | } | 690 | } |
684 | } | 691 | } |
685 | 692 | ||
@@ -689,48 +696,48 @@ static u32 overlay_cmd_reg(struct put_image_params *params) | |||
689 | 696 | ||
690 | if (params->format & I915_OVERLAY_YUV_PLANAR) { | 697 | if (params->format & I915_OVERLAY_YUV_PLANAR) { |
691 | switch (params->format & I915_OVERLAY_DEPTH_MASK) { | 698 | switch (params->format & I915_OVERLAY_DEPTH_MASK) { |
692 | case I915_OVERLAY_YUV422: | 699 | case I915_OVERLAY_YUV422: |
693 | cmd |= OCMD_YUV_422_PLANAR; | 700 | cmd |= OCMD_YUV_422_PLANAR; |
694 | break; | 701 | break; |
695 | case I915_OVERLAY_YUV420: | 702 | case I915_OVERLAY_YUV420: |
696 | cmd |= OCMD_YUV_420_PLANAR; | 703 | cmd |= OCMD_YUV_420_PLANAR; |
697 | break; | 704 | break; |
698 | case I915_OVERLAY_YUV411: | 705 | case I915_OVERLAY_YUV411: |
699 | case I915_OVERLAY_YUV410: | 706 | case I915_OVERLAY_YUV410: |
700 | cmd |= OCMD_YUV_410_PLANAR; | 707 | cmd |= OCMD_YUV_410_PLANAR; |
701 | break; | 708 | break; |
702 | } | 709 | } |
703 | } else { /* YUV packed */ | 710 | } else { /* YUV packed */ |
704 | switch (params->format & I915_OVERLAY_DEPTH_MASK) { | 711 | switch (params->format & I915_OVERLAY_DEPTH_MASK) { |
705 | case I915_OVERLAY_YUV422: | 712 | case I915_OVERLAY_YUV422: |
706 | cmd |= OCMD_YUV_422_PACKED; | 713 | cmd |= OCMD_YUV_422_PACKED; |
707 | break; | 714 | break; |
708 | case I915_OVERLAY_YUV411: | 715 | case I915_OVERLAY_YUV411: |
709 | cmd |= OCMD_YUV_411_PACKED; | 716 | cmd |= OCMD_YUV_411_PACKED; |
710 | break; | 717 | break; |
711 | } | 718 | } |
712 | 719 | ||
713 | switch (params->format & I915_OVERLAY_SWAP_MASK) { | 720 | switch (params->format & I915_OVERLAY_SWAP_MASK) { |
714 | case I915_OVERLAY_NO_SWAP: | 721 | case I915_OVERLAY_NO_SWAP: |
715 | break; | 722 | break; |
716 | case I915_OVERLAY_UV_SWAP: | 723 | case I915_OVERLAY_UV_SWAP: |
717 | cmd |= OCMD_UV_SWAP; | 724 | cmd |= OCMD_UV_SWAP; |
718 | break; | 725 | break; |
719 | case I915_OVERLAY_Y_SWAP: | 726 | case I915_OVERLAY_Y_SWAP: |
720 | cmd |= OCMD_Y_SWAP; | 727 | cmd |= OCMD_Y_SWAP; |
721 | break; | 728 | break; |
722 | case I915_OVERLAY_Y_AND_UV_SWAP: | 729 | case I915_OVERLAY_Y_AND_UV_SWAP: |
723 | cmd |= OCMD_Y_AND_UV_SWAP; | 730 | cmd |= OCMD_Y_AND_UV_SWAP; |
724 | break; | 731 | break; |
725 | } | 732 | } |
726 | } | 733 | } |
727 | 734 | ||
728 | return cmd; | 735 | return cmd; |
729 | } | 736 | } |
730 | 737 | ||
731 | int intel_overlay_do_put_image(struct intel_overlay *overlay, | 738 | static int intel_overlay_do_put_image(struct intel_overlay *overlay, |
732 | struct drm_gem_object *new_bo, | 739 | struct drm_gem_object *new_bo, |
733 | struct put_image_params *params) | 740 | struct put_image_params *params) |
734 | { | 741 | { |
735 | int ret, tmp_width; | 742 | int ret, tmp_width; |
736 | struct overlay_registers *regs; | 743 | struct overlay_registers *regs; |
@@ -755,7 +762,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
755 | goto out_unpin; | 762 | goto out_unpin; |
756 | 763 | ||
757 | if (!overlay->active) { | 764 | if (!overlay->active) { |
758 | regs = intel_overlay_map_regs_atomic(overlay); | 765 | regs = intel_overlay_map_regs(overlay); |
759 | if (!regs) { | 766 | if (!regs) { |
760 | ret = -ENOMEM; | 767 | ret = -ENOMEM; |
761 | goto out_unpin; | 768 | goto out_unpin; |
@@ -765,14 +772,14 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
765 | regs->OCONFIG |= OCONF_CSC_MODE_BT709; | 772 | regs->OCONFIG |= OCONF_CSC_MODE_BT709; |
766 | regs->OCONFIG |= overlay->crtc->pipe == 0 ? | 773 | regs->OCONFIG |= overlay->crtc->pipe == 0 ? |
767 | OCONF_PIPE_A : OCONF_PIPE_B; | 774 | OCONF_PIPE_A : OCONF_PIPE_B; |
768 | intel_overlay_unmap_regs_atomic(overlay); | 775 | intel_overlay_unmap_regs(overlay, regs); |
769 | 776 | ||
770 | ret = intel_overlay_on(overlay); | 777 | ret = intel_overlay_on(overlay); |
771 | if (ret != 0) | 778 | if (ret != 0) |
772 | goto out_unpin; | 779 | goto out_unpin; |
773 | } | 780 | } |
774 | 781 | ||
775 | regs = intel_overlay_map_regs_atomic(overlay); | 782 | regs = intel_overlay_map_regs(overlay); |
776 | if (!regs) { | 783 | if (!regs) { |
777 | ret = -ENOMEM; | 784 | ret = -ENOMEM; |
778 | goto out_unpin; | 785 | goto out_unpin; |
@@ -788,7 +795,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
788 | 795 | ||
789 | regs->SWIDTH = params->src_w; | 796 | regs->SWIDTH = params->src_w; |
790 | regs->SWIDTHSW = calc_swidthsw(overlay->dev, | 797 | regs->SWIDTHSW = calc_swidthsw(overlay->dev, |
791 | params->offset_Y, tmp_width); | 798 | params->offset_Y, tmp_width); |
792 | regs->SHEIGHT = params->src_h; | 799 | regs->SHEIGHT = params->src_h; |
793 | regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y; | 800 | regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y; |
794 | regs->OSTRIDE = params->stride_Y; | 801 | regs->OSTRIDE = params->stride_Y; |
@@ -799,9 +806,9 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
799 | u32 tmp_U, tmp_V; | 806 | u32 tmp_U, tmp_V; |
800 | regs->SWIDTH |= (params->src_w/uv_hscale) << 16; | 807 | regs->SWIDTH |= (params->src_w/uv_hscale) << 16; |
801 | tmp_U = calc_swidthsw(overlay->dev, params->offset_U, | 808 | tmp_U = calc_swidthsw(overlay->dev, params->offset_U, |
802 | params->src_w/uv_hscale); | 809 | params->src_w/uv_hscale); |
803 | tmp_V = calc_swidthsw(overlay->dev, params->offset_V, | 810 | tmp_V = calc_swidthsw(overlay->dev, params->offset_V, |
804 | params->src_w/uv_hscale); | 811 | params->src_w/uv_hscale); |
805 | regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16; | 812 | regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16; |
806 | regs->SHEIGHT |= (params->src_h/uv_vscale) << 16; | 813 | regs->SHEIGHT |= (params->src_h/uv_vscale) << 16; |
807 | regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U; | 814 | regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U; |
@@ -815,9 +822,11 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
815 | 822 | ||
816 | regs->OCMD = overlay_cmd_reg(params); | 823 | regs->OCMD = overlay_cmd_reg(params); |
817 | 824 | ||
818 | intel_overlay_unmap_regs_atomic(overlay); | 825 | intel_overlay_unmap_regs(overlay, regs); |
819 | 826 | ||
820 | intel_overlay_continue(overlay, scale_changed); | 827 | ret = intel_overlay_continue(overlay, scale_changed); |
828 | if (ret) | ||
829 | goto out_unpin; | ||
821 | 830 | ||
822 | overlay->old_vid_bo = overlay->vid_bo; | 831 | overlay->old_vid_bo = overlay->vid_bo; |
823 | overlay->vid_bo = to_intel_bo(new_bo); | 832 | overlay->vid_bo = to_intel_bo(new_bo); |
@@ -829,20 +838,19 @@ out_unpin: | |||
829 | return ret; | 838 | return ret; |
830 | } | 839 | } |
831 | 840 | ||
832 | int intel_overlay_switch_off(struct intel_overlay *overlay) | 841 | int intel_overlay_switch_off(struct intel_overlay *overlay, |
842 | bool interruptible) | ||
833 | { | 843 | { |
834 | int ret; | ||
835 | struct overlay_registers *regs; | 844 | struct overlay_registers *regs; |
836 | struct drm_device *dev = overlay->dev; | 845 | struct drm_device *dev = overlay->dev; |
846 | int ret; | ||
837 | 847 | ||
838 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); | 848 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); |
839 | BUG_ON(!mutex_is_locked(&dev->mode_config.mutex)); | 849 | BUG_ON(!mutex_is_locked(&dev->mode_config.mutex)); |
840 | 850 | ||
841 | if (overlay->hw_wedged) { | 851 | ret = intel_overlay_recover_from_interrupt(overlay, interruptible); |
842 | ret = intel_overlay_recover_from_interrupt(overlay, 1); | 852 | if (ret != 0) |
843 | if (ret != 0) | 853 | return ret; |
844 | return ret; | ||
845 | } | ||
846 | 854 | ||
847 | if (!overlay->active) | 855 | if (!overlay->active) |
848 | return 0; | 856 | return 0; |
@@ -851,33 +859,29 @@ int intel_overlay_switch_off(struct intel_overlay *overlay) | |||
851 | if (ret != 0) | 859 | if (ret != 0) |
852 | return ret; | 860 | return ret; |
853 | 861 | ||
854 | regs = intel_overlay_map_regs_atomic(overlay); | 862 | regs = intel_overlay_map_regs(overlay); |
855 | regs->OCMD = 0; | 863 | regs->OCMD = 0; |
856 | intel_overlay_unmap_regs_atomic(overlay); | 864 | intel_overlay_unmap_regs(overlay, regs); |
857 | 865 | ||
858 | ret = intel_overlay_off(overlay); | 866 | ret = intel_overlay_off(overlay, interruptible); |
859 | if (ret != 0) | 867 | if (ret != 0) |
860 | return ret; | 868 | return ret; |
861 | 869 | ||
862 | intel_overlay_off_tail(overlay); | 870 | intel_overlay_off_tail(overlay); |
863 | |||
864 | return 0; | 871 | return 0; |
865 | } | 872 | } |
866 | 873 | ||
867 | static int check_overlay_possible_on_crtc(struct intel_overlay *overlay, | 874 | static int check_overlay_possible_on_crtc(struct intel_overlay *overlay, |
868 | struct intel_crtc *crtc) | 875 | struct intel_crtc *crtc) |
869 | { | 876 | { |
870 | drm_i915_private_t *dev_priv = overlay->dev->dev_private; | 877 | drm_i915_private_t *dev_priv = overlay->dev->dev_private; |
871 | u32 pipeconf; | ||
872 | int pipeconf_reg = (crtc->pipe == 0) ? PIPEACONF : PIPEBCONF; | ||
873 | 878 | ||
874 | if (!crtc->base.enabled || crtc->dpms_mode != DRM_MODE_DPMS_ON) | 879 | if (!crtc->active) |
875 | return -EINVAL; | 880 | return -EINVAL; |
876 | 881 | ||
877 | pipeconf = I915_READ(pipeconf_reg); | ||
878 | |||
879 | /* can't use the overlay with double wide pipe */ | 882 | /* can't use the overlay with double wide pipe */ |
880 | if (!IS_I965G(overlay->dev) && pipeconf & PIPEACONF_DOUBLE_WIDE) | 883 | if (!IS_I965G(overlay->dev) && |
884 | (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE) | ||
881 | return -EINVAL; | 885 | return -EINVAL; |
882 | 886 | ||
883 | return 0; | 887 | return 0; |
@@ -886,20 +890,21 @@ static int check_overlay_possible_on_crtc(struct intel_overlay *overlay, | |||
886 | static void update_pfit_vscale_ratio(struct intel_overlay *overlay) | 890 | static void update_pfit_vscale_ratio(struct intel_overlay *overlay) |
887 | { | 891 | { |
888 | struct drm_device *dev = overlay->dev; | 892 | struct drm_device *dev = overlay->dev; |
889 | drm_i915_private_t *dev_priv = dev->dev_private; | 893 | drm_i915_private_t *dev_priv = dev->dev_private; |
890 | u32 ratio; | ||
891 | u32 pfit_control = I915_READ(PFIT_CONTROL); | 894 | u32 pfit_control = I915_READ(PFIT_CONTROL); |
895 | u32 ratio; | ||
892 | 896 | ||
893 | /* XXX: This is not the same logic as in the xorg driver, but more in | 897 | /* XXX: This is not the same logic as in the xorg driver, but more in |
894 | * line with the intel documentation for the i965 */ | 898 | * line with the intel documentation for the i965 |
895 | if (!IS_I965G(dev) && (pfit_control & VERT_AUTO_SCALE)) { | 899 | */ |
896 | ratio = I915_READ(PFIT_AUTO_RATIOS) >> PFIT_VERT_SCALE_SHIFT; | 900 | if (!IS_I965G(dev)) { |
897 | } else { /* on i965 use the PGM reg to read out the autoscaler values */ | 901 | if (pfit_control & VERT_AUTO_SCALE) |
898 | ratio = I915_READ(PFIT_PGM_RATIOS); | 902 | ratio = I915_READ(PFIT_AUTO_RATIOS); |
899 | if (IS_I965G(dev)) | ||
900 | ratio >>= PFIT_VERT_SCALE_SHIFT_965; | ||
901 | else | 903 | else |
902 | ratio >>= PFIT_VERT_SCALE_SHIFT; | 904 | ratio = I915_READ(PFIT_PGM_RATIOS); |
905 | ratio >>= PFIT_VERT_SCALE_SHIFT; | ||
906 | } else { /* on i965 use the PGM reg to read out the autoscaler values */ | ||
907 | ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965; | ||
903 | } | 908 | } |
904 | 909 | ||
905 | overlay->pfit_vscale_ratio = ratio; | 910 | overlay->pfit_vscale_ratio = ratio; |
@@ -910,12 +915,10 @@ static int check_overlay_dst(struct intel_overlay *overlay, | |||
910 | { | 915 | { |
911 | struct drm_display_mode *mode = &overlay->crtc->base.mode; | 916 | struct drm_display_mode *mode = &overlay->crtc->base.mode; |
912 | 917 | ||
913 | if ((rec->dst_x < mode->crtc_hdisplay) | 918 | if (rec->dst_x < mode->crtc_hdisplay && |
914 | && (rec->dst_x + rec->dst_width | 919 | rec->dst_x + rec->dst_width <= mode->crtc_hdisplay && |
915 | <= mode->crtc_hdisplay) | 920 | rec->dst_y < mode->crtc_vdisplay && |
916 | && (rec->dst_y < mode->crtc_vdisplay) | 921 | rec->dst_y + rec->dst_height <= mode->crtc_vdisplay) |
917 | && (rec->dst_y + rec->dst_height | ||
918 | <= mode->crtc_vdisplay)) | ||
919 | return 0; | 922 | return 0; |
920 | else | 923 | else |
921 | return -EINVAL; | 924 | return -EINVAL; |
@@ -940,53 +943,57 @@ static int check_overlay_src(struct drm_device *dev, | |||
940 | struct drm_intel_overlay_put_image *rec, | 943 | struct drm_intel_overlay_put_image *rec, |
941 | struct drm_gem_object *new_bo) | 944 | struct drm_gem_object *new_bo) |
942 | { | 945 | { |
943 | u32 stride_mask; | ||
944 | int depth; | ||
945 | int uv_hscale = uv_hsubsampling(rec->flags); | 946 | int uv_hscale = uv_hsubsampling(rec->flags); |
946 | int uv_vscale = uv_vsubsampling(rec->flags); | 947 | int uv_vscale = uv_vsubsampling(rec->flags); |
947 | size_t tmp; | 948 | u32 stride_mask, depth, tmp; |
948 | 949 | ||
949 | /* check src dimensions */ | 950 | /* check src dimensions */ |
950 | if (IS_845G(dev) || IS_I830(dev)) { | 951 | if (IS_845G(dev) || IS_I830(dev)) { |
951 | if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY | 952 | if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY || |
952 | || rec->src_width > IMAGE_MAX_WIDTH_LEGACY) | 953 | rec->src_width > IMAGE_MAX_WIDTH_LEGACY) |
953 | return -EINVAL; | 954 | return -EINVAL; |
954 | } else { | 955 | } else { |
955 | if (rec->src_height > IMAGE_MAX_HEIGHT | 956 | if (rec->src_height > IMAGE_MAX_HEIGHT || |
956 | || rec->src_width > IMAGE_MAX_WIDTH) | 957 | rec->src_width > IMAGE_MAX_WIDTH) |
957 | return -EINVAL; | 958 | return -EINVAL; |
958 | } | 959 | } |
960 | |||
959 | /* better safe than sorry, use 4 as the maximal subsampling ratio */ | 961 | /* better safe than sorry, use 4 as the maximal subsampling ratio */ |
960 | if (rec->src_height < N_VERT_Y_TAPS*4 | 962 | if (rec->src_height < N_VERT_Y_TAPS*4 || |
961 | || rec->src_width < N_HORIZ_Y_TAPS*4) | 963 | rec->src_width < N_HORIZ_Y_TAPS*4) |
962 | return -EINVAL; | 964 | return -EINVAL; |
963 | 965 | ||
964 | /* check alignment constraints */ | 966 | /* check alignment constraints */ |
965 | switch (rec->flags & I915_OVERLAY_TYPE_MASK) { | 967 | switch (rec->flags & I915_OVERLAY_TYPE_MASK) { |
966 | case I915_OVERLAY_RGB: | 968 | case I915_OVERLAY_RGB: |
967 | /* not implemented */ | 969 | /* not implemented */ |
970 | return -EINVAL; | ||
971 | |||
972 | case I915_OVERLAY_YUV_PACKED: | ||
973 | if (uv_vscale != 1) | ||
968 | return -EINVAL; | 974 | return -EINVAL; |
969 | case I915_OVERLAY_YUV_PACKED: | 975 | |
970 | depth = packed_depth_bytes(rec->flags); | 976 | depth = packed_depth_bytes(rec->flags); |
971 | if (uv_vscale != 1) | 977 | if (depth < 0) |
972 | return -EINVAL; | 978 | return depth; |
973 | if (depth < 0) | 979 | |
974 | return depth; | 980 | /* ignore UV planes */ |
975 | /* ignore UV planes */ | 981 | rec->stride_UV = 0; |
976 | rec->stride_UV = 0; | 982 | rec->offset_U = 0; |
977 | rec->offset_U = 0; | 983 | rec->offset_V = 0; |
978 | rec->offset_V = 0; | 984 | /* check pixel alignment */ |
979 | /* check pixel alignment */ | 985 | if (rec->offset_Y % depth) |
980 | if (rec->offset_Y % depth) | ||
981 | return -EINVAL; | ||
982 | break; | ||
983 | case I915_OVERLAY_YUV_PLANAR: | ||
984 | if (uv_vscale < 0 || uv_hscale < 0) | ||
985 | return -EINVAL; | ||
986 | /* no offset restrictions for planar formats */ | ||
987 | break; | ||
988 | default: | ||
989 | return -EINVAL; | 986 | return -EINVAL; |
987 | break; | ||
988 | |||
989 | case I915_OVERLAY_YUV_PLANAR: | ||
990 | if (uv_vscale < 0 || uv_hscale < 0) | ||
991 | return -EINVAL; | ||
992 | /* no offset restrictions for planar formats */ | ||
993 | break; | ||
994 | |||
995 | default: | ||
996 | return -EINVAL; | ||
990 | } | 997 | } |
991 | 998 | ||
992 | if (rec->src_width % uv_hscale) | 999 | if (rec->src_width % uv_hscale) |
@@ -1004,43 +1011,70 @@ static int check_overlay_src(struct drm_device *dev, | |||
1004 | return -EINVAL; | 1011 | return -EINVAL; |
1005 | 1012 | ||
1006 | tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ? | 1013 | tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ? |
1007 | 4 : 8; | 1014 | 4096 : 8192; |
1008 | if (rec->stride_Y > tmp*1024 || rec->stride_UV > 2*1024) | 1015 | if (rec->stride_Y > tmp || rec->stride_UV > 2*1024) |
1009 | return -EINVAL; | 1016 | return -EINVAL; |
1010 | 1017 | ||
1011 | /* check buffer dimensions */ | 1018 | /* check buffer dimensions */ |
1012 | switch (rec->flags & I915_OVERLAY_TYPE_MASK) { | 1019 | switch (rec->flags & I915_OVERLAY_TYPE_MASK) { |
1013 | case I915_OVERLAY_RGB: | 1020 | case I915_OVERLAY_RGB: |
1014 | case I915_OVERLAY_YUV_PACKED: | 1021 | case I915_OVERLAY_YUV_PACKED: |
1015 | /* always 4 Y values per depth pixels */ | 1022 | /* always 4 Y values per depth pixels */ |
1016 | if (packed_width_bytes(rec->flags, rec->src_width) | 1023 | if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y) |
1017 | > rec->stride_Y) | 1024 | return -EINVAL; |
1018 | return -EINVAL; | 1025 | |
1019 | 1026 | tmp = rec->stride_Y*rec->src_height; | |
1020 | tmp = rec->stride_Y*rec->src_height; | 1027 | if (rec->offset_Y + tmp > new_bo->size) |
1021 | if (rec->offset_Y + tmp > new_bo->size) | 1028 | return -EINVAL; |
1022 | return -EINVAL; | 1029 | break; |
1023 | break; | 1030 | |
1024 | case I915_OVERLAY_YUV_PLANAR: | 1031 | case I915_OVERLAY_YUV_PLANAR: |
1025 | if (rec->src_width > rec->stride_Y) | 1032 | if (rec->src_width > rec->stride_Y) |
1026 | return -EINVAL; | 1033 | return -EINVAL; |
1027 | if (rec->src_width/uv_hscale > rec->stride_UV) | 1034 | if (rec->src_width/uv_hscale > rec->stride_UV) |
1028 | return -EINVAL; | 1035 | return -EINVAL; |
1029 | 1036 | ||
1030 | tmp = rec->stride_Y*rec->src_height; | 1037 | tmp = rec->stride_Y * rec->src_height; |
1031 | if (rec->offset_Y + tmp > new_bo->size) | 1038 | if (rec->offset_Y + tmp > new_bo->size) |
1032 | return -EINVAL; | 1039 | return -EINVAL; |
1033 | tmp = rec->stride_UV*rec->src_height; | 1040 | |
1034 | tmp /= uv_vscale; | 1041 | tmp = rec->stride_UV * (rec->src_height / uv_vscale); |
1035 | if (rec->offset_U + tmp > new_bo->size | 1042 | if (rec->offset_U + tmp > new_bo->size || |
1036 | || rec->offset_V + tmp > new_bo->size) | 1043 | rec->offset_V + tmp > new_bo->size) |
1037 | return -EINVAL; | 1044 | return -EINVAL; |
1038 | break; | 1045 | break; |
1039 | } | 1046 | } |
1040 | 1047 | ||
1041 | return 0; | 1048 | return 0; |
1042 | } | 1049 | } |
1043 | 1050 | ||
1051 | /** | ||
1052 | * Return the pipe currently connected to the panel fitter, | ||
1053 | * or -1 if the panel fitter is not present or not in use | ||
1054 | */ | ||
1055 | static int intel_panel_fitter_pipe(struct drm_device *dev) | ||
1056 | { | ||
1057 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1058 | u32 pfit_control; | ||
1059 | |||
1060 | /* i830 doesn't have a panel fitter */ | ||
1061 | if (IS_I830(dev)) | ||
1062 | return -1; | ||
1063 | |||
1064 | pfit_control = I915_READ(PFIT_CONTROL); | ||
1065 | |||
1066 | /* See if the panel fitter is in use */ | ||
1067 | if ((pfit_control & PFIT_ENABLE) == 0) | ||
1068 | return -1; | ||
1069 | |||
1070 | /* 965 can place panel fitter on either pipe */ | ||
1071 | if (IS_I965G(dev)) | ||
1072 | return (pfit_control >> 29) & 0x3; | ||
1073 | |||
1074 | /* older chips can only use pipe 1 */ | ||
1075 | return 1; | ||
1076 | } | ||
1077 | |||
1044 | int intel_overlay_put_image(struct drm_device *dev, void *data, | 1078 | int intel_overlay_put_image(struct drm_device *dev, void *data, |
1045 | struct drm_file *file_priv) | 1079 | struct drm_file *file_priv) |
1046 | { | 1080 | { |
@@ -1068,7 +1102,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
1068 | mutex_lock(&dev->mode_config.mutex); | 1102 | mutex_lock(&dev->mode_config.mutex); |
1069 | mutex_lock(&dev->struct_mutex); | 1103 | mutex_lock(&dev->struct_mutex); |
1070 | 1104 | ||
1071 | ret = intel_overlay_switch_off(overlay); | 1105 | ret = intel_overlay_switch_off(overlay, true); |
1072 | 1106 | ||
1073 | mutex_unlock(&dev->struct_mutex); | 1107 | mutex_unlock(&dev->struct_mutex); |
1074 | mutex_unlock(&dev->mode_config.mutex); | 1108 | mutex_unlock(&dev->mode_config.mutex); |
@@ -1081,7 +1115,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
1081 | return -ENOMEM; | 1115 | return -ENOMEM; |
1082 | 1116 | ||
1083 | drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id, | 1117 | drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id, |
1084 | DRM_MODE_OBJECT_CRTC); | 1118 | DRM_MODE_OBJECT_CRTC); |
1085 | if (!drmmode_obj) { | 1119 | if (!drmmode_obj) { |
1086 | ret = -ENOENT; | 1120 | ret = -ENOENT; |
1087 | goto out_free; | 1121 | goto out_free; |
@@ -1089,7 +1123,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
1089 | crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); | 1123 | crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); |
1090 | 1124 | ||
1091 | new_bo = drm_gem_object_lookup(dev, file_priv, | 1125 | new_bo = drm_gem_object_lookup(dev, file_priv, |
1092 | put_image_rec->bo_handle); | 1126 | put_image_rec->bo_handle); |
1093 | if (!new_bo) { | 1127 | if (!new_bo) { |
1094 | ret = -ENOENT; | 1128 | ret = -ENOENT; |
1095 | goto out_free; | 1129 | goto out_free; |
@@ -1098,15 +1132,13 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
1098 | mutex_lock(&dev->mode_config.mutex); | 1132 | mutex_lock(&dev->mode_config.mutex); |
1099 | mutex_lock(&dev->struct_mutex); | 1133 | mutex_lock(&dev->struct_mutex); |
1100 | 1134 | ||
1101 | if (overlay->hw_wedged) { | 1135 | ret = intel_overlay_recover_from_interrupt(overlay, true); |
1102 | ret = intel_overlay_recover_from_interrupt(overlay, 1); | 1136 | if (ret != 0) |
1103 | if (ret != 0) | 1137 | goto out_unlock; |
1104 | goto out_unlock; | ||
1105 | } | ||
1106 | 1138 | ||
1107 | if (overlay->crtc != crtc) { | 1139 | if (overlay->crtc != crtc) { |
1108 | struct drm_display_mode *mode = &crtc->base.mode; | 1140 | struct drm_display_mode *mode = &crtc->base.mode; |
1109 | ret = intel_overlay_switch_off(overlay); | 1141 | ret = intel_overlay_switch_off(overlay, true); |
1110 | if (ret != 0) | 1142 | if (ret != 0) |
1111 | goto out_unlock; | 1143 | goto out_unlock; |
1112 | 1144 | ||
@@ -1117,9 +1149,9 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
1117 | overlay->crtc = crtc; | 1149 | overlay->crtc = crtc; |
1118 | crtc->overlay = overlay; | 1150 | crtc->overlay = overlay; |
1119 | 1151 | ||
1120 | if (intel_panel_fitter_pipe(dev) == crtc->pipe | 1152 | /* line too wide, i.e. one-line-mode */ |
1121 | /* and line to wide, i.e. one-line-mode */ | 1153 | if (mode->hdisplay > 1024 && |
1122 | && mode->hdisplay > 1024) { | 1154 | intel_panel_fitter_pipe(dev) == crtc->pipe) { |
1123 | overlay->pfit_active = 1; | 1155 | overlay->pfit_active = 1; |
1124 | update_pfit_vscale_ratio(overlay); | 1156 | update_pfit_vscale_ratio(overlay); |
1125 | } else | 1157 | } else |
@@ -1132,10 +1164,10 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
1132 | 1164 | ||
1133 | if (overlay->pfit_active) { | 1165 | if (overlay->pfit_active) { |
1134 | params->dst_y = ((((u32)put_image_rec->dst_y) << 12) / | 1166 | params->dst_y = ((((u32)put_image_rec->dst_y) << 12) / |
1135 | overlay->pfit_vscale_ratio); | 1167 | overlay->pfit_vscale_ratio); |
1136 | /* shifting right rounds downwards, so add 1 */ | 1168 | /* shifting right rounds downwards, so add 1 */ |
1137 | params->dst_h = ((((u32)put_image_rec->dst_height) << 12) / | 1169 | params->dst_h = ((((u32)put_image_rec->dst_height) << 12) / |
1138 | overlay->pfit_vscale_ratio) + 1; | 1170 | overlay->pfit_vscale_ratio) + 1; |
1139 | } else { | 1171 | } else { |
1140 | params->dst_y = put_image_rec->dst_y; | 1172 | params->dst_y = put_image_rec->dst_y; |
1141 | params->dst_h = put_image_rec->dst_height; | 1173 | params->dst_h = put_image_rec->dst_height; |
@@ -1147,8 +1179,8 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, | |||
1147 | params->src_h = put_image_rec->src_height; | 1179 | params->src_h = put_image_rec->src_height; |
1148 | params->src_scan_w = put_image_rec->src_scan_width; | 1180 | params->src_scan_w = put_image_rec->src_scan_width; |
1149 | params->src_scan_h = put_image_rec->src_scan_height; | 1181 | params->src_scan_h = put_image_rec->src_scan_height; |
1150 | if (params->src_scan_h > params->src_h | 1182 | if (params->src_scan_h > params->src_h || |
1151 | || params->src_scan_w > params->src_w) { | 1183 | params->src_scan_w > params->src_w) { |
1152 | ret = -EINVAL; | 1184 | ret = -EINVAL; |
1153 | goto out_unlock; | 1185 | goto out_unlock; |
1154 | } | 1186 | } |
@@ -1204,7 +1236,7 @@ static bool check_gamma_bounds(u32 gamma1, u32 gamma2) | |||
1204 | return false; | 1236 | return false; |
1205 | 1237 | ||
1206 | for (i = 0; i < 3; i++) { | 1238 | for (i = 0; i < 3; i++) { |
1207 | if (((gamma1 >> i * 8) & 0xff) >= ((gamma2 >> i*8) & 0xff)) | 1239 | if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff)) |
1208 | return false; | 1240 | return false; |
1209 | } | 1241 | } |
1210 | 1242 | ||
@@ -1225,16 +1257,18 @@ static bool check_gamma5_errata(u32 gamma5) | |||
1225 | 1257 | ||
1226 | static int check_gamma(struct drm_intel_overlay_attrs *attrs) | 1258 | static int check_gamma(struct drm_intel_overlay_attrs *attrs) |
1227 | { | 1259 | { |
1228 | if (!check_gamma_bounds(0, attrs->gamma0) | 1260 | if (!check_gamma_bounds(0, attrs->gamma0) || |
1229 | || !check_gamma_bounds(attrs->gamma0, attrs->gamma1) | 1261 | !check_gamma_bounds(attrs->gamma0, attrs->gamma1) || |
1230 | || !check_gamma_bounds(attrs->gamma1, attrs->gamma2) | 1262 | !check_gamma_bounds(attrs->gamma1, attrs->gamma2) || |
1231 | || !check_gamma_bounds(attrs->gamma2, attrs->gamma3) | 1263 | !check_gamma_bounds(attrs->gamma2, attrs->gamma3) || |
1232 | || !check_gamma_bounds(attrs->gamma3, attrs->gamma4) | 1264 | !check_gamma_bounds(attrs->gamma3, attrs->gamma4) || |
1233 | || !check_gamma_bounds(attrs->gamma4, attrs->gamma5) | 1265 | !check_gamma_bounds(attrs->gamma4, attrs->gamma5) || |
1234 | || !check_gamma_bounds(attrs->gamma5, 0x00ffffff)) | 1266 | !check_gamma_bounds(attrs->gamma5, 0x00ffffff)) |
1235 | return -EINVAL; | 1267 | return -EINVAL; |
1268 | |||
1236 | if (!check_gamma5_errata(attrs->gamma5)) | 1269 | if (!check_gamma5_errata(attrs->gamma5)) |
1237 | return -EINVAL; | 1270 | return -EINVAL; |
1271 | |||
1238 | return 0; | 1272 | return 0; |
1239 | } | 1273 | } |
1240 | 1274 | ||
@@ -1261,10 +1295,11 @@ int intel_overlay_attrs(struct drm_device *dev, void *data, | |||
1261 | mutex_lock(&dev->mode_config.mutex); | 1295 | mutex_lock(&dev->mode_config.mutex); |
1262 | mutex_lock(&dev->struct_mutex); | 1296 | mutex_lock(&dev->struct_mutex); |
1263 | 1297 | ||
1298 | ret = -EINVAL; | ||
1264 | if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) { | 1299 | if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) { |
1265 | attrs->color_key = overlay->color_key; | 1300 | attrs->color_key = overlay->color_key; |
1266 | attrs->brightness = overlay->brightness; | 1301 | attrs->brightness = overlay->brightness; |
1267 | attrs->contrast = overlay->contrast; | 1302 | attrs->contrast = overlay->contrast; |
1268 | attrs->saturation = overlay->saturation; | 1303 | attrs->saturation = overlay->saturation; |
1269 | 1304 | ||
1270 | if (IS_I9XX(dev)) { | 1305 | if (IS_I9XX(dev)) { |
@@ -1275,29 +1310,20 @@ int intel_overlay_attrs(struct drm_device *dev, void *data, | |||
1275 | attrs->gamma4 = I915_READ(OGAMC4); | 1310 | attrs->gamma4 = I915_READ(OGAMC4); |
1276 | attrs->gamma5 = I915_READ(OGAMC5); | 1311 | attrs->gamma5 = I915_READ(OGAMC5); |
1277 | } | 1312 | } |
1278 | ret = 0; | ||
1279 | } else { | 1313 | } else { |
1280 | overlay->color_key = attrs->color_key; | 1314 | if (attrs->brightness < -128 || attrs->brightness > 127) |
1281 | if (attrs->brightness >= -128 && attrs->brightness <= 127) { | ||
1282 | overlay->brightness = attrs->brightness; | ||
1283 | } else { | ||
1284 | ret = -EINVAL; | ||
1285 | goto out_unlock; | 1315 | goto out_unlock; |
1286 | } | 1316 | if (attrs->contrast > 255) |
1287 | if (attrs->contrast <= 255) { | ||
1288 | overlay->contrast = attrs->contrast; | ||
1289 | } else { | ||
1290 | ret = -EINVAL; | ||
1291 | goto out_unlock; | 1317 | goto out_unlock; |
1292 | } | 1318 | if (attrs->saturation > 1023) |
1293 | if (attrs->saturation <= 1023) { | ||
1294 | overlay->saturation = attrs->saturation; | ||
1295 | } else { | ||
1296 | ret = -EINVAL; | ||
1297 | goto out_unlock; | 1319 | goto out_unlock; |
1298 | } | ||
1299 | 1320 | ||
1300 | regs = intel_overlay_map_regs_atomic(overlay); | 1321 | overlay->color_key = attrs->color_key; |
1322 | overlay->brightness = attrs->brightness; | ||
1323 | overlay->contrast = attrs->contrast; | ||
1324 | overlay->saturation = attrs->saturation; | ||
1325 | |||
1326 | regs = intel_overlay_map_regs(overlay); | ||
1301 | if (!regs) { | 1327 | if (!regs) { |
1302 | ret = -ENOMEM; | 1328 | ret = -ENOMEM; |
1303 | goto out_unlock; | 1329 | goto out_unlock; |
@@ -1305,13 +1331,11 @@ int intel_overlay_attrs(struct drm_device *dev, void *data, | |||
1305 | 1331 | ||
1306 | update_reg_attrs(overlay, regs); | 1332 | update_reg_attrs(overlay, regs); |
1307 | 1333 | ||
1308 | intel_overlay_unmap_regs_atomic(overlay); | 1334 | intel_overlay_unmap_regs(overlay, regs); |
1309 | 1335 | ||
1310 | if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) { | 1336 | if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) { |
1311 | if (!IS_I9XX(dev)) { | 1337 | if (!IS_I9XX(dev)) |
1312 | ret = -EINVAL; | ||
1313 | goto out_unlock; | 1338 | goto out_unlock; |
1314 | } | ||
1315 | 1339 | ||
1316 | if (overlay->active) { | 1340 | if (overlay->active) { |
1317 | ret = -EBUSY; | 1341 | ret = -EBUSY; |
@@ -1319,7 +1343,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data, | |||
1319 | } | 1343 | } |
1320 | 1344 | ||
1321 | ret = check_gamma(attrs); | 1345 | ret = check_gamma(attrs); |
1322 | if (ret != 0) | 1346 | if (ret) |
1323 | goto out_unlock; | 1347 | goto out_unlock; |
1324 | 1348 | ||
1325 | I915_WRITE(OGAMC0, attrs->gamma0); | 1349 | I915_WRITE(OGAMC0, attrs->gamma0); |
@@ -1329,9 +1353,9 @@ int intel_overlay_attrs(struct drm_device *dev, void *data, | |||
1329 | I915_WRITE(OGAMC4, attrs->gamma4); | 1353 | I915_WRITE(OGAMC4, attrs->gamma4); |
1330 | I915_WRITE(OGAMC5, attrs->gamma5); | 1354 | I915_WRITE(OGAMC5, attrs->gamma5); |
1331 | } | 1355 | } |
1332 | ret = 0; | ||
1333 | } | 1356 | } |
1334 | 1357 | ||
1358 | ret = 0; | ||
1335 | out_unlock: | 1359 | out_unlock: |
1336 | mutex_unlock(&dev->struct_mutex); | 1360 | mutex_unlock(&dev->struct_mutex); |
1337 | mutex_unlock(&dev->mode_config.mutex); | 1361 | mutex_unlock(&dev->mode_config.mutex); |
@@ -1347,7 +1371,7 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1347 | struct overlay_registers *regs; | 1371 | struct overlay_registers *regs; |
1348 | int ret; | 1372 | int ret; |
1349 | 1373 | ||
1350 | if (!OVERLAY_EXISTS(dev)) | 1374 | if (!HAS_OVERLAY(dev)) |
1351 | return; | 1375 | return; |
1352 | 1376 | ||
1353 | overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL); | 1377 | overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL); |
@@ -1360,22 +1384,28 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1360 | goto out_free; | 1384 | goto out_free; |
1361 | overlay->reg_bo = to_intel_bo(reg_bo); | 1385 | overlay->reg_bo = to_intel_bo(reg_bo); |
1362 | 1386 | ||
1363 | if (OVERLAY_NONPHYSICAL(dev)) { | 1387 | if (OVERLAY_NEEDS_PHYSICAL(dev)) { |
1364 | ret = i915_gem_object_pin(reg_bo, PAGE_SIZE); | ||
1365 | if (ret) { | ||
1366 | DRM_ERROR("failed to pin overlay register bo\n"); | ||
1367 | goto out_free_bo; | ||
1368 | } | ||
1369 | overlay->flip_addr = overlay->reg_bo->gtt_offset; | ||
1370 | } else { | ||
1371 | ret = i915_gem_attach_phys_object(dev, reg_bo, | 1388 | ret = i915_gem_attach_phys_object(dev, reg_bo, |
1372 | I915_GEM_PHYS_OVERLAY_REGS, | 1389 | I915_GEM_PHYS_OVERLAY_REGS, |
1373 | 0); | 1390 | PAGE_SIZE); |
1374 | if (ret) { | 1391 | if (ret) { |
1375 | DRM_ERROR("failed to attach phys overlay regs\n"); | 1392 | DRM_ERROR("failed to attach phys overlay regs\n"); |
1376 | goto out_free_bo; | 1393 | goto out_free_bo; |
1377 | } | 1394 | } |
1378 | overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr; | 1395 | overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr; |
1396 | } else { | ||
1397 | ret = i915_gem_object_pin(reg_bo, PAGE_SIZE); | ||
1398 | if (ret) { | ||
1399 | DRM_ERROR("failed to pin overlay register bo\n"); | ||
1400 | goto out_free_bo; | ||
1401 | } | ||
1402 | overlay->flip_addr = overlay->reg_bo->gtt_offset; | ||
1403 | |||
1404 | ret = i915_gem_object_set_to_gtt_domain(reg_bo, true); | ||
1405 | if (ret) { | ||
1406 | DRM_ERROR("failed to move overlay register bo into the GTT\n"); | ||
1407 | goto out_unpin_bo; | ||
1408 | } | ||
1379 | } | 1409 | } |
1380 | 1410 | ||
1381 | /* init all values */ | 1411 | /* init all values */ |
@@ -1384,21 +1414,22 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1384 | overlay->contrast = 75; | 1414 | overlay->contrast = 75; |
1385 | overlay->saturation = 146; | 1415 | overlay->saturation = 146; |
1386 | 1416 | ||
1387 | regs = intel_overlay_map_regs_atomic(overlay); | 1417 | regs = intel_overlay_map_regs(overlay); |
1388 | if (!regs) | 1418 | if (!regs) |
1389 | goto out_free_bo; | 1419 | goto out_free_bo; |
1390 | 1420 | ||
1391 | memset(regs, 0, sizeof(struct overlay_registers)); | 1421 | memset(regs, 0, sizeof(struct overlay_registers)); |
1392 | update_polyphase_filter(regs); | 1422 | update_polyphase_filter(regs); |
1393 | |||
1394 | update_reg_attrs(overlay, regs); | 1423 | update_reg_attrs(overlay, regs); |
1395 | 1424 | ||
1396 | intel_overlay_unmap_regs_atomic(overlay); | 1425 | intel_overlay_unmap_regs(overlay, regs); |
1397 | 1426 | ||
1398 | dev_priv->overlay = overlay; | 1427 | dev_priv->overlay = overlay; |
1399 | DRM_INFO("initialized overlay support\n"); | 1428 | DRM_INFO("initialized overlay support\n"); |
1400 | return; | 1429 | return; |
1401 | 1430 | ||
1431 | out_unpin_bo: | ||
1432 | i915_gem_object_unpin(reg_bo); | ||
1402 | out_free_bo: | 1433 | out_free_bo: |
1403 | drm_gem_object_unreference(reg_bo); | 1434 | drm_gem_object_unreference(reg_bo); |
1404 | out_free: | 1435 | out_free: |
@@ -1408,18 +1439,23 @@ out_free: | |||
1408 | 1439 | ||
1409 | void intel_cleanup_overlay(struct drm_device *dev) | 1440 | void intel_cleanup_overlay(struct drm_device *dev) |
1410 | { | 1441 | { |
1411 | drm_i915_private_t *dev_priv = dev->dev_private; | 1442 | drm_i915_private_t *dev_priv = dev->dev_private; |
1412 | 1443 | ||
1413 | if (dev_priv->overlay) { | 1444 | if (!dev_priv->overlay) |
1414 | /* The bo's should be free'd by the generic code already. | 1445 | return; |
1415 | * Furthermore modesetting teardown happens beforehand so the | ||
1416 | * hardware should be off already */ | ||
1417 | BUG_ON(dev_priv->overlay->active); | ||
1418 | 1446 | ||
1419 | kfree(dev_priv->overlay); | 1447 | /* The bo's should be free'd by the generic code already. |
1420 | } | 1448 | * Furthermore modesetting teardown happens beforehand so the |
1449 | * hardware should be off already */ | ||
1450 | BUG_ON(dev_priv->overlay->active); | ||
1451 | |||
1452 | drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base); | ||
1453 | kfree(dev_priv->overlay); | ||
1421 | } | 1454 | } |
1422 | 1455 | ||
1456 | #ifdef CONFIG_DEBUG_FS | ||
1457 | #include <linux/seq_file.h> | ||
1458 | |||
1423 | struct intel_overlay_error_state { | 1459 | struct intel_overlay_error_state { |
1424 | struct overlay_registers regs; | 1460 | struct overlay_registers regs; |
1425 | unsigned long base; | 1461 | unsigned long base; |
@@ -1427,6 +1463,32 @@ struct intel_overlay_error_state { | |||
1427 | u32 isr; | 1463 | u32 isr; |
1428 | }; | 1464 | }; |
1429 | 1465 | ||
1466 | static struct overlay_registers * | ||
1467 | intel_overlay_map_regs_atomic(struct intel_overlay *overlay, | ||
1468 | int slot) | ||
1469 | { | ||
1470 | drm_i915_private_t *dev_priv = overlay->dev->dev_private; | ||
1471 | struct overlay_registers *regs; | ||
1472 | |||
1473 | if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) | ||
1474 | regs = overlay->reg_bo->phys_obj->handle->vaddr; | ||
1475 | else | ||
1476 | regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, | ||
1477 | overlay->reg_bo->gtt_offset, | ||
1478 | slot); | ||
1479 | |||
1480 | return regs; | ||
1481 | } | ||
1482 | |||
1483 | static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay, | ||
1484 | int slot, | ||
1485 | struct overlay_registers *regs) | ||
1486 | { | ||
1487 | if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev)) | ||
1488 | io_mapping_unmap_atomic(regs, slot); | ||
1489 | } | ||
1490 | |||
1491 | |||
1430 | struct intel_overlay_error_state * | 1492 | struct intel_overlay_error_state * |
1431 | intel_overlay_capture_error_state(struct drm_device *dev) | 1493 | intel_overlay_capture_error_state(struct drm_device *dev) |
1432 | { | 1494 | { |
@@ -1444,17 +1506,17 @@ intel_overlay_capture_error_state(struct drm_device *dev) | |||
1444 | 1506 | ||
1445 | error->dovsta = I915_READ(DOVSTA); | 1507 | error->dovsta = I915_READ(DOVSTA); |
1446 | error->isr = I915_READ(ISR); | 1508 | error->isr = I915_READ(ISR); |
1447 | if (OVERLAY_NONPHYSICAL(overlay->dev)) | 1509 | if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) |
1448 | error->base = (long) overlay->reg_bo->gtt_offset; | ||
1449 | else | ||
1450 | error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr; | 1510 | error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr; |
1511 | else | ||
1512 | error->base = (long) overlay->reg_bo->gtt_offset; | ||
1451 | 1513 | ||
1452 | regs = intel_overlay_map_regs_atomic(overlay); | 1514 | regs = intel_overlay_map_regs_atomic(overlay, KM_IRQ0); |
1453 | if (!regs) | 1515 | if (!regs) |
1454 | goto err; | 1516 | goto err; |
1455 | 1517 | ||
1456 | memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers)); | 1518 | memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers)); |
1457 | intel_overlay_unmap_regs_atomic(overlay); | 1519 | intel_overlay_unmap_regs_atomic(overlay, KM_IRQ0, regs); |
1458 | 1520 | ||
1459 | return error; | 1521 | return error; |
1460 | 1522 | ||
@@ -1515,3 +1577,4 @@ intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_s | |||
1515 | P(UVSCALEV); | 1577 | P(UVSCALEV); |
1516 | #undef P | 1578 | #undef P |
1517 | } | 1579 | } |
1580 | #endif | ||
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index e7f5299d9d57..30abe7afc942 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -30,6 +30,8 @@ | |||
30 | 30 | ||
31 | #include "intel_drv.h" | 31 | #include "intel_drv.h" |
32 | 32 | ||
33 | #define PCI_LBPC 0xf4 /* legacy/combination backlight modes */ | ||
34 | |||
33 | void | 35 | void |
34 | intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | 36 | intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, |
35 | struct drm_display_mode *adjusted_mode) | 37 | struct drm_display_mode *adjusted_mode) |
@@ -109,3 +111,110 @@ done: | |||
109 | dev_priv->pch_pf_pos = (x << 16) | y; | 111 | dev_priv->pch_pf_pos = (x << 16) | y; |
110 | dev_priv->pch_pf_size = (width << 16) | height; | 112 | dev_priv->pch_pf_size = (width << 16) | height; |
111 | } | 113 | } |
114 | |||
115 | static int is_backlight_combination_mode(struct drm_device *dev) | ||
116 | { | ||
117 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
118 | |||
119 | if (IS_I965G(dev)) | ||
120 | return I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE; | ||
121 | |||
122 | if (IS_GEN2(dev)) | ||
123 | return I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE; | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | u32 intel_panel_get_max_backlight(struct drm_device *dev) | ||
129 | { | ||
130 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
131 | u32 max; | ||
132 | |||
133 | if (HAS_PCH_SPLIT(dev)) { | ||
134 | max = I915_READ(BLC_PWM_PCH_CTL2) >> 16; | ||
135 | } else { | ||
136 | max = I915_READ(BLC_PWM_CTL); | ||
137 | if (IS_PINEVIEW(dev)) { | ||
138 | max >>= 17; | ||
139 | } else { | ||
140 | max >>= 16; | ||
141 | if (!IS_I965G(dev)) | ||
142 | max &= ~1; | ||
143 | } | ||
144 | |||
145 | if (is_backlight_combination_mode(dev)) | ||
146 | max *= 0xff; | ||
147 | } | ||
148 | |||
149 | if (max == 0) { | ||
150 | /* XXX add code here to query mode clock or hardware clock | ||
151 | * and program max PWM appropriately. | ||
152 | */ | ||
153 | DRM_ERROR("fixme: max PWM is zero.\n"); | ||
154 | max = 1; | ||
155 | } | ||
156 | |||
157 | DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); | ||
158 | return max; | ||
159 | } | ||
160 | |||
161 | u32 intel_panel_get_backlight(struct drm_device *dev) | ||
162 | { | ||
163 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
164 | u32 val; | ||
165 | |||
166 | if (HAS_PCH_SPLIT(dev)) { | ||
167 | val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; | ||
168 | } else { | ||
169 | val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; | ||
170 | if (IS_PINEVIEW(dev)) | ||
171 | val >>= 1; | ||
172 | |||
173 | if (is_backlight_combination_mode(dev)){ | ||
174 | u8 lbpc; | ||
175 | |||
176 | val &= ~1; | ||
177 | pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc); | ||
178 | val *= lbpc; | ||
179 | val >>= 1; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val); | ||
184 | return val; | ||
185 | } | ||
186 | |||
187 | static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level) | ||
188 | { | ||
189 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
190 | u32 val = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; | ||
191 | I915_WRITE(BLC_PWM_CPU_CTL, val | level); | ||
192 | } | ||
193 | |||
194 | void intel_panel_set_backlight(struct drm_device *dev, u32 level) | ||
195 | { | ||
196 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
197 | u32 tmp; | ||
198 | |||
199 | DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); | ||
200 | |||
201 | if (HAS_PCH_SPLIT(dev)) | ||
202 | return intel_pch_panel_set_backlight(dev, level); | ||
203 | |||
204 | if (is_backlight_combination_mode(dev)){ | ||
205 | u32 max = intel_panel_get_max_backlight(dev); | ||
206 | u8 lpbc; | ||
207 | |||
208 | lpbc = level * 0xfe / max + 1; | ||
209 | level /= lpbc; | ||
210 | pci_write_config_byte(dev->pdev, PCI_LBPC, lpbc); | ||
211 | } | ||
212 | |||
213 | tmp = I915_READ(BLC_PWM_CTL); | ||
214 | if (IS_PINEVIEW(dev)) { | ||
215 | tmp &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1); | ||
216 | level <<= 1; | ||
217 | } else | ||
218 | tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK; | ||
219 | I915_WRITE(BLC_PWM_CTL, tmp | level); | ||
220 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index cb3508f78bc3..11bcfc871a0d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -116,6 +116,8 @@ render_ring_flush(struct drm_device *dev, | |||
116 | intel_ring_emit(dev, ring, MI_NOOP); | 116 | intel_ring_emit(dev, ring, MI_NOOP); |
117 | intel_ring_advance(dev, ring); | 117 | intel_ring_advance(dev, ring); |
118 | } | 118 | } |
119 | |||
120 | i915_gem_process_flushing_list(dev, flush_domains, ring); | ||
119 | } | 121 | } |
120 | 122 | ||
121 | static unsigned int render_ring_get_head(struct drm_device *dev, | 123 | static unsigned int render_ring_get_head(struct drm_device *dev, |
@@ -384,6 +386,8 @@ bsd_ring_flush(struct drm_device *dev, | |||
384 | intel_ring_emit(dev, ring, MI_FLUSH); | 386 | intel_ring_emit(dev, ring, MI_FLUSH); |
385 | intel_ring_emit(dev, ring, MI_NOOP); | 387 | intel_ring_emit(dev, ring, MI_NOOP); |
386 | intel_ring_advance(dev, ring); | 388 | intel_ring_advance(dev, ring); |
389 | |||
390 | i915_gem_process_flushing_list(dev, flush_domains, ring); | ||
387 | } | 391 | } |
388 | 392 | ||
389 | static inline unsigned int bsd_ring_get_head(struct drm_device *dev, | 393 | static inline unsigned int bsd_ring_get_head(struct drm_device *dev, |
@@ -801,7 +805,6 @@ struct intel_ring_buffer render_ring = { | |||
801 | .tail = PRB0_TAIL, | 805 | .tail = PRB0_TAIL, |
802 | .start = PRB0_START | 806 | .start = PRB0_START |
803 | }, | 807 | }, |
804 | .ring_flag = I915_EXEC_RENDER, | ||
805 | .size = 32 * PAGE_SIZE, | 808 | .size = 32 * PAGE_SIZE, |
806 | .alignment = PAGE_SIZE, | 809 | .alignment = PAGE_SIZE, |
807 | .virtual_start = NULL, | 810 | .virtual_start = NULL, |
@@ -839,7 +842,6 @@ struct intel_ring_buffer bsd_ring = { | |||
839 | .tail = BSD_RING_TAIL, | 842 | .tail = BSD_RING_TAIL, |
840 | .start = BSD_RING_START | 843 | .start = BSD_RING_START |
841 | }, | 844 | }, |
842 | .ring_flag = I915_EXEC_BSD, | ||
843 | .size = 32 * PAGE_SIZE, | 845 | .size = 32 * PAGE_SIZE, |
844 | .alignment = PAGE_SIZE, | 846 | .alignment = PAGE_SIZE, |
845 | .virtual_start = NULL, | 847 | .virtual_start = NULL, |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 525e7d3edda8..fa5d84f85c26 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -16,7 +16,6 @@ struct intel_ring_buffer { | |||
16 | u32 tail; | 16 | u32 tail; |
17 | u32 start; | 17 | u32 start; |
18 | } regs; | 18 | } regs; |
19 | unsigned int ring_flag; | ||
20 | unsigned long size; | 19 | unsigned long size; |
21 | unsigned int alignment; | 20 | unsigned int alignment; |
22 | void *virtual_start; | 21 | void *virtual_start; |
@@ -83,6 +82,11 @@ struct intel_ring_buffer { | |||
83 | */ | 82 | */ |
84 | struct list_head request_list; | 83 | struct list_head request_list; |
85 | 84 | ||
85 | /** | ||
86 | * Do we have some not yet emitted requests outstanding? | ||
87 | */ | ||
88 | bool outstanding_lazy_request; | ||
89 | |||
86 | wait_queue_head_t irq_queue; | 90 | wait_queue_head_t irq_queue; |
87 | drm_local_map_t map; | 91 | drm_local_map_t map; |
88 | }; | 92 | }; |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index e8e902d614ed..ba058e600ce7 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -65,6 +65,7 @@ static const char *tv_format_names[] = { | |||
65 | struct intel_sdvo { | 65 | struct intel_sdvo { |
66 | struct intel_encoder base; | 66 | struct intel_encoder base; |
67 | 67 | ||
68 | struct i2c_adapter *i2c; | ||
68 | u8 slave_addr; | 69 | u8 slave_addr; |
69 | 70 | ||
70 | /* Register for the SDVO device: SDVOB or SDVOC */ | 71 | /* Register for the SDVO device: SDVOB or SDVOC */ |
@@ -106,16 +107,12 @@ struct intel_sdvo { | |||
106 | bool is_hdmi; | 107 | bool is_hdmi; |
107 | 108 | ||
108 | /** | 109 | /** |
109 | * This is set if we detect output of sdvo device as LVDS. | 110 | * This is set if we detect output of sdvo device as LVDS and |
111 | * have a valid fixed mode to use with the panel. | ||
110 | */ | 112 | */ |
111 | bool is_lvds; | 113 | bool is_lvds; |
112 | 114 | ||
113 | /** | 115 | /** |
114 | * This is sdvo flags for input timing. | ||
115 | */ | ||
116 | uint8_t sdvo_flags; | ||
117 | |||
118 | /** | ||
119 | * This is sdvo fixed pannel mode pointer | 116 | * This is sdvo fixed pannel mode pointer |
120 | */ | 117 | */ |
121 | struct drm_display_mode *sdvo_lvds_fixed_mode; | 118 | struct drm_display_mode *sdvo_lvds_fixed_mode; |
@@ -129,9 +126,8 @@ struct intel_sdvo { | |||
129 | /* DDC bus used by this SDVO encoder */ | 126 | /* DDC bus used by this SDVO encoder */ |
130 | uint8_t ddc_bus; | 127 | uint8_t ddc_bus; |
131 | 128 | ||
132 | /* Mac mini hack -- use the same DDC as the analog connector */ | 129 | /* Input timings for adjusted_mode */ |
133 | struct i2c_adapter *analog_ddc_bus; | 130 | struct intel_sdvo_dtd input_dtd; |
134 | |||
135 | }; | 131 | }; |
136 | 132 | ||
137 | struct intel_sdvo_connector { | 133 | struct intel_sdvo_connector { |
@@ -186,9 +182,15 @@ struct intel_sdvo_connector { | |||
186 | u32 cur_dot_crawl, max_dot_crawl; | 182 | u32 cur_dot_crawl, max_dot_crawl; |
187 | }; | 183 | }; |
188 | 184 | ||
189 | static struct intel_sdvo *enc_to_intel_sdvo(struct drm_encoder *encoder) | 185 | static struct intel_sdvo *to_intel_sdvo(struct drm_encoder *encoder) |
190 | { | 186 | { |
191 | return container_of(enc_to_intel_encoder(encoder), struct intel_sdvo, base); | 187 | return container_of(encoder, struct intel_sdvo, base.base); |
188 | } | ||
189 | |||
190 | static struct intel_sdvo *intel_attached_sdvo(struct drm_connector *connector) | ||
191 | { | ||
192 | return container_of(intel_attached_encoder(connector), | ||
193 | struct intel_sdvo, base); | ||
192 | } | 194 | } |
193 | 195 | ||
194 | static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) | 196 | static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) |
@@ -213,7 +215,7 @@ intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, | |||
213 | */ | 215 | */ |
214 | static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) | 216 | static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) |
215 | { | 217 | { |
216 | struct drm_device *dev = intel_sdvo->base.enc.dev; | 218 | struct drm_device *dev = intel_sdvo->base.base.dev; |
217 | struct drm_i915_private *dev_priv = dev->dev_private; | 219 | struct drm_i915_private *dev_priv = dev->dev_private; |
218 | u32 bval = val, cval = val; | 220 | u32 bval = val, cval = val; |
219 | int i; | 221 | int i; |
@@ -263,7 +265,7 @@ static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch) | |||
263 | }; | 265 | }; |
264 | int ret; | 266 | int ret; |
265 | 267 | ||
266 | if ((ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 2)) == 2) | 268 | if ((ret = i2c_transfer(intel_sdvo->i2c, msgs, 2)) == 2) |
267 | { | 269 | { |
268 | *ch = buf[0]; | 270 | *ch = buf[0]; |
269 | return true; | 271 | return true; |
@@ -285,7 +287,7 @@ static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr, u8 ch | |||
285 | } | 287 | } |
286 | }; | 288 | }; |
287 | 289 | ||
288 | return i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 1) == 1; | 290 | return i2c_transfer(intel_sdvo->i2c, msgs, 1) == 1; |
289 | } | 291 | } |
290 | 292 | ||
291 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} | 293 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} |
@@ -458,54 +460,55 @@ static const char *cmd_status_names[] = { | |||
458 | "Scaling not supported" | 460 | "Scaling not supported" |
459 | }; | 461 | }; |
460 | 462 | ||
461 | static void intel_sdvo_debug_response(struct intel_sdvo *intel_sdvo, | 463 | static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, |
462 | void *response, int response_len, | 464 | void *response, int response_len) |
463 | u8 status) | ||
464 | { | 465 | { |
466 | u8 retry = 5; | ||
467 | u8 status; | ||
465 | int i; | 468 | int i; |
466 | 469 | ||
470 | /* | ||
471 | * The documentation states that all commands will be | ||
472 | * processed within 15µs, and that we need only poll | ||
473 | * the status byte a maximum of 3 times in order for the | ||
474 | * command to be complete. | ||
475 | * | ||
476 | * Check 5 times in case the hardware failed to read the docs. | ||
477 | */ | ||
478 | do { | ||
479 | if (!intel_sdvo_read_byte(intel_sdvo, | ||
480 | SDVO_I2C_CMD_STATUS, | ||
481 | &status)) | ||
482 | return false; | ||
483 | } while (status == SDVO_CMD_STATUS_PENDING && --retry); | ||
484 | |||
467 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo)); | 485 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo)); |
468 | for (i = 0; i < response_len; i++) | ||
469 | DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); | ||
470 | for (; i < 8; i++) | ||
471 | DRM_LOG_KMS(" "); | ||
472 | if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) | 486 | if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) |
473 | DRM_LOG_KMS("(%s)", cmd_status_names[status]); | 487 | DRM_LOG_KMS("(%s)", cmd_status_names[status]); |
474 | else | 488 | else |
475 | DRM_LOG_KMS("(??? %d)", status); | 489 | DRM_LOG_KMS("(??? %d)", status); |
476 | DRM_LOG_KMS("\n"); | ||
477 | } | ||
478 | 490 | ||
479 | static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, | 491 | if (status != SDVO_CMD_STATUS_SUCCESS) |
480 | void *response, int response_len) | 492 | goto log_fail; |
481 | { | ||
482 | int i; | ||
483 | u8 status; | ||
484 | u8 retry = 50; | ||
485 | |||
486 | while (retry--) { | ||
487 | /* Read the command response */ | ||
488 | for (i = 0; i < response_len; i++) { | ||
489 | if (!intel_sdvo_read_byte(intel_sdvo, | ||
490 | SDVO_I2C_RETURN_0 + i, | ||
491 | &((u8 *)response)[i])) | ||
492 | return false; | ||
493 | } | ||
494 | 493 | ||
495 | /* read the return status */ | 494 | /* Read the command response */ |
496 | if (!intel_sdvo_read_byte(intel_sdvo, SDVO_I2C_CMD_STATUS, | 495 | for (i = 0; i < response_len; i++) { |
497 | &status)) | 496 | if (!intel_sdvo_read_byte(intel_sdvo, |
498 | return false; | 497 | SDVO_I2C_RETURN_0 + i, |
498 | &((u8 *)response)[i])) | ||
499 | goto log_fail; | ||
500 | DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); | ||
501 | } | ||
499 | 502 | ||
500 | intel_sdvo_debug_response(intel_sdvo, response, response_len, | 503 | for (; i < 8; i++) |
501 | status); | 504 | DRM_LOG_KMS(" "); |
502 | if (status != SDVO_CMD_STATUS_PENDING) | 505 | DRM_LOG_KMS("\n"); |
503 | break; | ||
504 | 506 | ||
505 | mdelay(50); | 507 | return true; |
506 | } | ||
507 | 508 | ||
508 | return status == SDVO_CMD_STATUS_SUCCESS; | 509 | log_fail: |
510 | DRM_LOG_KMS("\n"); | ||
511 | return false; | ||
509 | } | 512 | } |
510 | 513 | ||
511 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | 514 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) |
@@ -525,8 +528,8 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | |||
525 | * another I2C transaction after issuing the DDC bus switch, it will be | 528 | * another I2C transaction after issuing the DDC bus switch, it will be |
526 | * switched to the internal SDVO register. | 529 | * switched to the internal SDVO register. |
527 | */ | 530 | */ |
528 | static void intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, | 531 | static int intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, |
529 | u8 target) | 532 | u8 target) |
530 | { | 533 | { |
531 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; | 534 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; |
532 | struct i2c_msg msgs[] = { | 535 | struct i2c_msg msgs[] = { |
@@ -552,9 +555,10 @@ static void intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, | |||
552 | }; | 555 | }; |
553 | 556 | ||
554 | intel_sdvo_debug_write(intel_sdvo, SDVO_CMD_SET_CONTROL_BUS_SWITCH, | 557 | intel_sdvo_debug_write(intel_sdvo, SDVO_CMD_SET_CONTROL_BUS_SWITCH, |
555 | &target, 1); | 558 | &target, 1); |
556 | /* write the DDC switch command argument */ | 559 | /* write the DDC switch command argument */ |
557 | intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0, target); | 560 | if (!intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0, target)) |
561 | return -EIO; | ||
558 | 562 | ||
559 | out_buf[0] = SDVO_I2C_OPCODE; | 563 | out_buf[0] = SDVO_I2C_OPCODE; |
560 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; | 564 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; |
@@ -563,18 +567,21 @@ static void intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, | |||
563 | ret_value[0] = 0; | 567 | ret_value[0] = 0; |
564 | ret_value[1] = 0; | 568 | ret_value[1] = 0; |
565 | 569 | ||
566 | ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 3); | 570 | ret = i2c_transfer(intel_sdvo->i2c, msgs, 3); |
571 | if (ret < 0) | ||
572 | return ret; | ||
567 | if (ret != 3) { | 573 | if (ret != 3) { |
568 | /* failure in I2C transfer */ | 574 | /* failure in I2C transfer */ |
569 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); | 575 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); |
570 | return; | 576 | return -EIO; |
571 | } | 577 | } |
572 | if (ret_value[0] != SDVO_CMD_STATUS_SUCCESS) { | 578 | if (ret_value[0] != SDVO_CMD_STATUS_SUCCESS) { |
573 | DRM_DEBUG_KMS("DDC switch command returns response %d\n", | 579 | DRM_DEBUG_KMS("DDC switch command returns response %d\n", |
574 | ret_value[0]); | 580 | ret_value[0]); |
575 | return; | 581 | return -EIO; |
576 | } | 582 | } |
577 | return; | 583 | |
584 | return 0; | ||
578 | } | 585 | } |
579 | 586 | ||
580 | static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len) | 587 | static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len) |
@@ -1022,8 +1029,6 @@ intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, | |||
1022 | struct drm_display_mode *mode, | 1029 | struct drm_display_mode *mode, |
1023 | struct drm_display_mode *adjusted_mode) | 1030 | struct drm_display_mode *adjusted_mode) |
1024 | { | 1031 | { |
1025 | struct intel_sdvo_dtd input_dtd; | ||
1026 | |||
1027 | /* Reset the input timing to the screen. Assume always input 0. */ | 1032 | /* Reset the input timing to the screen. Assume always input 0. */ |
1028 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 1033 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
1029 | return false; | 1034 | return false; |
@@ -1035,14 +1040,12 @@ intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, | |||
1035 | return false; | 1040 | return false; |
1036 | 1041 | ||
1037 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, | 1042 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, |
1038 | &input_dtd)) | 1043 | &intel_sdvo->input_dtd)) |
1039 | return false; | 1044 | return false; |
1040 | 1045 | ||
1041 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 1046 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &intel_sdvo->input_dtd); |
1042 | intel_sdvo->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
1043 | 1047 | ||
1044 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1048 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
1045 | mode->clock = adjusted_mode->clock; | ||
1046 | return true; | 1049 | return true; |
1047 | } | 1050 | } |
1048 | 1051 | ||
@@ -1050,7 +1053,8 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1050 | struct drm_display_mode *mode, | 1053 | struct drm_display_mode *mode, |
1051 | struct drm_display_mode *adjusted_mode) | 1054 | struct drm_display_mode *adjusted_mode) |
1052 | { | 1055 | { |
1053 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | 1056 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); |
1057 | int multiplier; | ||
1054 | 1058 | ||
1055 | /* We need to construct preferred input timings based on our | 1059 | /* We need to construct preferred input timings based on our |
1056 | * output timings. To do that, we have to set the output | 1060 | * output timings. To do that, we have to set the output |
@@ -1065,10 +1069,8 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1065 | mode, | 1069 | mode, |
1066 | adjusted_mode); | 1070 | adjusted_mode); |
1067 | } else if (intel_sdvo->is_lvds) { | 1071 | } else if (intel_sdvo->is_lvds) { |
1068 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0); | ||
1069 | |||
1070 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, | 1072 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, |
1071 | intel_sdvo->sdvo_lvds_fixed_mode)) | 1073 | intel_sdvo->sdvo_lvds_fixed_mode)) |
1072 | return false; | 1074 | return false; |
1073 | 1075 | ||
1074 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, | 1076 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, |
@@ -1077,9 +1079,10 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1077 | } | 1079 | } |
1078 | 1080 | ||
1079 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | 1081 | /* Make the CRTC code factor in the SDVO pixel multiplier. The |
1080 | * SDVO device will be told of the multiplier during mode_set. | 1082 | * SDVO device will factor out the multiplier during mode_set. |
1081 | */ | 1083 | */ |
1082 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | 1084 | multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode); |
1085 | intel_mode_set_pixel_multiplier(adjusted_mode, multiplier); | ||
1083 | 1086 | ||
1084 | return true; | 1087 | return true; |
1085 | } | 1088 | } |
@@ -1092,11 +1095,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1092 | struct drm_i915_private *dev_priv = dev->dev_private; | 1095 | struct drm_i915_private *dev_priv = dev->dev_private; |
1093 | struct drm_crtc *crtc = encoder->crtc; | 1096 | struct drm_crtc *crtc = encoder->crtc; |
1094 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1097 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1095 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | 1098 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); |
1096 | u32 sdvox = 0; | 1099 | u32 sdvox; |
1097 | int sdvo_pixel_multiply, rate; | ||
1098 | struct intel_sdvo_in_out_map in_out; | 1100 | struct intel_sdvo_in_out_map in_out; |
1099 | struct intel_sdvo_dtd input_dtd; | 1101 | struct intel_sdvo_dtd input_dtd; |
1102 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | ||
1103 | int rate; | ||
1100 | 1104 | ||
1101 | if (!mode) | 1105 | if (!mode) |
1102 | return; | 1106 | return; |
@@ -1114,28 +1118,23 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1114 | SDVO_CMD_SET_IN_OUT_MAP, | 1118 | SDVO_CMD_SET_IN_OUT_MAP, |
1115 | &in_out, sizeof(in_out)); | 1119 | &in_out, sizeof(in_out)); |
1116 | 1120 | ||
1117 | if (intel_sdvo->is_hdmi) { | 1121 | /* Set the output timings to the screen */ |
1118 | if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode)) | 1122 | if (!intel_sdvo_set_target_output(intel_sdvo, |
1119 | return; | 1123 | intel_sdvo->attached_output)) |
1120 | 1124 | return; | |
1121 | sdvox |= SDVO_AUDIO_ENABLE; | ||
1122 | } | ||
1123 | 1125 | ||
1124 | /* We have tried to get input timing in mode_fixup, and filled into | 1126 | /* We have tried to get input timing in mode_fixup, and filled into |
1125 | adjusted_mode */ | 1127 | * adjusted_mode. |
1126 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | ||
1127 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) | ||
1128 | input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags; | ||
1129 | |||
1130 | /* If it's a TV, we already set the output timing in mode_fixup. | ||
1131 | * Otherwise, the output timing is equal to the input timing. | ||
1132 | */ | 1128 | */ |
1133 | if (!intel_sdvo->is_tv && !intel_sdvo->is_lvds) { | 1129 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { |
1130 | input_dtd = intel_sdvo->input_dtd; | ||
1131 | } else { | ||
1134 | /* Set the output timing to the screen */ | 1132 | /* Set the output timing to the screen */ |
1135 | if (!intel_sdvo_set_target_output(intel_sdvo, | 1133 | if (!intel_sdvo_set_target_output(intel_sdvo, |
1136 | intel_sdvo->attached_output)) | 1134 | intel_sdvo->attached_output)) |
1137 | return; | 1135 | return; |
1138 | 1136 | ||
1137 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | ||
1139 | (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); | 1138 | (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); |
1140 | } | 1139 | } |
1141 | 1140 | ||
@@ -1143,31 +1142,18 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1143 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 1142 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
1144 | return; | 1143 | return; |
1145 | 1144 | ||
1146 | if (intel_sdvo->is_tv) { | 1145 | if (intel_sdvo->is_hdmi && |
1147 | if (!intel_sdvo_set_tv_format(intel_sdvo)) | 1146 | !intel_sdvo_set_avi_infoframe(intel_sdvo, mode)) |
1148 | return; | 1147 | return; |
1149 | } | ||
1150 | 1148 | ||
1151 | /* We would like to use intel_sdvo_create_preferred_input_timing() to | 1149 | if (intel_sdvo->is_tv && |
1152 | * provide the device with a timing it can support, if it supports that | 1150 | !intel_sdvo_set_tv_format(intel_sdvo)) |
1153 | * feature. However, presumably we would need to adjust the CRTC to | 1151 | return; |
1154 | * output the preferred timing, and we don't support that currently. | ||
1155 | */ | ||
1156 | #if 0 | ||
1157 | success = intel_sdvo_create_preferred_input_timing(encoder, clock, | ||
1158 | width, height); | ||
1159 | if (success) { | ||
1160 | struct intel_sdvo_dtd *input_dtd; | ||
1161 | 1152 | ||
1162 | intel_sdvo_get_preferred_input_timing(encoder, &input_dtd); | ||
1163 | intel_sdvo_set_input_timing(encoder, &input_dtd); | ||
1164 | } | ||
1165 | #else | ||
1166 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); | 1153 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); |
1167 | #endif | ||
1168 | 1154 | ||
1169 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); | 1155 | switch (pixel_multiplier) { |
1170 | switch (sdvo_pixel_multiply) { | 1156 | default: |
1171 | case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; | 1157 | case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; |
1172 | case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; | 1158 | case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; |
1173 | case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; | 1159 | case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; |
@@ -1177,13 +1163,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1177 | 1163 | ||
1178 | /* Set the SDVO control regs. */ | 1164 | /* Set the SDVO control regs. */ |
1179 | if (IS_I965G(dev)) { | 1165 | if (IS_I965G(dev)) { |
1180 | sdvox |= SDVO_BORDER_ENABLE; | 1166 | sdvox = SDVO_BORDER_ENABLE; |
1181 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 1167 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
1182 | sdvox |= SDVO_VSYNC_ACTIVE_HIGH; | 1168 | sdvox |= SDVO_VSYNC_ACTIVE_HIGH; |
1183 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 1169 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
1184 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | 1170 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; |
1185 | } else { | 1171 | } else { |
1186 | sdvox |= I915_READ(intel_sdvo->sdvo_reg); | 1172 | sdvox = I915_READ(intel_sdvo->sdvo_reg); |
1187 | switch (intel_sdvo->sdvo_reg) { | 1173 | switch (intel_sdvo->sdvo_reg) { |
1188 | case SDVOB: | 1174 | case SDVOB: |
1189 | sdvox &= SDVOB_PRESERVE_MASK; | 1175 | sdvox &= SDVOB_PRESERVE_MASK; |
@@ -1196,16 +1182,18 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1196 | } | 1182 | } |
1197 | if (intel_crtc->pipe == 1) | 1183 | if (intel_crtc->pipe == 1) |
1198 | sdvox |= SDVO_PIPE_B_SELECT; | 1184 | sdvox |= SDVO_PIPE_B_SELECT; |
1185 | if (intel_sdvo->is_hdmi) | ||
1186 | sdvox |= SDVO_AUDIO_ENABLE; | ||
1199 | 1187 | ||
1200 | if (IS_I965G(dev)) { | 1188 | if (IS_I965G(dev)) { |
1201 | /* done in crtc_mode_set as the dpll_md reg must be written early */ | 1189 | /* done in crtc_mode_set as the dpll_md reg must be written early */ |
1202 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { | 1190 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { |
1203 | /* done in crtc_mode_set as it lives inside the dpll register */ | 1191 | /* done in crtc_mode_set as it lives inside the dpll register */ |
1204 | } else { | 1192 | } else { |
1205 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1193 | sdvox |= (pixel_multiplier - 1) << SDVO_PORT_MULTIPLY_SHIFT; |
1206 | } | 1194 | } |
1207 | 1195 | ||
1208 | if (intel_sdvo->sdvo_flags & SDVO_NEED_TO_STALL) | 1196 | if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL) |
1209 | sdvox |= SDVO_STALL_SELECT; | 1197 | sdvox |= SDVO_STALL_SELECT; |
1210 | intel_sdvo_write_sdvox(intel_sdvo, sdvox); | 1198 | intel_sdvo_write_sdvox(intel_sdvo, sdvox); |
1211 | } | 1199 | } |
@@ -1214,7 +1202,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
1214 | { | 1202 | { |
1215 | struct drm_device *dev = encoder->dev; | 1203 | struct drm_device *dev = encoder->dev; |
1216 | struct drm_i915_private *dev_priv = dev->dev_private; | 1204 | struct drm_i915_private *dev_priv = dev->dev_private; |
1217 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | 1205 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); |
1218 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 1206 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
1219 | u32 temp; | 1207 | u32 temp; |
1220 | 1208 | ||
@@ -1260,8 +1248,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
1260 | static int intel_sdvo_mode_valid(struct drm_connector *connector, | 1248 | static int intel_sdvo_mode_valid(struct drm_connector *connector, |
1261 | struct drm_display_mode *mode) | 1249 | struct drm_display_mode *mode) |
1262 | { | 1250 | { |
1263 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1251 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
1264 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | ||
1265 | 1252 | ||
1266 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 1253 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
1267 | return MODE_NO_DBLESCAN; | 1254 | return MODE_NO_DBLESCAN; |
@@ -1389,22 +1376,39 @@ intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo) | |||
1389 | return (caps > 1); | 1376 | return (caps > 1); |
1390 | } | 1377 | } |
1391 | 1378 | ||
1379 | static struct edid * | ||
1380 | intel_sdvo_get_edid(struct drm_connector *connector, int ddc) | ||
1381 | { | ||
1382 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); | ||
1383 | int ret; | ||
1384 | |||
1385 | ret = intel_sdvo_set_control_bus_switch(intel_sdvo, ddc); | ||
1386 | if (ret) | ||
1387 | return NULL; | ||
1388 | |||
1389 | return drm_get_edid(connector, intel_sdvo->i2c); | ||
1390 | } | ||
1391 | |||
1392 | static struct drm_connector * | 1392 | static struct drm_connector * |
1393 | intel_find_analog_connector(struct drm_device *dev) | 1393 | intel_find_analog_connector(struct drm_device *dev) |
1394 | { | 1394 | { |
1395 | struct drm_connector *connector; | 1395 | struct drm_connector *connector; |
1396 | struct drm_encoder *encoder; | 1396 | struct intel_sdvo *encoder; |
1397 | struct intel_sdvo *intel_sdvo; | 1397 | |
1398 | 1398 | list_for_each_entry(encoder, | |
1399 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1399 | &dev->mode_config.encoder_list, |
1400 | intel_sdvo = enc_to_intel_sdvo(encoder); | 1400 | base.base.head) { |
1401 | if (intel_sdvo->base.type == INTEL_OUTPUT_ANALOG) { | 1401 | if (encoder->base.type == INTEL_OUTPUT_ANALOG) { |
1402 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1402 | list_for_each_entry(connector, |
1403 | if (encoder == intel_attached_encoder(connector)) | 1403 | &dev->mode_config.connector_list, |
1404 | head) { | ||
1405 | if (&encoder->base == | ||
1406 | intel_attached_encoder(connector)) | ||
1404 | return connector; | 1407 | return connector; |
1405 | } | 1408 | } |
1406 | } | 1409 | } |
1407 | } | 1410 | } |
1411 | |||
1408 | return NULL; | 1412 | return NULL; |
1409 | } | 1413 | } |
1410 | 1414 | ||
@@ -1424,65 +1428,65 @@ intel_analog_is_connected(struct drm_device *dev) | |||
1424 | return true; | 1428 | return true; |
1425 | } | 1429 | } |
1426 | 1430 | ||
1431 | /* Mac mini hack -- use the same DDC as the analog connector */ | ||
1432 | static struct edid * | ||
1433 | intel_sdvo_get_analog_edid(struct drm_connector *connector) | ||
1434 | { | ||
1435 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | ||
1436 | |||
1437 | if (!intel_analog_is_connected(connector->dev)) | ||
1438 | return NULL; | ||
1439 | |||
1440 | return drm_get_edid(connector, &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); | ||
1441 | } | ||
1442 | |||
1427 | enum drm_connector_status | 1443 | enum drm_connector_status |
1428 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | 1444 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) |
1429 | { | 1445 | { |
1430 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1446 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
1431 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | 1447 | enum drm_connector_status status; |
1432 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); | 1448 | struct edid *edid; |
1433 | enum drm_connector_status status = connector_status_connected; | ||
1434 | struct edid *edid = NULL; | ||
1435 | 1449 | ||
1436 | edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus); | 1450 | edid = intel_sdvo_get_edid(connector, intel_sdvo->ddc_bus); |
1437 | 1451 | ||
1438 | /* This is only applied to SDVO cards with multiple outputs */ | ||
1439 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) { | 1452 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) { |
1440 | uint8_t saved_ddc, temp_ddc; | 1453 | u8 ddc; |
1441 | saved_ddc = intel_sdvo->ddc_bus; | 1454 | |
1442 | temp_ddc = intel_sdvo->ddc_bus >> 1; | ||
1443 | /* | 1455 | /* |
1444 | * Don't use the 1 as the argument of DDC bus switch to get | 1456 | * Don't use the 1 as the argument of DDC bus switch to get |
1445 | * the EDID. It is used for SDVO SPD ROM. | 1457 | * the EDID. It is used for SDVO SPD ROM. |
1446 | */ | 1458 | */ |
1447 | while(temp_ddc > 1) { | 1459 | for (ddc = intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) { |
1448 | intel_sdvo->ddc_bus = temp_ddc; | 1460 | edid = intel_sdvo_get_edid(connector, ddc); |
1449 | edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus); | ||
1450 | if (edid) { | 1461 | if (edid) { |
1451 | /* | 1462 | /* |
1452 | * When we can get the EDID, maybe it is the | 1463 | * If we found the EDID on the other bus, |
1453 | * correct DDC bus. Update it. | 1464 | * assume that is the correct DDC bus. |
1454 | */ | 1465 | */ |
1455 | intel_sdvo->ddc_bus = temp_ddc; | 1466 | intel_sdvo->ddc_bus = ddc; |
1456 | break; | 1467 | break; |
1457 | } | 1468 | } |
1458 | temp_ddc >>= 1; | ||
1459 | } | 1469 | } |
1460 | if (edid == NULL) | ||
1461 | intel_sdvo->ddc_bus = saved_ddc; | ||
1462 | } | 1470 | } |
1463 | /* when there is no edid and no monitor is connected with VGA | 1471 | |
1464 | * port, try to use the CRT ddc to read the EDID for DVI-connector | 1472 | /* |
1473 | * When there is no edid and no monitor is connected with VGA | ||
1474 | * port, try to use the CRT ddc to read the EDID for DVI-connector. | ||
1465 | */ | 1475 | */ |
1466 | if (edid == NULL && intel_sdvo->analog_ddc_bus && | 1476 | if (edid == NULL) |
1467 | !intel_analog_is_connected(connector->dev)) | 1477 | edid = intel_sdvo_get_analog_edid(connector); |
1468 | edid = drm_get_edid(connector, intel_sdvo->analog_ddc_bus); | ||
1469 | 1478 | ||
1479 | status = connector_status_unknown; | ||
1470 | if (edid != NULL) { | 1480 | if (edid != NULL) { |
1471 | bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); | ||
1472 | bool need_digital = !!(intel_sdvo_connector->output_flag & SDVO_TMDS_MASK); | ||
1473 | |||
1474 | /* DDC bus is shared, match EDID to connector type */ | 1481 | /* DDC bus is shared, match EDID to connector type */ |
1475 | if (is_digital && need_digital) | 1482 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
1483 | status = connector_status_connected; | ||
1476 | intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid); | 1484 | intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid); |
1477 | else if (is_digital != need_digital) | 1485 | } |
1478 | status = connector_status_disconnected; | ||
1479 | |||
1480 | connector->display_info.raw_edid = NULL; | 1486 | connector->display_info.raw_edid = NULL; |
1481 | } else | 1487 | kfree(edid); |
1482 | status = connector_status_disconnected; | 1488 | } |
1483 | 1489 | ||
1484 | kfree(edid); | ||
1485 | |||
1486 | return status; | 1490 | return status; |
1487 | } | 1491 | } |
1488 | 1492 | ||
@@ -1490,8 +1494,7 @@ static enum drm_connector_status | |||
1490 | intel_sdvo_detect(struct drm_connector *connector, bool force) | 1494 | intel_sdvo_detect(struct drm_connector *connector, bool force) |
1491 | { | 1495 | { |
1492 | uint16_t response; | 1496 | uint16_t response; |
1493 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1497 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
1494 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | ||
1495 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); | 1498 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1496 | enum drm_connector_status ret; | 1499 | enum drm_connector_status ret; |
1497 | 1500 | ||
@@ -1538,12 +1541,11 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
1538 | 1541 | ||
1539 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1542 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
1540 | { | 1543 | { |
1541 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1544 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
1542 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | 1545 | struct edid *edid; |
1543 | int num_modes; | ||
1544 | 1546 | ||
1545 | /* set the bus switch and get the modes */ | 1547 | /* set the bus switch and get the modes */ |
1546 | num_modes = intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus); | 1548 | edid = intel_sdvo_get_edid(connector, intel_sdvo->ddc_bus); |
1547 | 1549 | ||
1548 | /* | 1550 | /* |
1549 | * Mac mini hack. On this device, the DVI-I connector shares one DDC | 1551 | * Mac mini hack. On this device, the DVI-I connector shares one DDC |
@@ -1551,12 +1553,14 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
1551 | * DDC fails, check to see if the analog output is disconnected, in | 1553 | * DDC fails, check to see if the analog output is disconnected, in |
1552 | * which case we'll look there for the digital DDC data. | 1554 | * which case we'll look there for the digital DDC data. |
1553 | */ | 1555 | */ |
1554 | if (num_modes == 0 && | 1556 | if (edid == NULL) |
1555 | intel_sdvo->analog_ddc_bus && | 1557 | edid = intel_sdvo_get_analog_edid(connector); |
1556 | !intel_analog_is_connected(connector->dev)) { | 1558 | |
1557 | /* Switch to the analog ddc bus and try that | 1559 | if (edid != NULL) { |
1558 | */ | 1560 | drm_mode_connector_update_edid_property(connector, edid); |
1559 | (void) intel_ddc_get_modes(connector, intel_sdvo->analog_ddc_bus); | 1561 | drm_add_edid_modes(connector, edid); |
1562 | connector->display_info.raw_edid = NULL; | ||
1563 | kfree(edid); | ||
1560 | } | 1564 | } |
1561 | } | 1565 | } |
1562 | 1566 | ||
@@ -1627,8 +1631,7 @@ struct drm_display_mode sdvo_tv_modes[] = { | |||
1627 | 1631 | ||
1628 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | 1632 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) |
1629 | { | 1633 | { |
1630 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1634 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
1631 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | ||
1632 | struct intel_sdvo_sdtv_resolution_request tv_res; | 1635 | struct intel_sdvo_sdtv_resolution_request tv_res; |
1633 | uint32_t reply = 0, format_map = 0; | 1636 | uint32_t reply = 0, format_map = 0; |
1634 | int i; | 1637 | int i; |
@@ -1662,8 +1665,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1662 | 1665 | ||
1663 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1666 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
1664 | { | 1667 | { |
1665 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1668 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
1666 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | ||
1667 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1669 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1668 | struct drm_display_mode *newmode; | 1670 | struct drm_display_mode *newmode; |
1669 | 1671 | ||
@@ -1672,7 +1674,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1672 | * Assume that the preferred modes are | 1674 | * Assume that the preferred modes are |
1673 | * arranged in priority order. | 1675 | * arranged in priority order. |
1674 | */ | 1676 | */ |
1675 | intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus); | 1677 | intel_ddc_get_modes(connector, intel_sdvo->i2c); |
1676 | if (list_empty(&connector->probed_modes) == false) | 1678 | if (list_empty(&connector->probed_modes) == false) |
1677 | goto end; | 1679 | goto end; |
1678 | 1680 | ||
@@ -1693,6 +1695,10 @@ end: | |||
1693 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | 1695 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { |
1694 | intel_sdvo->sdvo_lvds_fixed_mode = | 1696 | intel_sdvo->sdvo_lvds_fixed_mode = |
1695 | drm_mode_duplicate(connector->dev, newmode); | 1697 | drm_mode_duplicate(connector->dev, newmode); |
1698 | |||
1699 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, | ||
1700 | 0); | ||
1701 | |||
1696 | intel_sdvo->is_lvds = true; | 1702 | intel_sdvo->is_lvds = true; |
1697 | break; | 1703 | break; |
1698 | } | 1704 | } |
@@ -1775,8 +1781,7 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1775 | struct drm_property *property, | 1781 | struct drm_property *property, |
1776 | uint64_t val) | 1782 | uint64_t val) |
1777 | { | 1783 | { |
1778 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1784 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); |
1779 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | ||
1780 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); | 1785 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1781 | uint16_t temp_value; | 1786 | uint16_t temp_value; |
1782 | uint8_t cmd; | 1787 | uint8_t cmd; |
@@ -1879,9 +1884,8 @@ set_value: | |||
1879 | 1884 | ||
1880 | 1885 | ||
1881 | done: | 1886 | done: |
1882 | if (encoder->crtc) { | 1887 | if (intel_sdvo->base.base.crtc) { |
1883 | struct drm_crtc *crtc = encoder->crtc; | 1888 | struct drm_crtc *crtc = intel_sdvo->base.base.crtc; |
1884 | |||
1885 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, | 1889 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, |
1886 | crtc->y, crtc->fb); | 1890 | crtc->y, crtc->fb); |
1887 | } | 1891 | } |
@@ -1909,15 +1913,12 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | |||
1909 | static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = { | 1913 | static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = { |
1910 | .get_modes = intel_sdvo_get_modes, | 1914 | .get_modes = intel_sdvo_get_modes, |
1911 | .mode_valid = intel_sdvo_mode_valid, | 1915 | .mode_valid = intel_sdvo_mode_valid, |
1912 | .best_encoder = intel_attached_encoder, | 1916 | .best_encoder = intel_best_encoder, |
1913 | }; | 1917 | }; |
1914 | 1918 | ||
1915 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) | 1919 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) |
1916 | { | 1920 | { |
1917 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | 1921 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); |
1918 | |||
1919 | if (intel_sdvo->analog_ddc_bus) | ||
1920 | intel_i2c_destroy(intel_sdvo->analog_ddc_bus); | ||
1921 | 1922 | ||
1922 | if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) | 1923 | if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) |
1923 | drm_mode_destroy(encoder->dev, | 1924 | drm_mode_destroy(encoder->dev, |
@@ -1999,45 +2000,6 @@ intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device) | |||
1999 | &intel_sdvo->is_hdmi, 1); | 2000 | &intel_sdvo->is_hdmi, 1); |
2000 | } | 2001 | } |
2001 | 2002 | ||
2002 | static struct intel_sdvo * | ||
2003 | intel_sdvo_chan_to_intel_sdvo(struct intel_i2c_chan *chan) | ||
2004 | { | ||
2005 | struct drm_device *dev = chan->drm_dev; | ||
2006 | struct drm_encoder *encoder; | ||
2007 | |||
2008 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
2009 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | ||
2010 | if (intel_sdvo->base.ddc_bus == &chan->adapter) | ||
2011 | return intel_sdvo; | ||
2012 | } | ||
2013 | |||
2014 | return NULL; | ||
2015 | } | ||
2016 | |||
2017 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | ||
2018 | struct i2c_msg msgs[], int num) | ||
2019 | { | ||
2020 | struct intel_sdvo *intel_sdvo; | ||
2021 | struct i2c_algo_bit_data *algo_data; | ||
2022 | const struct i2c_algorithm *algo; | ||
2023 | |||
2024 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; | ||
2025 | intel_sdvo = | ||
2026 | intel_sdvo_chan_to_intel_sdvo((struct intel_i2c_chan *) | ||
2027 | (algo_data->data)); | ||
2028 | if (intel_sdvo == NULL) | ||
2029 | return -EINVAL; | ||
2030 | |||
2031 | algo = intel_sdvo->base.i2c_bus->algo; | ||
2032 | |||
2033 | intel_sdvo_set_control_bus_switch(intel_sdvo, intel_sdvo->ddc_bus); | ||
2034 | return algo->master_xfer(i2c_adap, msgs, num); | ||
2035 | } | ||
2036 | |||
2037 | static struct i2c_algorithm intel_sdvo_i2c_bit_algo = { | ||
2038 | .master_xfer = intel_sdvo_master_xfer, | ||
2039 | }; | ||
2040 | |||
2041 | static u8 | 2003 | static u8 |
2042 | intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) | 2004 | intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) |
2043 | { | 2005 | { |
@@ -2076,26 +2038,29 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) | |||
2076 | } | 2038 | } |
2077 | 2039 | ||
2078 | static void | 2040 | static void |
2079 | intel_sdvo_connector_init(struct drm_encoder *encoder, | 2041 | intel_sdvo_connector_init(struct intel_sdvo_connector *connector, |
2080 | struct drm_connector *connector) | 2042 | struct intel_sdvo *encoder) |
2081 | { | 2043 | { |
2082 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, | 2044 | drm_connector_init(encoder->base.base.dev, |
2083 | connector->connector_type); | 2045 | &connector->base.base, |
2046 | &intel_sdvo_connector_funcs, | ||
2047 | connector->base.base.connector_type); | ||
2084 | 2048 | ||
2085 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); | 2049 | drm_connector_helper_add(&connector->base.base, |
2050 | &intel_sdvo_connector_helper_funcs); | ||
2086 | 2051 | ||
2087 | connector->interlace_allowed = 0; | 2052 | connector->base.base.interlace_allowed = 0; |
2088 | connector->doublescan_allowed = 0; | 2053 | connector->base.base.doublescan_allowed = 0; |
2089 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 2054 | connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; |
2090 | 2055 | ||
2091 | drm_mode_connector_attach_encoder(connector, encoder); | 2056 | intel_connector_attach_encoder(&connector->base, &encoder->base); |
2092 | drm_sysfs_connector_add(connector); | 2057 | drm_sysfs_connector_add(&connector->base.base); |
2093 | } | 2058 | } |
2094 | 2059 | ||
2095 | static bool | 2060 | static bool |
2096 | intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | 2061 | intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) |
2097 | { | 2062 | { |
2098 | struct drm_encoder *encoder = &intel_sdvo->base.enc; | 2063 | struct drm_encoder *encoder = &intel_sdvo->base.base; |
2099 | struct drm_connector *connector; | 2064 | struct drm_connector *connector; |
2100 | struct intel_connector *intel_connector; | 2065 | struct intel_connector *intel_connector; |
2101 | struct intel_sdvo_connector *intel_sdvo_connector; | 2066 | struct intel_sdvo_connector *intel_sdvo_connector; |
@@ -2130,7 +2095,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | |||
2130 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2095 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2131 | (1 << INTEL_ANALOG_CLONE_BIT)); | 2096 | (1 << INTEL_ANALOG_CLONE_BIT)); |
2132 | 2097 | ||
2133 | intel_sdvo_connector_init(encoder, connector); | 2098 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2134 | 2099 | ||
2135 | return true; | 2100 | return true; |
2136 | } | 2101 | } |
@@ -2138,36 +2103,36 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | |||
2138 | static bool | 2103 | static bool |
2139 | intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) | 2104 | intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) |
2140 | { | 2105 | { |
2141 | struct drm_encoder *encoder = &intel_sdvo->base.enc; | 2106 | struct drm_encoder *encoder = &intel_sdvo->base.base; |
2142 | struct drm_connector *connector; | 2107 | struct drm_connector *connector; |
2143 | struct intel_connector *intel_connector; | 2108 | struct intel_connector *intel_connector; |
2144 | struct intel_sdvo_connector *intel_sdvo_connector; | 2109 | struct intel_sdvo_connector *intel_sdvo_connector; |
2145 | 2110 | ||
2146 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); | 2111 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
2147 | if (!intel_sdvo_connector) | 2112 | if (!intel_sdvo_connector) |
2148 | return false; | 2113 | return false; |
2149 | 2114 | ||
2150 | intel_connector = &intel_sdvo_connector->base; | 2115 | intel_connector = &intel_sdvo_connector->base; |
2151 | connector = &intel_connector->base; | 2116 | connector = &intel_connector->base; |
2152 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | 2117 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; |
2153 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | 2118 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; |
2154 | 2119 | ||
2155 | intel_sdvo->controlled_output |= type; | 2120 | intel_sdvo->controlled_output |= type; |
2156 | intel_sdvo_connector->output_flag = type; | 2121 | intel_sdvo_connector->output_flag = type; |
2157 | 2122 | ||
2158 | intel_sdvo->is_tv = true; | 2123 | intel_sdvo->is_tv = true; |
2159 | intel_sdvo->base.needs_tv_clock = true; | 2124 | intel_sdvo->base.needs_tv_clock = true; |
2160 | intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | 2125 | intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; |
2161 | 2126 | ||
2162 | intel_sdvo_connector_init(encoder, connector); | 2127 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2163 | 2128 | ||
2164 | if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type)) | 2129 | if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type)) |
2165 | goto err; | 2130 | goto err; |
2166 | 2131 | ||
2167 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) | 2132 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
2168 | goto err; | 2133 | goto err; |
2169 | 2134 | ||
2170 | return true; | 2135 | return true; |
2171 | 2136 | ||
2172 | err: | 2137 | err: |
2173 | intel_sdvo_destroy_enhance_property(connector); | 2138 | intel_sdvo_destroy_enhance_property(connector); |
@@ -2178,43 +2143,44 @@ err: | |||
2178 | static bool | 2143 | static bool |
2179 | intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) | 2144 | intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) |
2180 | { | 2145 | { |
2181 | struct drm_encoder *encoder = &intel_sdvo->base.enc; | 2146 | struct drm_encoder *encoder = &intel_sdvo->base.base; |
2182 | struct drm_connector *connector; | 2147 | struct drm_connector *connector; |
2183 | struct intel_connector *intel_connector; | 2148 | struct intel_connector *intel_connector; |
2184 | struct intel_sdvo_connector *intel_sdvo_connector; | 2149 | struct intel_sdvo_connector *intel_sdvo_connector; |
2185 | 2150 | ||
2186 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); | 2151 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
2187 | if (!intel_sdvo_connector) | 2152 | if (!intel_sdvo_connector) |
2188 | return false; | 2153 | return false; |
2189 | 2154 | ||
2190 | intel_connector = &intel_sdvo_connector->base; | 2155 | intel_connector = &intel_sdvo_connector->base; |
2191 | connector = &intel_connector->base; | 2156 | connector = &intel_connector->base; |
2192 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 2157 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
2193 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | 2158 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; |
2194 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | 2159 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
2195 | 2160 | ||
2196 | if (device == 0) { | 2161 | if (device == 0) { |
2197 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0; | 2162 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0; |
2198 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; | 2163 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; |
2199 | } else if (device == 1) { | 2164 | } else if (device == 1) { |
2200 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; | 2165 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; |
2201 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; | 2166 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; |
2202 | } | 2167 | } |
2203 | 2168 | ||
2204 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2169 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2205 | (1 << INTEL_ANALOG_CLONE_BIT)); | 2170 | (1 << INTEL_ANALOG_CLONE_BIT)); |
2206 | 2171 | ||
2207 | intel_sdvo_connector_init(encoder, connector); | 2172 | intel_sdvo_connector_init(intel_sdvo_connector, |
2208 | return true; | 2173 | intel_sdvo); |
2174 | return true; | ||
2209 | } | 2175 | } |
2210 | 2176 | ||
2211 | static bool | 2177 | static bool |
2212 | intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) | 2178 | intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) |
2213 | { | 2179 | { |
2214 | struct drm_encoder *encoder = &intel_sdvo->base.enc; | 2180 | struct drm_encoder *encoder = &intel_sdvo->base.base; |
2215 | struct drm_connector *connector; | 2181 | struct drm_connector *connector; |
2216 | struct intel_connector *intel_connector; | 2182 | struct intel_connector *intel_connector; |
2217 | struct intel_sdvo_connector *intel_sdvo_connector; | 2183 | struct intel_sdvo_connector *intel_sdvo_connector; |
2218 | 2184 | ||
2219 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); | 2185 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
2220 | if (!intel_sdvo_connector) | 2186 | if (!intel_sdvo_connector) |
@@ -2222,22 +2188,22 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) | |||
2222 | 2188 | ||
2223 | intel_connector = &intel_sdvo_connector->base; | 2189 | intel_connector = &intel_sdvo_connector->base; |
2224 | connector = &intel_connector->base; | 2190 | connector = &intel_connector->base; |
2225 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 2191 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
2226 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 2192 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
2227 | 2193 | ||
2228 | if (device == 0) { | 2194 | if (device == 0) { |
2229 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0; | 2195 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0; |
2230 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; | 2196 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; |
2231 | } else if (device == 1) { | 2197 | } else if (device == 1) { |
2232 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; | 2198 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; |
2233 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; | 2199 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
2234 | } | 2200 | } |
2235 | 2201 | ||
2236 | intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | | 2202 | intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | |
2237 | (1 << INTEL_SDVO_LVDS_CLONE_BIT)); | 2203 | (1 << INTEL_SDVO_LVDS_CLONE_BIT)); |
2238 | 2204 | ||
2239 | intel_sdvo_connector_init(encoder, connector); | 2205 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2240 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) | 2206 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
2241 | goto err; | 2207 | goto err; |
2242 | 2208 | ||
2243 | return true; | 2209 | return true; |
@@ -2309,7 +2275,7 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, | |||
2309 | struct intel_sdvo_connector *intel_sdvo_connector, | 2275 | struct intel_sdvo_connector *intel_sdvo_connector, |
2310 | int type) | 2276 | int type) |
2311 | { | 2277 | { |
2312 | struct drm_device *dev = intel_sdvo->base.enc.dev; | 2278 | struct drm_device *dev = intel_sdvo->base.base.dev; |
2313 | struct intel_sdvo_tv_format format; | 2279 | struct intel_sdvo_tv_format format; |
2314 | uint32_t format_map, i; | 2280 | uint32_t format_map, i; |
2315 | 2281 | ||
@@ -2375,7 +2341,7 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, | |||
2375 | struct intel_sdvo_connector *intel_sdvo_connector, | 2341 | struct intel_sdvo_connector *intel_sdvo_connector, |
2376 | struct intel_sdvo_enhancements_reply enhancements) | 2342 | struct intel_sdvo_enhancements_reply enhancements) |
2377 | { | 2343 | { |
2378 | struct drm_device *dev = intel_sdvo->base.enc.dev; | 2344 | struct drm_device *dev = intel_sdvo->base.base.dev; |
2379 | struct drm_connector *connector = &intel_sdvo_connector->base.base; | 2345 | struct drm_connector *connector = &intel_sdvo_connector->base.base; |
2380 | uint16_t response, data_value[2]; | 2346 | uint16_t response, data_value[2]; |
2381 | 2347 | ||
@@ -2504,7 +2470,7 @@ intel_sdvo_create_enhance_property_lvds(struct intel_sdvo *intel_sdvo, | |||
2504 | struct intel_sdvo_connector *intel_sdvo_connector, | 2470 | struct intel_sdvo_connector *intel_sdvo_connector, |
2505 | struct intel_sdvo_enhancements_reply enhancements) | 2471 | struct intel_sdvo_enhancements_reply enhancements) |
2506 | { | 2472 | { |
2507 | struct drm_device *dev = intel_sdvo->base.enc.dev; | 2473 | struct drm_device *dev = intel_sdvo->base.base.dev; |
2508 | struct drm_connector *connector = &intel_sdvo_connector->base.base; | 2474 | struct drm_connector *connector = &intel_sdvo_connector->base.base; |
2509 | uint16_t response, data_value[2]; | 2475 | uint16_t response, data_value[2]; |
2510 | 2476 | ||
@@ -2546,9 +2512,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2546 | struct drm_i915_private *dev_priv = dev->dev_private; | 2512 | struct drm_i915_private *dev_priv = dev->dev_private; |
2547 | struct intel_encoder *intel_encoder; | 2513 | struct intel_encoder *intel_encoder; |
2548 | struct intel_sdvo *intel_sdvo; | 2514 | struct intel_sdvo *intel_sdvo; |
2549 | u8 ch[0x40]; | ||
2550 | int i; | 2515 | int i; |
2551 | u32 i2c_reg, ddc_reg, analog_ddc_reg; | ||
2552 | 2516 | ||
2553 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); | 2517 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); |
2554 | if (!intel_sdvo) | 2518 | if (!intel_sdvo) |
@@ -2558,83 +2522,52 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2558 | 2522 | ||
2559 | intel_encoder = &intel_sdvo->base; | 2523 | intel_encoder = &intel_sdvo->base; |
2560 | intel_encoder->type = INTEL_OUTPUT_SDVO; | 2524 | intel_encoder->type = INTEL_OUTPUT_SDVO; |
2525 | /* encoder type will be decided later */ | ||
2526 | drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0); | ||
2561 | 2527 | ||
2562 | if (HAS_PCH_SPLIT(dev)) { | 2528 | intel_sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter; |
2563 | i2c_reg = PCH_GPIOE; | ||
2564 | ddc_reg = PCH_GPIOE; | ||
2565 | analog_ddc_reg = PCH_GPIOA; | ||
2566 | } else { | ||
2567 | i2c_reg = GPIOE; | ||
2568 | ddc_reg = GPIOE; | ||
2569 | analog_ddc_reg = GPIOA; | ||
2570 | } | ||
2571 | |||
2572 | /* setup the DDC bus. */ | ||
2573 | if (IS_SDVOB(sdvo_reg)) | ||
2574 | intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOB"); | ||
2575 | else | ||
2576 | intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOC"); | ||
2577 | |||
2578 | if (!intel_encoder->i2c_bus) | ||
2579 | goto err_inteloutput; | ||
2580 | 2529 | ||
2581 | intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); | 2530 | intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); |
2582 | 2531 | ||
2583 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ | ||
2584 | intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; | ||
2585 | |||
2586 | /* Read the regs to test if we can talk to the device */ | 2532 | /* Read the regs to test if we can talk to the device */ |
2587 | for (i = 0; i < 0x40; i++) { | 2533 | for (i = 0; i < 0x40; i++) { |
2588 | if (!intel_sdvo_read_byte(intel_sdvo, i, &ch[i])) { | 2534 | u8 byte; |
2535 | |||
2536 | if (!intel_sdvo_read_byte(intel_sdvo, i, &byte)) { | ||
2589 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", | 2537 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", |
2590 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); | 2538 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2591 | goto err_i2c; | 2539 | goto err; |
2592 | } | 2540 | } |
2593 | } | 2541 | } |
2594 | 2542 | ||
2595 | /* setup the DDC bus. */ | 2543 | if (IS_SDVOB(sdvo_reg)) |
2596 | if (IS_SDVOB(sdvo_reg)) { | ||
2597 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); | ||
2598 | intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, | ||
2599 | "SDVOB/VGA DDC BUS"); | ||
2600 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | 2544 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; |
2601 | } else { | 2545 | else |
2602 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); | ||
2603 | intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, | ||
2604 | "SDVOC/VGA DDC BUS"); | ||
2605 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2546 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; |
2606 | } | ||
2607 | if (intel_encoder->ddc_bus == NULL || intel_sdvo->analog_ddc_bus == NULL) | ||
2608 | goto err_i2c; | ||
2609 | 2547 | ||
2610 | /* Wrap with our custom algo which switches to DDC mode */ | 2548 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); |
2611 | intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; | ||
2612 | |||
2613 | /* encoder type will be decided later */ | ||
2614 | drm_encoder_init(dev, &intel_encoder->enc, &intel_sdvo_enc_funcs, 0); | ||
2615 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); | ||
2616 | 2549 | ||
2617 | /* In default case sdvo lvds is false */ | 2550 | /* In default case sdvo lvds is false */ |
2618 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) | 2551 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |
2619 | goto err_enc; | 2552 | goto err; |
2620 | 2553 | ||
2621 | if (intel_sdvo_output_setup(intel_sdvo, | 2554 | if (intel_sdvo_output_setup(intel_sdvo, |
2622 | intel_sdvo->caps.output_flags) != true) { | 2555 | intel_sdvo->caps.output_flags) != true) { |
2623 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", | 2556 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", |
2624 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); | 2557 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2625 | goto err_enc; | 2558 | goto err; |
2626 | } | 2559 | } |
2627 | 2560 | ||
2628 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); | 2561 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); |
2629 | 2562 | ||
2630 | /* Set the input timing to the screen. Assume always input 0. */ | 2563 | /* Set the input timing to the screen. Assume always input 0. */ |
2631 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 2564 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
2632 | goto err_enc; | 2565 | goto err; |
2633 | 2566 | ||
2634 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, | 2567 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, |
2635 | &intel_sdvo->pixel_clock_min, | 2568 | &intel_sdvo->pixel_clock_min, |
2636 | &intel_sdvo->pixel_clock_max)) | 2569 | &intel_sdvo->pixel_clock_max)) |
2637 | goto err_enc; | 2570 | goto err; |
2638 | 2571 | ||
2639 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " | 2572 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " |
2640 | "clock range %dMHz - %dMHz, " | 2573 | "clock range %dMHz - %dMHz, " |
@@ -2654,16 +2587,8 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2654 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); | 2587 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
2655 | return true; | 2588 | return true; |
2656 | 2589 | ||
2657 | err_enc: | 2590 | err: |
2658 | drm_encoder_cleanup(&intel_encoder->enc); | 2591 | drm_encoder_cleanup(&intel_encoder->base); |
2659 | err_i2c: | ||
2660 | if (intel_sdvo->analog_ddc_bus != NULL) | ||
2661 | intel_i2c_destroy(intel_sdvo->analog_ddc_bus); | ||
2662 | if (intel_encoder->ddc_bus != NULL) | ||
2663 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
2664 | if (intel_encoder->i2c_bus != NULL) | ||
2665 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
2666 | err_inteloutput: | ||
2667 | kfree(intel_sdvo); | 2592 | kfree(intel_sdvo); |
2668 | 2593 | ||
2669 | return false; | 2594 | return false; |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 4a117e318a73..e03783fbbf95 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -48,7 +48,7 @@ struct intel_tv { | |||
48 | struct intel_encoder base; | 48 | struct intel_encoder base; |
49 | 49 | ||
50 | int type; | 50 | int type; |
51 | char *tv_format; | 51 | const char *tv_format; |
52 | int margin[4]; | 52 | int margin[4]; |
53 | u32 save_TV_H_CTL_1; | 53 | u32 save_TV_H_CTL_1; |
54 | u32 save_TV_H_CTL_2; | 54 | u32 save_TV_H_CTL_2; |
@@ -350,7 +350,7 @@ static const struct video_levels component_levels = { | |||
350 | 350 | ||
351 | 351 | ||
352 | struct tv_mode { | 352 | struct tv_mode { |
353 | char *name; | 353 | const char *name; |
354 | int clock; | 354 | int clock; |
355 | int refresh; /* in millihertz (for precision) */ | 355 | int refresh; /* in millihertz (for precision) */ |
356 | u32 oversample; | 356 | u32 oversample; |
@@ -900,7 +900,14 @@ static const struct tv_mode tv_modes[] = { | |||
900 | 900 | ||
901 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) | 901 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) |
902 | { | 902 | { |
903 | return container_of(enc_to_intel_encoder(encoder), struct intel_tv, base); | 903 | return container_of(encoder, struct intel_tv, base.base); |
904 | } | ||
905 | |||
906 | static struct intel_tv *intel_attached_tv(struct drm_connector *connector) | ||
907 | { | ||
908 | return container_of(intel_attached_encoder(connector), | ||
909 | struct intel_tv, | ||
910 | base); | ||
904 | } | 911 | } |
905 | 912 | ||
906 | static void | 913 | static void |
@@ -922,7 +929,7 @@ intel_tv_dpms(struct drm_encoder *encoder, int mode) | |||
922 | } | 929 | } |
923 | 930 | ||
924 | static const struct tv_mode * | 931 | static const struct tv_mode * |
925 | intel_tv_mode_lookup (char *tv_format) | 932 | intel_tv_mode_lookup(const char *tv_format) |
926 | { | 933 | { |
927 | int i; | 934 | int i; |
928 | 935 | ||
@@ -936,22 +943,23 @@ intel_tv_mode_lookup (char *tv_format) | |||
936 | } | 943 | } |
937 | 944 | ||
938 | static const struct tv_mode * | 945 | static const struct tv_mode * |
939 | intel_tv_mode_find (struct intel_tv *intel_tv) | 946 | intel_tv_mode_find(struct intel_tv *intel_tv) |
940 | { | 947 | { |
941 | return intel_tv_mode_lookup(intel_tv->tv_format); | 948 | return intel_tv_mode_lookup(intel_tv->tv_format); |
942 | } | 949 | } |
943 | 950 | ||
944 | static enum drm_mode_status | 951 | static enum drm_mode_status |
945 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) | 952 | intel_tv_mode_valid(struct drm_connector *connector, |
953 | struct drm_display_mode *mode) | ||
946 | { | 954 | { |
947 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 955 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
948 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | ||
949 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); | 956 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
950 | 957 | ||
951 | /* Ensure TV refresh is close to desired refresh */ | 958 | /* Ensure TV refresh is close to desired refresh */ |
952 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) | 959 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) |
953 | < 1000) | 960 | < 1000) |
954 | return MODE_OK; | 961 | return MODE_OK; |
962 | |||
955 | return MODE_CLOCK_RANGE; | 963 | return MODE_CLOCK_RANGE; |
956 | } | 964 | } |
957 | 965 | ||
@@ -1160,9 +1168,9 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1160 | if (!IS_I9XX(dev)) | 1168 | if (!IS_I9XX(dev)) |
1161 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1169 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1162 | 1170 | ||
1163 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); | 1171 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPECONF_ENABLE); |
1164 | /* Wait for vblank for the disable to take effect. */ | 1172 | /* Wait for vblank for the disable to take effect. */ |
1165 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1173 | intel_wait_for_vblank_off(dev, intel_crtc->pipe); |
1166 | 1174 | ||
1167 | /* Filter ctl must be set before TV_WIN_SIZE */ | 1175 | /* Filter ctl must be set before TV_WIN_SIZE */ |
1168 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); | 1176 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); |
@@ -1196,7 +1204,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1196 | I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]); | 1204 | I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]); |
1197 | for (i = 0; i < 43; i++) | 1205 | for (i = 0; i < 43; i++) |
1198 | I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]); | 1206 | I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]); |
1199 | I915_WRITE(TV_DAC, 0); | 1207 | I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE); |
1200 | I915_WRITE(TV_CTL, tv_ctl); | 1208 | I915_WRITE(TV_CTL, tv_ctl); |
1201 | } | 1209 | } |
1202 | 1210 | ||
@@ -1228,15 +1236,13 @@ static const struct drm_display_mode reported_modes[] = { | |||
1228 | static int | 1236 | static int |
1229 | intel_tv_detect_type (struct intel_tv *intel_tv) | 1237 | intel_tv_detect_type (struct intel_tv *intel_tv) |
1230 | { | 1238 | { |
1231 | struct drm_encoder *encoder = &intel_tv->base.enc; | 1239 | struct drm_encoder *encoder = &intel_tv->base.base; |
1232 | struct drm_device *dev = encoder->dev; | 1240 | struct drm_device *dev = encoder->dev; |
1233 | struct drm_i915_private *dev_priv = dev->dev_private; | 1241 | struct drm_i915_private *dev_priv = dev->dev_private; |
1234 | unsigned long irqflags; | 1242 | unsigned long irqflags; |
1235 | u32 tv_ctl, save_tv_ctl; | 1243 | u32 tv_ctl, save_tv_ctl; |
1236 | u32 tv_dac, save_tv_dac; | 1244 | u32 tv_dac, save_tv_dac; |
1237 | int type = DRM_MODE_CONNECTOR_Unknown; | 1245 | int type; |
1238 | |||
1239 | tv_dac = I915_READ(TV_DAC); | ||
1240 | 1246 | ||
1241 | /* Disable TV interrupts around load detect or we'll recurse */ | 1247 | /* Disable TV interrupts around load detect or we'll recurse */ |
1242 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1248 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); |
@@ -1244,19 +1250,14 @@ intel_tv_detect_type (struct intel_tv *intel_tv) | |||
1244 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); | 1250 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); |
1245 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 1251 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); |
1246 | 1252 | ||
1247 | /* | 1253 | save_tv_dac = tv_dac = I915_READ(TV_DAC); |
1248 | * Detect TV by polling) | 1254 | save_tv_ctl = tv_ctl = I915_READ(TV_CTL); |
1249 | */ | 1255 | |
1250 | save_tv_dac = tv_dac; | 1256 | /* Poll for TV detection */ |
1251 | tv_ctl = I915_READ(TV_CTL); | 1257 | tv_ctl &= ~(TV_ENC_ENABLE | TV_TEST_MODE_MASK); |
1252 | save_tv_ctl = tv_ctl; | ||
1253 | tv_ctl &= ~TV_ENC_ENABLE; | ||
1254 | tv_ctl &= ~TV_TEST_MODE_MASK; | ||
1255 | tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; | 1258 | tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; |
1256 | tv_dac &= ~TVDAC_SENSE_MASK; | 1259 | |
1257 | tv_dac &= ~DAC_A_MASK; | 1260 | tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK); |
1258 | tv_dac &= ~DAC_B_MASK; | ||
1259 | tv_dac &= ~DAC_C_MASK; | ||
1260 | tv_dac |= (TVDAC_STATE_CHG_EN | | 1261 | tv_dac |= (TVDAC_STATE_CHG_EN | |
1261 | TVDAC_A_SENSE_CTL | | 1262 | TVDAC_A_SENSE_CTL | |
1262 | TVDAC_B_SENSE_CTL | | 1263 | TVDAC_B_SENSE_CTL | |
@@ -1265,37 +1266,37 @@ intel_tv_detect_type (struct intel_tv *intel_tv) | |||
1265 | DAC_A_0_7_V | | 1266 | DAC_A_0_7_V | |
1266 | DAC_B_0_7_V | | 1267 | DAC_B_0_7_V | |
1267 | DAC_C_0_7_V); | 1268 | DAC_C_0_7_V); |
1269 | |||
1268 | I915_WRITE(TV_CTL, tv_ctl); | 1270 | I915_WRITE(TV_CTL, tv_ctl); |
1269 | I915_WRITE(TV_DAC, tv_dac); | 1271 | I915_WRITE(TV_DAC, tv_dac); |
1270 | POSTING_READ(TV_DAC); | 1272 | POSTING_READ(TV_DAC); |
1271 | msleep(20); | ||
1272 | 1273 | ||
1273 | tv_dac = I915_READ(TV_DAC); | 1274 | type = -1; |
1274 | I915_WRITE(TV_DAC, save_tv_dac); | 1275 | if (wait_for((tv_dac = I915_READ(TV_DAC)) & TVDAC_STATE_CHG, 20) == 0) { |
1275 | I915_WRITE(TV_CTL, save_tv_ctl); | 1276 | /* |
1276 | POSTING_READ(TV_CTL); | 1277 | * A B C |
1277 | msleep(20); | 1278 | * 0 1 1 Composite |
1278 | 1279 | * 1 0 X svideo | |
1279 | /* | 1280 | * 0 0 0 Component |
1280 | * A B C | 1281 | */ |
1281 | * 0 1 1 Composite | 1282 | if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) { |
1282 | * 1 0 X svideo | 1283 | DRM_DEBUG_KMS("Detected Composite TV connection\n"); |
1283 | * 0 0 0 Component | 1284 | type = DRM_MODE_CONNECTOR_Composite; |
1284 | */ | 1285 | } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) { |
1285 | if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) { | 1286 | DRM_DEBUG_KMS("Detected S-Video TV connection\n"); |
1286 | DRM_DEBUG_KMS("Detected Composite TV connection\n"); | 1287 | type = DRM_MODE_CONNECTOR_SVIDEO; |
1287 | type = DRM_MODE_CONNECTOR_Composite; | 1288 | } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) { |
1288 | } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) { | 1289 | DRM_DEBUG_KMS("Detected Component TV connection\n"); |
1289 | DRM_DEBUG_KMS("Detected S-Video TV connection\n"); | 1290 | type = DRM_MODE_CONNECTOR_Component; |
1290 | type = DRM_MODE_CONNECTOR_SVIDEO; | 1291 | } else { |
1291 | } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) { | 1292 | DRM_DEBUG_KMS("Unrecognised TV connection: %x\n", |
1292 | DRM_DEBUG_KMS("Detected Component TV connection\n"); | 1293 | tv_dac); |
1293 | type = DRM_MODE_CONNECTOR_Component; | 1294 | } |
1294 | } else { | ||
1295 | DRM_DEBUG_KMS("No TV connection detected\n"); | ||
1296 | type = -1; | ||
1297 | } | 1295 | } |
1298 | 1296 | ||
1297 | I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN); | ||
1298 | I915_WRITE(TV_CTL, save_tv_ctl); | ||
1299 | |||
1299 | /* Restore interrupt config */ | 1300 | /* Restore interrupt config */ |
1300 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1301 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); |
1301 | i915_enable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE | | 1302 | i915_enable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE | |
@@ -1311,8 +1312,7 @@ intel_tv_detect_type (struct intel_tv *intel_tv) | |||
1311 | */ | 1312 | */ |
1312 | static void intel_tv_find_better_format(struct drm_connector *connector) | 1313 | static void intel_tv_find_better_format(struct drm_connector *connector) |
1313 | { | 1314 | { |
1314 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1315 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
1315 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | ||
1316 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); | 1316 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1317 | int i; | 1317 | int i; |
1318 | 1318 | ||
@@ -1344,14 +1344,13 @@ static enum drm_connector_status | |||
1344 | intel_tv_detect(struct drm_connector *connector, bool force) | 1344 | intel_tv_detect(struct drm_connector *connector, bool force) |
1345 | { | 1345 | { |
1346 | struct drm_display_mode mode; | 1346 | struct drm_display_mode mode; |
1347 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1347 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
1348 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | ||
1349 | int type; | 1348 | int type; |
1350 | 1349 | ||
1351 | mode = reported_modes[0]; | 1350 | mode = reported_modes[0]; |
1352 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); | 1351 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); |
1353 | 1352 | ||
1354 | if (encoder->crtc && encoder->crtc->enabled) { | 1353 | if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) { |
1355 | type = intel_tv_detect_type(intel_tv); | 1354 | type = intel_tv_detect_type(intel_tv); |
1356 | } else if (force) { | 1355 | } else if (force) { |
1357 | struct drm_crtc *crtc; | 1356 | struct drm_crtc *crtc; |
@@ -1375,11 +1374,10 @@ intel_tv_detect(struct drm_connector *connector, bool force) | |||
1375 | return connector_status_connected; | 1374 | return connector_status_connected; |
1376 | } | 1375 | } |
1377 | 1376 | ||
1378 | static struct input_res { | 1377 | static const struct input_res { |
1379 | char *name; | 1378 | const char *name; |
1380 | int w, h; | 1379 | int w, h; |
1381 | } input_res_table[] = | 1380 | } input_res_table[] = { |
1382 | { | ||
1383 | {"640x480", 640, 480}, | 1381 | {"640x480", 640, 480}, |
1384 | {"800x600", 800, 600}, | 1382 | {"800x600", 800, 600}, |
1385 | {"1024x768", 1024, 768}, | 1383 | {"1024x768", 1024, 768}, |
@@ -1396,8 +1394,7 @@ static void | |||
1396 | intel_tv_chose_preferred_modes(struct drm_connector *connector, | 1394 | intel_tv_chose_preferred_modes(struct drm_connector *connector, |
1397 | struct drm_display_mode *mode_ptr) | 1395 | struct drm_display_mode *mode_ptr) |
1398 | { | 1396 | { |
1399 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1397 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
1400 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | ||
1401 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); | 1398 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1402 | 1399 | ||
1403 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) | 1400 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) |
@@ -1422,15 +1419,14 @@ static int | |||
1422 | intel_tv_get_modes(struct drm_connector *connector) | 1419 | intel_tv_get_modes(struct drm_connector *connector) |
1423 | { | 1420 | { |
1424 | struct drm_display_mode *mode_ptr; | 1421 | struct drm_display_mode *mode_ptr; |
1425 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1422 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
1426 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | ||
1427 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); | 1423 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1428 | int j, count = 0; | 1424 | int j, count = 0; |
1429 | u64 tmp; | 1425 | u64 tmp; |
1430 | 1426 | ||
1431 | for (j = 0; j < ARRAY_SIZE(input_res_table); | 1427 | for (j = 0; j < ARRAY_SIZE(input_res_table); |
1432 | j++) { | 1428 | j++) { |
1433 | struct input_res *input = &input_res_table[j]; | 1429 | const struct input_res *input = &input_res_table[j]; |
1434 | unsigned int hactive_s = input->w; | 1430 | unsigned int hactive_s = input->w; |
1435 | unsigned int vactive_s = input->h; | 1431 | unsigned int vactive_s = input->h; |
1436 | 1432 | ||
@@ -1488,9 +1484,8 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
1488 | uint64_t val) | 1484 | uint64_t val) |
1489 | { | 1485 | { |
1490 | struct drm_device *dev = connector->dev; | 1486 | struct drm_device *dev = connector->dev; |
1491 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1487 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
1492 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | 1488 | struct drm_crtc *crtc = intel_tv->base.base.crtc; |
1493 | struct drm_crtc *crtc = encoder->crtc; | ||
1494 | int ret = 0; | 1489 | int ret = 0; |
1495 | bool changed = false; | 1490 | bool changed = false; |
1496 | 1491 | ||
@@ -1555,7 +1550,7 @@ static const struct drm_connector_funcs intel_tv_connector_funcs = { | |||
1555 | static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = { | 1550 | static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = { |
1556 | .mode_valid = intel_tv_mode_valid, | 1551 | .mode_valid = intel_tv_mode_valid, |
1557 | .get_modes = intel_tv_get_modes, | 1552 | .get_modes = intel_tv_get_modes, |
1558 | .best_encoder = intel_attached_encoder, | 1553 | .best_encoder = intel_best_encoder, |
1559 | }; | 1554 | }; |
1560 | 1555 | ||
1561 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { | 1556 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { |
@@ -1607,7 +1602,7 @@ intel_tv_init(struct drm_device *dev) | |||
1607 | struct intel_encoder *intel_encoder; | 1602 | struct intel_encoder *intel_encoder; |
1608 | struct intel_connector *intel_connector; | 1603 | struct intel_connector *intel_connector; |
1609 | u32 tv_dac_on, tv_dac_off, save_tv_dac; | 1604 | u32 tv_dac_on, tv_dac_off, save_tv_dac; |
1610 | char **tv_format_names; | 1605 | char *tv_format_names[ARRAY_SIZE(tv_modes)]; |
1611 | int i, initial_mode = 0; | 1606 | int i, initial_mode = 0; |
1612 | 1607 | ||
1613 | if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) | 1608 | if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) |
@@ -1661,15 +1656,15 @@ intel_tv_init(struct drm_device *dev) | |||
1661 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1656 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
1662 | DRM_MODE_CONNECTOR_SVIDEO); | 1657 | DRM_MODE_CONNECTOR_SVIDEO); |
1663 | 1658 | ||
1664 | drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs, | 1659 | drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs, |
1665 | DRM_MODE_ENCODER_TVDAC); | 1660 | DRM_MODE_ENCODER_TVDAC); |
1666 | 1661 | ||
1667 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); | 1662 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
1668 | intel_encoder->type = INTEL_OUTPUT_TVOUT; | 1663 | intel_encoder->type = INTEL_OUTPUT_TVOUT; |
1669 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1664 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
1670 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); | 1665 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); |
1671 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); | 1666 | intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1)); |
1672 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); | 1667 | intel_encoder->base.possible_clones = (1 << INTEL_OUTPUT_TVOUT); |
1673 | intel_tv->type = DRM_MODE_CONNECTOR_Unknown; | 1668 | intel_tv->type = DRM_MODE_CONNECTOR_Unknown; |
1674 | 1669 | ||
1675 | /* BIOS margin values */ | 1670 | /* BIOS margin values */ |
@@ -1678,21 +1673,19 @@ intel_tv_init(struct drm_device *dev) | |||
1678 | intel_tv->margin[TV_MARGIN_RIGHT] = 46; | 1673 | intel_tv->margin[TV_MARGIN_RIGHT] = 46; |
1679 | intel_tv->margin[TV_MARGIN_BOTTOM] = 37; | 1674 | intel_tv->margin[TV_MARGIN_BOTTOM] = 37; |
1680 | 1675 | ||
1681 | intel_tv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); | 1676 | intel_tv->tv_format = tv_modes[initial_mode].name; |
1682 | 1677 | ||
1683 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); | 1678 | drm_encoder_helper_add(&intel_encoder->base, &intel_tv_helper_funcs); |
1684 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); | 1679 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); |
1685 | connector->interlace_allowed = false; | 1680 | connector->interlace_allowed = false; |
1686 | connector->doublescan_allowed = false; | 1681 | connector->doublescan_allowed = false; |
1687 | 1682 | ||
1688 | /* Create TV properties then attach current values */ | 1683 | /* Create TV properties then attach current values */ |
1689 | tv_format_names = kmalloc(sizeof(char *) * ARRAY_SIZE(tv_modes), | ||
1690 | GFP_KERNEL); | ||
1691 | if (!tv_format_names) | ||
1692 | goto out; | ||
1693 | for (i = 0; i < ARRAY_SIZE(tv_modes); i++) | 1684 | for (i = 0; i < ARRAY_SIZE(tv_modes); i++) |
1694 | tv_format_names[i] = tv_modes[i].name; | 1685 | tv_format_names[i] = (char *)tv_modes[i].name; |
1695 | drm_mode_create_tv_properties(dev, ARRAY_SIZE(tv_modes), tv_format_names); | 1686 | drm_mode_create_tv_properties(dev, |
1687 | ARRAY_SIZE(tv_modes), | ||
1688 | tv_format_names); | ||
1696 | 1689 | ||
1697 | drm_connector_attach_property(connector, dev->mode_config.tv_mode_property, | 1690 | drm_connector_attach_property(connector, dev->mode_config.tv_mode_property, |
1698 | initial_mode); | 1691 | initial_mode); |
@@ -1708,6 +1701,5 @@ intel_tv_init(struct drm_device *dev) | |||
1708 | drm_connector_attach_property(connector, | 1701 | drm_connector_attach_property(connector, |
1709 | dev->mode_config.tv_bottom_margin_property, | 1702 | dev->mode_config.tv_bottom_margin_property, |
1710 | intel_tv->margin[TV_MARGIN_BOTTOM]); | 1703 | intel_tv->margin[TV_MARGIN_BOTTOM]); |
1711 | out: | ||
1712 | drm_sysfs_connector_add(connector); | 1704 | drm_sysfs_connector_add(connector); |
1713 | } | 1705 | } |
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c index 26d0d8ced80d..65ea42cf1795 100644 --- a/drivers/gpu/drm/mga/mga_drv.c +++ b/drivers/gpu/drm/mga/mga_drv.c | |||
@@ -60,8 +60,6 @@ static struct drm_driver driver = { | |||
60 | .irq_uninstall = mga_driver_irq_uninstall, | 60 | .irq_uninstall = mga_driver_irq_uninstall, |
61 | .irq_handler = mga_driver_irq_handler, | 61 | .irq_handler = mga_driver_irq_handler, |
62 | .reclaim_buffers = drm_core_reclaim_buffers, | 62 | .reclaim_buffers = drm_core_reclaim_buffers, |
63 | .get_map_ofs = drm_core_get_map_ofs, | ||
64 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
65 | .ioctls = mga_ioctls, | 63 | .ioctls = mga_ioctls, |
66 | .dma_ioctl = mga_dma_buffers, | 64 | .dma_ioctl = mga_dma_buffers, |
67 | .fops = { | 65 | .fops = { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 1de5eb53e016..209912a1b7a5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
@@ -379,8 +379,6 @@ static struct drm_driver driver = { | |||
379 | .irq_uninstall = nouveau_irq_uninstall, | 379 | .irq_uninstall = nouveau_irq_uninstall, |
380 | .irq_handler = nouveau_irq_handler, | 380 | .irq_handler = nouveau_irq_handler, |
381 | .reclaim_buffers = drm_core_reclaim_buffers, | 381 | .reclaim_buffers = drm_core_reclaim_buffers, |
382 | .get_map_ofs = drm_core_get_map_ofs, | ||
383 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
384 | .ioctls = nouveau_ioctls, | 382 | .ioctls = nouveau_ioctls, |
385 | .fops = { | 383 | .fops = { |
386 | .owner = THIS_MODULE, | 384 | .owner = THIS_MODULE, |
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index 1e2971f13aa1..67309f84f16d 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c | |||
@@ -56,8 +56,6 @@ static struct drm_driver driver = { | |||
56 | .irq_uninstall = r128_driver_irq_uninstall, | 56 | .irq_uninstall = r128_driver_irq_uninstall, |
57 | .irq_handler = r128_driver_irq_handler, | 57 | .irq_handler = r128_driver_irq_handler, |
58 | .reclaim_buffers = drm_core_reclaim_buffers, | 58 | .reclaim_buffers = drm_core_reclaim_buffers, |
59 | .get_map_ofs = drm_core_get_map_ofs, | ||
60 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
61 | .ioctls = r128_ioctls, | 59 | .ioctls = r128_ioctls, |
62 | .dma_ioctl = r128_cce_buffers, | 60 | .dma_ioctl = r128_cce_buffers, |
63 | .fops = { | 61 | .fops = { |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 795403b0e2cd..663cdc10a5c2 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -203,8 +203,6 @@ static struct drm_driver driver_old = { | |||
203 | .irq_uninstall = radeon_driver_irq_uninstall, | 203 | .irq_uninstall = radeon_driver_irq_uninstall, |
204 | .irq_handler = radeon_driver_irq_handler, | 204 | .irq_handler = radeon_driver_irq_handler, |
205 | .reclaim_buffers = drm_core_reclaim_buffers, | 205 | .reclaim_buffers = drm_core_reclaim_buffers, |
206 | .get_map_ofs = drm_core_get_map_ofs, | ||
207 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
208 | .ioctls = radeon_ioctls, | 206 | .ioctls = radeon_ioctls, |
209 | .dma_ioctl = radeon_cp_buffers, | 207 | .dma_ioctl = radeon_cp_buffers, |
210 | .fops = { | 208 | .fops = { |
@@ -290,8 +288,6 @@ static struct drm_driver kms_driver = { | |||
290 | .irq_uninstall = radeon_driver_irq_uninstall_kms, | 288 | .irq_uninstall = radeon_driver_irq_uninstall_kms, |
291 | .irq_handler = radeon_driver_irq_handler_kms, | 289 | .irq_handler = radeon_driver_irq_handler_kms, |
292 | .reclaim_buffers = drm_core_reclaim_buffers, | 290 | .reclaim_buffers = drm_core_reclaim_buffers, |
293 | .get_map_ofs = drm_core_get_map_ofs, | ||
294 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
295 | .ioctls = radeon_ioctls_kms, | 291 | .ioctls = radeon_ioctls_kms, |
296 | .gem_init_object = radeon_gem_object_init, | 292 | .gem_init_object = radeon_gem_object_init, |
297 | .gem_free_object = radeon_gem_object_free, | 293 | .gem_free_object = radeon_gem_object_free, |
diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c index 021de44c15ab..c0385633667d 100644 --- a/drivers/gpu/drm/savage/savage_drv.c +++ b/drivers/gpu/drm/savage/savage_drv.c | |||
@@ -42,8 +42,6 @@ static struct drm_driver driver = { | |||
42 | .lastclose = savage_driver_lastclose, | 42 | .lastclose = savage_driver_lastclose, |
43 | .unload = savage_driver_unload, | 43 | .unload = savage_driver_unload, |
44 | .reclaim_buffers = savage_reclaim_buffers, | 44 | .reclaim_buffers = savage_reclaim_buffers, |
45 | .get_map_ofs = drm_core_get_map_ofs, | ||
46 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
47 | .ioctls = savage_ioctls, | 45 | .ioctls = savage_ioctls, |
48 | .dma_ioctl = savage_bci_buffers, | 46 | .dma_ioctl = savage_bci_buffers, |
49 | .fops = { | 47 | .fops = { |
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 776bf9e9ea1a..4d9f311d249d 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
@@ -67,13 +67,10 @@ static struct drm_driver driver = { | |||
67 | .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, | 67 | .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, |
68 | .load = sis_driver_load, | 68 | .load = sis_driver_load, |
69 | .unload = sis_driver_unload, | 69 | .unload = sis_driver_unload, |
70 | .context_dtor = NULL, | ||
71 | .dma_quiescent = sis_idle, | 70 | .dma_quiescent = sis_idle, |
72 | .reclaim_buffers = NULL, | 71 | .reclaim_buffers = NULL, |
73 | .reclaim_buffers_idlelocked = sis_reclaim_buffers_locked, | 72 | .reclaim_buffers_idlelocked = sis_reclaim_buffers_locked, |
74 | .lastclose = sis_lastclose, | 73 | .lastclose = sis_lastclose, |
75 | .get_map_ofs = drm_core_get_map_ofs, | ||
76 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
77 | .ioctls = sis_ioctls, | 74 | .ioctls = sis_ioctls, |
78 | .fops = { | 75 | .fops = { |
79 | .owner = THIS_MODULE, | 76 | .owner = THIS_MODULE, |
diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c index ec5a43e65722..e0768adbeccd 100644 --- a/drivers/gpu/drm/tdfx/tdfx_drv.c +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c | |||
@@ -42,8 +42,6 @@ static struct pci_device_id pciidlist[] = { | |||
42 | static struct drm_driver driver = { | 42 | static struct drm_driver driver = { |
43 | .driver_features = DRIVER_USE_MTRR, | 43 | .driver_features = DRIVER_USE_MTRR, |
44 | .reclaim_buffers = drm_core_reclaim_buffers, | 44 | .reclaim_buffers = drm_core_reclaim_buffers, |
45 | .get_map_ofs = drm_core_get_map_ofs, | ||
46 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
47 | .fops = { | 45 | .fops = { |
48 | .owner = THIS_MODULE, | 46 | .owner = THIS_MODULE, |
49 | .open = drm_open, | 47 | .open = drm_open, |
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index 7a1b210401e0..02f733db61c1 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c | |||
@@ -51,8 +51,6 @@ static struct drm_driver driver = { | |||
51 | .reclaim_buffers_locked = NULL, | 51 | .reclaim_buffers_locked = NULL, |
52 | .reclaim_buffers_idlelocked = via_reclaim_buffers_locked, | 52 | .reclaim_buffers_idlelocked = via_reclaim_buffers_locked, |
53 | .lastclose = via_lastclose, | 53 | .lastclose = via_lastclose, |
54 | .get_map_ofs = drm_core_get_map_ofs, | ||
55 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
56 | .ioctls = via_ioctls, | 54 | .ioctls = via_ioctls, |
57 | .fops = { | 55 | .fops = { |
58 | .owner = THIS_MODULE, | 56 | .owner = THIS_MODULE, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 72ec2e2b6e97..e645f44e4302 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -723,8 +723,6 @@ static struct drm_driver driver = { | |||
723 | .irq_uninstall = vmw_irq_uninstall, | 723 | .irq_uninstall = vmw_irq_uninstall, |
724 | .irq_handler = vmw_irq_handler, | 724 | .irq_handler = vmw_irq_handler, |
725 | .reclaim_buffers_locked = NULL, | 725 | .reclaim_buffers_locked = NULL, |
726 | .get_map_ofs = drm_core_get_map_ofs, | ||
727 | .get_reg_ofs = drm_core_get_reg_ofs, | ||
728 | .ioctls = vmw_ioctls, | 726 | .ioctls = vmw_ioctls, |
729 | .num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls), | 727 | .num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls), |
730 | .dma_quiescent = NULL, /*vmw_dma_quiescent, */ | 728 | .dma_quiescent = NULL, /*vmw_dma_quiescent, */ |