Rev 5060 | Rev 6084 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5060 | Rev 5271 | ||
---|---|---|---|
Line 32... | Line 32... | ||
32 | #include |
32 | #include |
33 | #include |
33 | #include |
34 | #include |
34 | #include |
35 | #include |
35 | #include |
36 | #include |
36 | #include |
- | 37 | #include |
|
Line 37... | Line 38... | ||
37 | 38 | ||
38 | #define version_greater(edid, maj, min) \ |
39 | #define version_greater(edid, maj, min) \ |
39 | (((edid)->version > (maj)) || \ |
40 | (((edid)->version > (maj)) || \ |
Line 630... | Line 631... | ||
630 | { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008, |
631 | { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008, |
631 | 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, |
632 | 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, |
632 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
633 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
633 | DRM_MODE_FLAG_INTERLACE), |
634 | DRM_MODE_FLAG_INTERLACE), |
634 | .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
635 | .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
635 | /* 6 - 1440x480i@60Hz */ |
636 | /* 6 - 720(1440)x480i@60Hz */ |
636 | { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, |
637 | { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739, |
637 | 1602, 1716, 0, 480, 488, 494, 525, 0, |
638 | 801, 858, 0, 480, 488, 494, 525, 0, |
638 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
639 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
639 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
640 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
640 | .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
641 | .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
641 | /* 7 - 1440x480i@60Hz */ |
642 | /* 7 - 720(1440)x480i@60Hz */ |
642 | { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, |
643 | { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500, 720, 739, |
643 | 1602, 1716, 0, 480, 488, 494, 525, 0, |
644 | 801, 858, 0, 480, 488, 494, 525, 0, |
644 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
645 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
645 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
646 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
646 | .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
647 | .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
647 | /* 8 - 1440x240@60Hz */ |
648 | /* 8 - 720(1440)x240@60Hz */ |
648 | { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, |
649 | { DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739, |
649 | 1602, 1716, 0, 240, 244, 247, 262, 0, |
650 | 801, 858, 0, 240, 244, 247, 262, 0, |
650 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
651 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
651 | DRM_MODE_FLAG_DBLCLK), |
652 | DRM_MODE_FLAG_DBLCLK), |
652 | .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
653 | .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
653 | /* 9 - 1440x240@60Hz */ |
654 | /* 9 - 720(1440)x240@60Hz */ |
654 | { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, |
655 | { DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739, |
655 | 1602, 1716, 0, 240, 244, 247, 262, 0, |
656 | 801, 858, 0, 240, 244, 247, 262, 0, |
656 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
657 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
657 | DRM_MODE_FLAG_DBLCLK), |
658 | DRM_MODE_FLAG_DBLCLK), |
658 | .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
659 | .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
659 | /* 10 - 2880x480i@60Hz */ |
660 | /* 10 - 2880x480i@60Hz */ |
660 | { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, |
661 | { DRM_MODE("2880x480i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, |
Line 712... | Line 713... | ||
712 | { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448, |
713 | { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448, |
713 | 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, |
714 | 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, |
714 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
715 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
715 | DRM_MODE_FLAG_INTERLACE), |
716 | DRM_MODE_FLAG_INTERLACE), |
716 | .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
717 | .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
717 | /* 21 - 1440x576i@50Hz */ |
718 | /* 21 - 720(1440)x576i@50Hz */ |
718 | { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, |
719 | { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732, |
719 | 1590, 1728, 0, 576, 580, 586, 625, 0, |
720 | 795, 864, 0, 576, 580, 586, 625, 0, |
720 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
721 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
721 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
722 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
722 | .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
723 | .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
723 | /* 22 - 1440x576i@50Hz */ |
724 | /* 22 - 720(1440)x576i@50Hz */ |
724 | { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, |
725 | { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500, 720, 732, |
725 | 1590, 1728, 0, 576, 580, 586, 625, 0, |
726 | 795, 864, 0, 576, 580, 586, 625, 0, |
726 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
727 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
727 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
728 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
728 | .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
729 | .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
729 | /* 23 - 1440x288@50Hz */ |
730 | /* 23 - 720(1440)x288@50Hz */ |
730 | { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, |
731 | { DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500, 720, 732, |
731 | 1590, 1728, 0, 288, 290, 293, 312, 0, |
732 | 795, 864, 0, 288, 290, 293, 312, 0, |
732 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
733 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
733 | DRM_MODE_FLAG_DBLCLK), |
734 | DRM_MODE_FLAG_DBLCLK), |
734 | .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
735 | .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
735 | /* 24 - 1440x288@50Hz */ |
736 | /* 24 - 720(1440)x288@50Hz */ |
736 | { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, |
737 | { DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500, 720, 732, |
737 | 1590, 1728, 0, 288, 290, 293, 312, 0, |
738 | 795, 864, 0, 288, 290, 293, 312, 0, |
738 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
739 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
739 | DRM_MODE_FLAG_DBLCLK), |
740 | DRM_MODE_FLAG_DBLCLK), |
740 | .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
741 | .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
741 | /* 25 - 2880x576i@50Hz */ |
742 | /* 25 - 2880x576i@50Hz */ |
742 | { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, |
743 | { DRM_MODE("2880x576i", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, |
Line 835... | Line 836... | ||
835 | /* 43 - 720x576@100Hz */ |
836 | /* 43 - 720x576@100Hz */ |
836 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732, |
837 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732, |
837 | 796, 864, 0, 576, 581, 586, 625, 0, |
838 | 796, 864, 0, 576, 581, 586, 625, 0, |
838 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), |
839 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), |
839 | .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
840 | .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
840 | /* 44 - 1440x576i@100Hz */ |
841 | /* 44 - 720(1440)x576i@100Hz */ |
841 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, |
842 | { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, |
842 | 1590, 1728, 0, 576, 580, 586, 625, 0, |
843 | 795, 864, 0, 576, 580, 586, 625, 0, |
843 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
844 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
844 | DRM_MODE_FLAG_DBLCLK), |
845 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
845 | .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
846 | .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
846 | /* 45 - 1440x576i@100Hz */ |
847 | /* 45 - 720(1440)x576i@100Hz */ |
847 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, |
848 | { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, |
848 | 1590, 1728, 0, 576, 580, 586, 625, 0, |
849 | 795, 864, 0, 576, 580, 586, 625, 0, |
849 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
850 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
850 | DRM_MODE_FLAG_DBLCLK), |
851 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
851 | .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
852 | .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
852 | /* 46 - 1920x1080i@120Hz */ |
853 | /* 46 - 1920x1080i@120Hz */ |
853 | { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, |
854 | { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, |
854 | 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, |
855 | 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, |
855 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
856 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
Line 868... | Line 869... | ||
868 | /* 49 - 720x480@120Hz */ |
869 | /* 49 - 720x480@120Hz */ |
869 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736, |
870 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736, |
870 | 798, 858, 0, 480, 489, 495, 525, 0, |
871 | 798, 858, 0, 480, 489, 495, 525, 0, |
871 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), |
872 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), |
872 | .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
873 | .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
873 | /* 50 - 1440x480i@120Hz */ |
874 | /* 50 - 720(1440)x480i@120Hz */ |
874 | { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478, |
875 | { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 27000, 720, 739, |
875 | 1602, 1716, 0, 480, 488, 494, 525, 0, |
876 | 801, 858, 0, 480, 488, 494, 525, 0, |
876 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
877 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
877 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
878 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
878 | .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
879 | .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
879 | /* 51 - 1440x480i@120Hz */ |
880 | /* 51 - 720(1440)x480i@120Hz */ |
880 | { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478, |
881 | { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 27000, 720, 739, |
881 | 1602, 1716, 0, 480, 488, 494, 525, 0, |
882 | 801, 858, 0, 480, 488, 494, 525, 0, |
882 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
883 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
883 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
884 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
884 | .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
885 | .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
885 | /* 52 - 720x576@200Hz */ |
886 | /* 52 - 720x576@200Hz */ |
886 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732, |
887 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732, |
Line 890... | Line 891... | ||
890 | /* 53 - 720x576@200Hz */ |
891 | /* 53 - 720x576@200Hz */ |
891 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732, |
892 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732, |
892 | 796, 864, 0, 576, 581, 586, 625, 0, |
893 | 796, 864, 0, 576, 581, 586, 625, 0, |
893 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), |
894 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), |
894 | .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
895 | .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
895 | /* 54 - 1440x576i@200Hz */ |
896 | /* 54 - 720(1440)x576i@200Hz */ |
896 | { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464, |
897 | { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 54000, 720, 732, |
897 | 1590, 1728, 0, 576, 580, 586, 625, 0, |
898 | 795, 864, 0, 576, 580, 586, 625, 0, |
898 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
899 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
899 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
900 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
900 | .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
901 | .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
901 | /* 55 - 1440x576i@200Hz */ |
902 | /* 55 - 720(1440)x576i@200Hz */ |
902 | { DRM_MODE("1440x576i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464, |
903 | { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 54000, 720, 732, |
903 | 1590, 1728, 0, 576, 580, 586, 625, 0, |
904 | 795, 864, 0, 576, 580, 586, 625, 0, |
904 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
905 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
905 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
906 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
906 | .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
907 | .vrefresh = 200, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
907 | /* 56 - 720x480@240Hz */ |
908 | /* 56 - 720x480@240Hz */ |
908 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736, |
909 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736, |
Line 912... | Line 913... | ||
912 | /* 57 - 720x480@240Hz */ |
913 | /* 57 - 720x480@240Hz */ |
913 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736, |
914 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736, |
914 | 798, 858, 0, 480, 489, 495, 525, 0, |
915 | 798, 858, 0, 480, 489, 495, 525, 0, |
915 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), |
916 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), |
916 | .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
917 | .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
917 | /* 58 - 1440x480i@240 */ |
918 | /* 58 - 720(1440)x480i@240 */ |
918 | { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478, |
919 | { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739, |
919 | 1602, 1716, 0, 480, 488, 494, 525, 0, |
920 | 801, 858, 0, 480, 488, 494, 525, 0, |
920 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
921 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
921 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
922 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
922 | .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
923 | .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
923 | /* 59 - 1440x480i@240 */ |
924 | /* 59 - 720(1440)x480i@240 */ |
924 | { DRM_MODE("1440x480i", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478, |
925 | { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739, |
925 | 1602, 1716, 0, 480, 488, 494, 525, 0, |
926 | 801, 858, 0, 480, 488, 494, 525, 0, |
926 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
927 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
927 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
928 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
928 | .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
929 | .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
929 | /* 60 - 1280x720@24Hz */ |
930 | /* 60 - 1280x720@24Hz */ |
930 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040, |
931 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040, |
Line 1012... | Line 1013... | ||
1012 | static int edid_fixup __read_mostly = 6; |
1013 | static int edid_fixup __read_mostly = 6; |
1013 | module_param_named(edid_fixup, edid_fixup, int, 0400); |
1014 | module_param_named(edid_fixup, edid_fixup, int, 0400); |
1014 | MODULE_PARM_DESC(edid_fixup, |
1015 | MODULE_PARM_DESC(edid_fixup, |
1015 | "Minimum number of valid EDID header bytes (0-8, default 6)"); |
1016 | "Minimum number of valid EDID header bytes (0-8, default 6)"); |
Line -... | Line 1017... | ||
- | 1017 | ||
- | 1018 | static void drm_get_displayid(struct drm_connector *connector, |
|
- | 1019 | struct edid *edid); |
|
- | 1020 | ||
- | 1021 | static int drm_edid_block_checksum(const u8 *raw_edid) |
|
- | 1022 | { |
|
- | 1023 | int i; |
|
- | 1024 | u8 csum = 0; |
|
- | 1025 | for (i = 0; i < EDID_LENGTH; i++) |
|
- | 1026 | csum += raw_edid[i]; |
|
- | 1027 | ||
- | 1028 | return csum; |
|
- | 1029 | } |
|
- | 1030 | ||
- | 1031 | static bool drm_edid_is_zero(const u8 *in_edid, int length) |
|
- | 1032 | { |
|
- | 1033 | if (memchr_inv(in_edid, 0, length)) |
|
- | 1034 | return false; |
|
- | 1035 | ||
- | 1036 | return true; |
|
- | 1037 | } |
|
1016 | 1038 | ||
1017 | /** |
1039 | /** |
1018 | * drm_edid_block_valid - Sanity check the EDID block (base or extension) |
1040 | * drm_edid_block_valid - Sanity check the EDID block (base or extension) |
1019 | * @raw_edid: pointer to raw EDID block |
1041 | * @raw_edid: pointer to raw EDID block |
1020 | * @block: type of block to validate (0 for base, extension otherwise) |
1042 | * @block: type of block to validate (0 for base, extension otherwise) |
Line 1025... | Line 1047... | ||
1025 | * |
1047 | * |
1026 | * Return: True if the block is valid, false otherwise. |
1048 | * Return: True if the block is valid, false otherwise. |
1027 | */ |
1049 | */ |
1028 | bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid) |
1050 | bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid) |
1029 | { |
1051 | { |
1030 | int i; |
- | |
1031 | u8 csum = 0; |
1052 | u8 csum; |
1032 | struct edid *edid = (struct edid *)raw_edid; |
1053 | struct edid *edid = (struct edid *)raw_edid; |
Line 1033... | Line 1054... | ||
1033 | 1054 | ||
1034 | if (WARN_ON(!raw_edid)) |
1055 | if (WARN_ON(!raw_edid)) |
Line 1046... | Line 1067... | ||
1046 | } else { |
1067 | } else { |
1047 | goto bad; |
1068 | goto bad; |
1048 | } |
1069 | } |
1049 | } |
1070 | } |
Line 1050... | Line -... | ||
1050 | - | ||
1051 | for (i = 0; i < EDID_LENGTH; i++) |
1071 | |
1052 | csum += raw_edid[i]; |
1072 | csum = drm_edid_block_checksum(raw_edid); |
1053 | if (csum) { |
1073 | if (csum) { |
1054 | if (print_bad_edid) { |
1074 | if (print_bad_edid) { |
1055 | DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum); |
1075 | DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum); |
Line 1078... | Line 1098... | ||
1078 | 1098 | ||
Line 1079... | Line 1099... | ||
1079 | return true; |
1099 | return true; |
1080 | 1100 | ||
- | 1101 | bad: |
|
- | 1102 | if (print_bad_edid) { |
|
- | 1103 | if (drm_edid_is_zero(raw_edid, EDID_LENGTH)) { |
|
1081 | bad: |
1104 | printk(KERN_ERR "EDID block is all zeroes\n"); |
1082 | if (print_bad_edid) { |
1105 | } else { |
1083 | printk(KERN_ERR "Raw EDID:\n"); |
1106 | printk(KERN_ERR "Raw EDID:\n"); |
1084 | print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1, |
1107 | print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1, |
- | 1108 | raw_edid, EDID_LENGTH, false); |
|
1085 | raw_edid, EDID_LENGTH, false); |
1109 | } |
1086 | } |
1110 | } |
1087 | return false; |
1111 | return false; |
Line 1088... | Line 1112... | ||
1088 | } |
1112 | } |
Line 1113... | Line 1137... | ||
1113 | EXPORT_SYMBOL(drm_edid_is_valid); |
1137 | EXPORT_SYMBOL(drm_edid_is_valid); |
Line 1114... | Line 1138... | ||
1114 | 1138 | ||
1115 | #define DDC_SEGMENT_ADDR 0x30 |
1139 | #define DDC_SEGMENT_ADDR 0x30 |
1116 | /** |
1140 | /** |
1117 | * drm_do_probe_ddc_edid() - get EDID information via I2C |
1141 | * drm_do_probe_ddc_edid() - get EDID information via I2C |
1118 | * @adapter: I2C device adaptor |
1142 | * @data: I2C device adapter |
1119 | * @buf: EDID data buffer to be filled |
1143 | * @buf: EDID data buffer to be filled |
1120 | * @block: 128 byte EDID block to start fetching from |
1144 | * @block: 128 byte EDID block to start fetching from |
1121 | * @len: EDID data buffer length to fetch |
1145 | * @len: EDID data buffer length to fetch |
1122 | * |
1146 | * |
1123 | * Try to fetch EDID information by calling I2C driver functions. |
1147 | * Try to fetch EDID information by calling I2C driver functions. |
1124 | * |
1148 | * |
1125 | * Return: 0 on success or -1 on failure. |
1149 | * Return: 0 on success or -1 on failure. |
1126 | */ |
1150 | */ |
1127 | static int |
1151 | static int |
1128 | drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, |
- | |
1129 | int block, int len) |
1152 | drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len) |
- | 1153 | { |
|
1130 | { |
1154 | struct i2c_adapter *adapter = data; |
1131 | unsigned char start = block * EDID_LENGTH; |
1155 | unsigned char start = block * EDID_LENGTH; |
1132 | unsigned char segment = block >> 1; |
1156 | unsigned char segment = block >> 1; |
1133 | unsigned char xfers = segment ? 3 : 2; |
1157 | unsigned char xfers = segment ? 3 : 2; |
Line 1174... | Line 1198... | ||
1174 | } while (ret != xfers && --retries); |
1198 | } while (ret != xfers && --retries); |
Line 1175... | Line 1199... | ||
1175 | 1199 | ||
1176 | return ret == xfers ? 0 : -1; |
1200 | return ret == xfers ? 0 : -1; |
Line 1177... | Line -... | ||
1177 | } |
- | |
1178 | 1201 | } |
|
- | 1202 | ||
1179 | static bool drm_edid_is_zero(u8 *in_edid, int length) |
1203 | /** |
1180 | { |
1204 | * drm_do_get_edid - get EDID data using a custom EDID block read function |
- | 1205 | * @connector: connector we're probing |
|
1181 | if (memchr_inv(in_edid, 0, length)) |
1206 | * @get_edid_block: EDID block read function |
- | 1207 | * @data: private data passed to the block read function |
|
- | 1208 | * |
|
1182 | return false; |
1209 | * When the I2C adapter connected to the DDC bus is hidden behind a device that |
1183 | 1210 | * exposes a different interface to read EDID blocks this function can be used |
|
- | 1211 | * to get EDID data using a custom block read function. |
|
- | 1212 | * |
|
- | 1213 | * As in the general case the DDC bus is accessible by the kernel at the I2C |
|
1184 | return true; |
1214 | * level, drivers must make all reasonable efforts to expose it as an I2C |
- | 1215 | * adapter and use drm_get_edid() instead of abusing this function. |
|
1185 | } |
1216 | * |
1186 | 1217 | * Return: Pointer to valid EDID or NULL if we couldn't find any. |
|
- | 1218 | */ |
|
- | 1219 | struct edid *drm_do_get_edid(struct drm_connector *connector, |
|
- | 1220 | int (*get_edid_block)(void *data, u8 *buf, unsigned int block, |
|
1187 | static u8 * |
1221 | size_t len), |
1188 | drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) |
1222 | void *data) |
1189 | { |
1223 | { |
1190 | int i, j = 0, valid_extensions = 0; |
1224 | int i, j = 0, valid_extensions = 0; |
Line 1191... | Line 1225... | ||
1191 | u8 *block, *new; |
1225 | u8 *block, *new; |
1192 | bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS); |
1226 | bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS); |
Line 1193... | Line 1227... | ||
1193 | 1227 | ||
1194 | if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) |
1228 | if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) |
1195 | return NULL; |
1229 | return NULL; |
1196 | 1230 | ||
1197 | /* base block fetch */ |
1231 | /* base block fetch */ |
1198 | for (i = 0; i < 4; i++) { |
1232 | for (i = 0; i < 4; i++) { |
1199 | if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH)) |
1233 | if (get_edid_block(data, block, 0, EDID_LENGTH)) |
1200 | goto out; |
1234 | goto out; |
Line 1208... | Line 1242... | ||
1208 | if (i == 4) |
1242 | if (i == 4) |
1209 | goto carp; |
1243 | goto carp; |
Line 1210... | Line 1244... | ||
1210 | 1244 | ||
1211 | /* if there's no extensions, we're done */ |
1245 | /* if there's no extensions, we're done */ |
1212 | if (block[0x7e] == 0) |
1246 | if (block[0x7e] == 0) |
Line 1213... | Line 1247... | ||
1213 | return block; |
1247 | return (struct edid *)block; |
1214 | 1248 | ||
1215 | new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL); |
1249 | new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL); |
1216 | if (!new) |
1250 | if (!new) |
Line 1217... | Line 1251... | ||
1217 | goto out; |
1251 | goto out; |
1218 | block = new; |
1252 | block = new; |
1219 | 1253 | ||
1220 | for (j = 1; j <= block[0x7e]; j++) { |
1254 | for (j = 1; j <= block[0x7e]; j++) { |
1221 | for (i = 0; i < 4; i++) { |
1255 | for (i = 0; i < 4; i++) { |
1222 | if (drm_do_probe_ddc_edid(adapter, |
1256 | if (get_edid_block(data, |
1223 | block + (valid_extensions + 1) * EDID_LENGTH, |
1257 | block + (valid_extensions + 1) * EDID_LENGTH, |
1224 | j, EDID_LENGTH)) |
1258 | j, EDID_LENGTH)) |
Line 1245... | Line 1279... | ||
1245 | if (!new) |
1279 | if (!new) |
1246 | goto out; |
1280 | goto out; |
1247 | block = new; |
1281 | block = new; |
1248 | } |
1282 | } |
Line 1249... | Line 1283... | ||
1249 | 1283 | ||
Line 1250... | Line 1284... | ||
1250 | return block; |
1284 | return (struct edid *)block; |
1251 | 1285 | ||
1252 | carp: |
1286 | carp: |
1253 | if (print_bad_edid) { |
1287 | if (print_bad_edid) { |
Line 1258... | Line 1292... | ||
1258 | 1292 | ||
1259 | out: |
1293 | out: |
1260 | kfree(block); |
1294 | kfree(block); |
1261 | return NULL; |
1295 | return NULL; |
- | 1296 | } |
|
Line 1262... | Line 1297... | ||
1262 | } |
1297 | EXPORT_SYMBOL_GPL(drm_do_get_edid); |
1263 | 1298 | ||
1264 | /** |
1299 | /** |
1265 | * drm_probe_ddc() - probe DDC presence |
1300 | * drm_probe_ddc() - probe DDC presence |
Line 1287... | Line 1322... | ||
1287 | * Return: Pointer to valid EDID or NULL if we couldn't find any. |
1322 | * Return: Pointer to valid EDID or NULL if we couldn't find any. |
1288 | */ |
1323 | */ |
1289 | struct edid *drm_get_edid(struct drm_connector *connector, |
1324 | struct edid *drm_get_edid(struct drm_connector *connector, |
1290 | struct i2c_adapter *adapter) |
1325 | struct i2c_adapter *adapter) |
1291 | { |
1326 | { |
1292 | struct edid *edid = NULL; |
1327 | struct edid *edid; |
Line 1293... | Line 1328... | ||
1293 | 1328 | ||
1294 | if (drm_probe_ddc(adapter)) |
1329 | if (!drm_probe_ddc(adapter)) |
Line -... | Line 1330... | ||
- | 1330 | return NULL; |
|
- | 1331 | ||
- | 1332 | edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter); |
|
1295 | edid = (struct edid *)drm_do_get_edid(connector, adapter); |
1333 | if (edid) |
1296 | 1334 | drm_get_displayid(connector, edid); |
|
1297 | return edid; |
1335 | return edid; |
Line 1298... | Line 1336... | ||
1298 | } |
1336 | } |
Line 2101... | Line 2139... | ||
2101 | 2139 | ||
2102 | static int |
2140 | static int |
2103 | add_inferred_modes(struct drm_connector *connector, struct edid *edid) |
2141 | add_inferred_modes(struct drm_connector *connector, struct edid *edid) |
2104 | { |
2142 | { |
2105 | struct detailed_mode_closure closure = { |
2143 | struct detailed_mode_closure closure = { |
- | 2144 | .connector = connector, |
|
2106 | connector, edid, 0, 0, 0 |
2145 | .edid = edid, |
Line 2107... | Line 2146... | ||
2107 | }; |
2146 | }; |
2108 | 2147 | ||
2109 | if (version_greater(edid, 1, 0)) |
2148 | if (version_greater(edid, 1, 0)) |
Line 2167... | Line 2206... | ||
2167 | unsigned long est_bits = edid->established_timings.t1 | |
2206 | unsigned long est_bits = edid->established_timings.t1 | |
2168 | (edid->established_timings.t2 << 8) | |
2207 | (edid->established_timings.t2 << 8) | |
2169 | ((edid->established_timings.mfg_rsvd & 0x80) << 9); |
2208 | ((edid->established_timings.mfg_rsvd & 0x80) << 9); |
2170 | int i, modes = 0; |
2209 | int i, modes = 0; |
2171 | struct detailed_mode_closure closure = { |
2210 | struct detailed_mode_closure closure = { |
2172 | connector, edid, 0, 0, 0 |
2211 | .connector = connector, |
- | 2212 | .edid = edid, |
|
2173 | }; |
2213 | }; |
Line 2174... | Line 2214... | ||
2174 | 2214 | ||
2175 | for (i = 0; i <= EDID_EST_TIMINGS; i++) { |
2215 | for (i = 0; i <= EDID_EST_TIMINGS; i++) { |
2176 | if (est_bits & (1< |
2216 | if (est_bits & (1< |
Line 2225... | Line 2265... | ||
2225 | static int |
2265 | static int |
2226 | add_standard_modes(struct drm_connector *connector, struct edid *edid) |
2266 | add_standard_modes(struct drm_connector *connector, struct edid *edid) |
2227 | { |
2267 | { |
2228 | int i, modes = 0; |
2268 | int i, modes = 0; |
2229 | struct detailed_mode_closure closure = { |
2269 | struct detailed_mode_closure closure = { |
2230 | connector, edid, 0, 0, 0 |
2270 | .connector = connector, |
- | 2271 | .edid = edid, |
|
2231 | }; |
2272 | }; |
Line 2232... | Line 2273... | ||
2232 | 2273 | ||
2233 | for (i = 0; i < EDID_STD_TIMINGS; i++) { |
2274 | for (i = 0; i < EDID_STD_TIMINGS; i++) { |
Line 2311... | Line 2352... | ||
2311 | 2352 | ||
2312 | static int |
2353 | static int |
2313 | add_cvt_modes(struct drm_connector *connector, struct edid *edid) |
2354 | add_cvt_modes(struct drm_connector *connector, struct edid *edid) |
2314 | { |
2355 | { |
2315 | struct detailed_mode_closure closure = { |
2356 | struct detailed_mode_closure closure = { |
- | 2357 | .connector = connector, |
|
2316 | connector, edid, 0, 0, 0 |
2358 | .edid = edid, |
Line 2317... | Line 2359... | ||
2317 | }; |
2359 | }; |
2318 | 2360 | ||
Line 2355... | Line 2397... | ||
2355 | static int |
2397 | static int |
2356 | add_detailed_modes(struct drm_connector *connector, struct edid *edid, |
2398 | add_detailed_modes(struct drm_connector *connector, struct edid *edid, |
2357 | u32 quirks) |
2399 | u32 quirks) |
2358 | { |
2400 | { |
2359 | struct detailed_mode_closure closure = { |
2401 | struct detailed_mode_closure closure = { |
2360 | connector, |
2402 | .connector = connector, |
2361 | edid, |
2403 | .edid = edid, |
2362 | 1, |
2404 | .preferred = 1, |
2363 | quirks, |
2405 | .quirks = quirks, |
2364 | 0 |
- | |
2365 | }; |
2406 | }; |
Line 2366... | Line 2407... | ||
2366 | 2407 | ||
2367 | if (closure.preferred && !version_greater(edid, 1, 3)) |
2408 | if (closure.preferred && !version_greater(edid, 1, 3)) |
2368 | closure.preferred = |
2409 | closure.preferred = |
Line 2384... | Line 2425... | ||
2384 | #define EDID_CEA_VCDB_QS (1 << 6) |
2425 | #define EDID_CEA_VCDB_QS (1 << 6) |
Line 2385... | Line 2426... | ||
2385 | 2426 | ||
2386 | /* |
2427 | /* |
2387 | * Search EDID for CEA extension block. |
2428 | * Search EDID for CEA extension block. |
2388 | */ |
2429 | */ |
2389 | static u8 *drm_find_cea_extension(struct edid *edid) |
2430 | static u8 *drm_find_edid_extension(struct edid *edid, int ext_id) |
2390 | { |
2431 | { |
2391 | u8 *edid_ext = NULL; |
2432 | u8 *edid_ext = NULL; |
Line 2392... | Line 2433... | ||
2392 | int i; |
2433 | int i; |
Line 2396... | Line 2437... | ||
2396 | return NULL; |
2437 | return NULL; |
Line 2397... | Line 2438... | ||
2397 | 2438 | ||
2398 | /* Find CEA extension */ |
2439 | /* Find CEA extension */ |
2399 | for (i = 0; i < edid->extensions; i++) { |
2440 | for (i = 0; i < edid->extensions; i++) { |
2400 | edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1); |
2441 | edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1); |
2401 | if (edid_ext[0] == CEA_EXT) |
2442 | if (edid_ext[0] == ext_id) |
2402 | break; |
2443 | break; |
Line 2403... | Line 2444... | ||
2403 | } |
2444 | } |
2404 | 2445 | ||
Line 2405... | Line 2446... | ||
2405 | if (i == edid->extensions) |
2446 | if (i == edid->extensions) |
2406 | return NULL; |
2447 | return NULL; |
Line -... | Line 2448... | ||
- | 2448 | ||
- | 2449 | return edid_ext; |
|
- | 2450 | } |
|
- | 2451 | ||
- | 2452 | static u8 *drm_find_cea_extension(struct edid *edid) |
|
- | 2453 | { |
|
- | 2454 | return drm_find_edid_extension(edid, CEA_EXT); |
|
- | 2455 | } |
|
- | 2456 | ||
- | 2457 | static u8 *drm_find_displayid_extension(struct edid *edid) |
|
2407 | 2458 | { |
|
2408 | return edid_ext; |
2459 | return drm_find_edid_extension(edid, DISPLAYID_EXT); |
2409 | } |
2460 | } |
2410 | 2461 | ||
2411 | /* |
2462 | /* |
Line 3123... | Line 3174... | ||
3123 | break; |
3174 | break; |
3124 | } |
3175 | } |
3125 | } |
3176 | } |
3126 | } |
3177 | } |
3127 | eld[5] |= sad_count << 4; |
3178 | eld[5] |= sad_count << 4; |
3128 | eld[2] = (20 + mnl + sad_count * 3 + 3) / 4; |
- | |
Line -... | Line 3179... | ||
- | 3179 | ||
- | 3180 | eld[DRM_ELD_BASELINE_ELD_LEN] = |
|
- | 3181 | DIV_ROUND_UP(drm_eld_calc_baseline_block_size(eld), 4); |
|
3129 | 3182 | ||
- | 3183 | DRM_DEBUG_KMS("ELD size %d, SAD count %d\n", |
|
3130 | DRM_DEBUG_KMS("ELD size %d, SAD count %d\n", (int)eld[2], sad_count); |
3184 | drm_eld_size(eld), sad_count); |
3131 | } |
3185 | } |
Line 3132... | Line 3186... | ||
3132 | EXPORT_SYMBOL(drm_edid_to_eld); |
3186 | EXPORT_SYMBOL(drm_edid_to_eld); |
3133 | 3187 | ||
Line 3431... | Line 3485... | ||
3431 | EXPORT_SYMBOL(drm_rgb_quant_range_selectable); |
3485 | EXPORT_SYMBOL(drm_rgb_quant_range_selectable); |
Line 3432... | Line 3486... | ||
3432 | 3486 | ||
3433 | /** |
3487 | /** |
3434 | * drm_assign_hdmi_deep_color_info - detect whether monitor supports |
3488 | * drm_assign_hdmi_deep_color_info - detect whether monitor supports |
3435 | * hdmi deep color modes and update drm_display_info if so. |
- | |
3436 | * |
3489 | * hdmi deep color modes and update drm_display_info if so. |
3437 | * @edid: monitor EDID information |
3490 | * @edid: monitor EDID information |
3438 | * @info: Updated with maximum supported deep color bpc and color format |
3491 | * @info: Updated with maximum supported deep color bpc and color format |
- | 3492 | * if deep color supported. |
|
3439 | * if deep color supported. |
3493 | * @connector: DRM connector, used only for debug output |
3440 | * |
3494 | * |
3441 | * Parse the CEA extension according to CEA-861-B. |
3495 | * Parse the CEA extension according to CEA-861-B. |
3442 | * Return true if HDMI deep color supported, false if not or unknown. |
3496 | * Return true if HDMI deep color supported, false if not or unknown. |
3443 | */ |
3497 | */ |
Line 3863... | Line 3917... | ||
3863 | frame->s3d_struct = s3d_structure_from_display_mode(mode); |
3917 | frame->s3d_struct = s3d_structure_from_display_mode(mode); |
Line 3864... | Line 3918... | ||
3864 | 3918 | ||
3865 | return 0; |
3919 | return 0; |
3866 | } |
3920 | } |
- | 3921 | EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode); |
|
- | 3922 | ||
- | 3923 | static int drm_parse_display_id(struct drm_connector *connector, |
|
- | 3924 | u8 *displayid, int length, |
|
- | 3925 | bool is_edid_extension) |
|
- | 3926 | { |
|
- | 3927 | /* if this is an EDID extension the first byte will be 0x70 */ |
|
- | 3928 | int idx = 0; |
|
- | 3929 | struct displayid_hdr *base; |
|
- | 3930 | struct displayid_block *block; |
|
- | 3931 | u8 csum = 0; |
|
- | 3932 | int i; |
|
- | 3933 | ||
- | 3934 | if (is_edid_extension) |
|
- | 3935 | idx = 1; |
|
- | 3936 | ||
- | 3937 | base = (struct displayid_hdr *)&displayid[idx]; |
|
- | 3938 | ||
- | 3939 | DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n", |
|
- | 3940 | base->rev, base->bytes, base->prod_id, base->ext_count); |
|
- | 3941 | ||
- | 3942 | if (base->bytes + 5 > length - idx) |
|
- | 3943 | return -EINVAL; |
|
- | 3944 | ||
- | 3945 | for (i = idx; i <= base->bytes + 5; i++) { |
|
- | 3946 | csum += displayid[i]; |
|
- | 3947 | } |
|
- | 3948 | if (csum) { |
|
- | 3949 | DRM_ERROR("DisplayID checksum invalid, remainder is %d\n", csum); |
|
- | 3950 | return -EINVAL; |
|
- | 3951 | } |
|
- | 3952 | ||
- | 3953 | block = (struct displayid_block *)&displayid[idx + 4]; |
|
- | 3954 | DRM_DEBUG_KMS("block id %d, rev %d, len %d\n", |
|
- | 3955 | block->tag, block->rev, block->num_bytes); |
|
- | 3956 | ||
- | 3957 | switch (block->tag) { |
|
- | 3958 | case DATA_BLOCK_TILED_DISPLAY: { |
|
- | 3959 | struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block; |
|
- | 3960 | ||
- | 3961 | u16 w, h; |
|
- | 3962 | u8 tile_v_loc, tile_h_loc; |
|
- | 3963 | u8 num_v_tile, num_h_tile; |
|
- | 3964 | struct drm_tile_group *tg; |
|
- | 3965 | ||
- | 3966 | w = tile->tile_size[0] | tile->tile_size[1] << 8; |
|
- | 3967 | h = tile->tile_size[2] | tile->tile_size[3] << 8; |
|
- | 3968 | ||
- | 3969 | num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30); |
|
- | 3970 | num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30); |
|
- | 3971 | tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4); |
|
- | 3972 | tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4); |
|
- | 3973 | ||
- | 3974 | connector->has_tile = true; |
|
- | 3975 | if (tile->tile_cap & 0x80) |
|
- | 3976 | connector->tile_is_single_monitor = true; |
|
- | 3977 | ||
- | 3978 | connector->num_h_tile = num_h_tile + 1; |
|
- | 3979 | connector->num_v_tile = num_v_tile + 1; |
|
- | 3980 | connector->tile_h_loc = tile_h_loc; |
|
- | 3981 | connector->tile_v_loc = tile_v_loc; |
|
- | 3982 | connector->tile_h_size = w + 1; |
|
- | 3983 | connector->tile_v_size = h + 1; |
|
- | 3984 | ||
- | 3985 | DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap); |
|
- | 3986 | DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1); |
|
- | 3987 | DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n", |
|
- | 3988 | num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc); |
|
- | 3989 | DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]); |
|
- | 3990 | ||
- | 3991 | tg = drm_mode_get_tile_group(connector->dev, tile->topology_id); |
|
- | 3992 | if (!tg) { |
|
- | 3993 | tg = drm_mode_create_tile_group(connector->dev, tile->topology_id); |
|
- | 3994 | } |
|
- | 3995 | if (!tg) |
|
- | 3996 | return -ENOMEM; |
|
- | 3997 | ||
- | 3998 | if (connector->tile_group != tg) { |
|
- | 3999 | /* if we haven't got a pointer, |
|
- | 4000 | take the reference, drop ref to old tile group */ |
|
- | 4001 | if (connector->tile_group) { |
|
- | 4002 | drm_mode_put_tile_group(connector->dev, connector->tile_group); |
|
- | 4003 | } |
|
- | 4004 | connector->tile_group = tg; |
|
- | 4005 | } else |
|
- | 4006 | /* if same tile group, then release the ref we just took. */ |
|
- | 4007 | drm_mode_put_tile_group(connector->dev, tg); |
|
- | 4008 | } |
|
- | 4009 | break; |
|
- | 4010 | default: |
|
- | 4011 | printk("unknown displayid tag %d\n", block->tag); |
|
- | 4012 | break; |
|
- | 4013 | } |
|
- | 4014 | return 0; |
|
- | 4015 | } |
|
- | 4016 | ||
- | 4017 | static void drm_get_displayid(struct drm_connector *connector, |
|
- | 4018 | struct edid *edid) |
|
- | 4019 | { |
|
- | 4020 | void *displayid = NULL; |
|
- | 4021 | int ret; |
|
- | 4022 | connector->has_tile = false; |
|
- | 4023 | displayid = drm_find_displayid_extension(edid); |
|
- | 4024 | if (!displayid) { |
|
- | 4025 | /* drop reference to any tile group we had */ |
|
- | 4026 | goto out_drop_ref; |
|
- | 4027 | } |
|
- | 4028 | ||
- | 4029 | ret = drm_parse_display_id(connector, displayid, EDID_LENGTH, true); |
|
- | 4030 | if (ret < 0) |
|
- | 4031 | goto out_drop_ref; |
|
- | 4032 | if (!connector->has_tile) |
|
- | 4033 | goto out_drop_ref; |
|
- | 4034 | return; |
|
- | 4035 | out_drop_ref: |
|
- | 4036 | if (connector->tile_group) { |
|
- | 4037 | drm_mode_put_tile_group(connector->dev, connector->tile_group); |
|
- | 4038 | connector->tile_group = NULL; |
|
- | 4039 | } |
|
- | 4040 | return; |