aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_edid.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-12-07 22:52:41 -0500
committerDave Airlie <airlied@redhat.com>2009-12-07 22:52:41 -0500
commit1bd049fa895f9c6743f38b52ce14775f5a31ea63 (patch)
treecb9163ac1c20f7fbdbde42eaab8013d0c3734aed /drivers/gpu/drm/drm_edid.c
parent22763c5cf3690a681551162c15d34d935308c8d7 (diff)
parentb0a007dc27d8d3ff3db07b3ea997323d9330f770 (diff)
Merge branch 'drm-core-next' into drm-linus
Bring all core drm changes into 2.6.32 tree and resolve the conflict that occurs. Conflicts: drivers/gpu/drm/drm_fb_helper.c
Diffstat (limited to 'drivers/gpu/drm/drm_edid.c')
-rw-r--r--drivers/gpu/drm/drm_edid.c328
1 files changed, 204 insertions, 124 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index b54ba63d506e..c39b26f1abed 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -123,18 +123,20 @@ static const u8 edid_header[] = {
123 */ 123 */
124static bool edid_is_valid(struct edid *edid) 124static bool edid_is_valid(struct edid *edid)
125{ 125{
126 int i; 126 int i, score = 0;
127 u8 csum = 0; 127 u8 csum = 0;
128 u8 *raw_edid = (u8 *)edid; 128 u8 *raw_edid = (u8 *)edid;
129 129
130 if (memcmp(edid->header, edid_header, sizeof(edid_header))) 130 for (i = 0; i < sizeof(edid_header); i++)
131 goto bad; 131 if (raw_edid[i] == edid_header[i])
132 if (edid->version != 1) { 132 score++;
133 DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version); 133
134 if (score == 8) ;
135 else if (score >= 6) {
136 DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
137 memcpy(raw_edid, edid_header, sizeof(edid_header));
138 } else
134 goto bad; 139 goto bad;
135 }
136 if (edid->revision > 4)
137 DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
138 140
139 for (i = 0; i < EDID_LENGTH; i++) 141 for (i = 0; i < EDID_LENGTH; i++)
140 csum += raw_edid[i]; 142 csum += raw_edid[i];
@@ -143,6 +145,14 @@ static bool edid_is_valid(struct edid *edid)
143 goto bad; 145 goto bad;
144 } 146 }
145 147
148 if (edid->version != 1) {
149 DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
150 goto bad;
151 }
152
153 if (edid->revision > 4)
154 DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
155
146 return 1; 156 return 1;
147 157
148bad: 158bad:
@@ -481,16 +491,17 @@ static struct drm_display_mode drm_dmt_modes[] = {
481 3048, 3536, 0, 1600, 1603, 1609, 1682, 0, 491 3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
482 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, 492 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
483}; 493};
494static const int drm_num_dmt_modes =
495 sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
484 496
485static struct drm_display_mode *drm_find_dmt(struct drm_device *dev, 497static struct drm_display_mode *drm_find_dmt(struct drm_device *dev,
486 int hsize, int vsize, int fresh) 498 int hsize, int vsize, int fresh)
487{ 499{
488 int i, count; 500 int i;
489 struct drm_display_mode *ptr, *mode; 501 struct drm_display_mode *ptr, *mode;
490 502
491 count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
492 mode = NULL; 503 mode = NULL;
493 for (i = 0; i < count; i++) { 504 for (i = 0; i < drm_num_dmt_modes; i++) {
494 ptr = &drm_dmt_modes[i]; 505 ptr = &drm_dmt_modes[i];
495 if (hsize == ptr->hdisplay && 506 if (hsize == ptr->hdisplay &&
496 vsize == ptr->vdisplay && 507 vsize == ptr->vdisplay &&
@@ -834,8 +845,165 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid
834 return modes; 845 return modes;
835} 846}
836 847
848/*
849 * XXX fix this for:
850 * - GTF secondary curve formula
851 * - EDID 1.4 range offsets
852 * - CVT extended bits
853 */
854static bool
855mode_in_range(struct drm_display_mode *mode, struct detailed_timing *timing)
856{
857 struct detailed_data_monitor_range *range;
858 int hsync, vrefresh;
859
860 range = &timing->data.other_data.data.range;
861
862 hsync = drm_mode_hsync(mode);
863 vrefresh = drm_mode_vrefresh(mode);
864
865 if (hsync < range->min_hfreq_khz || hsync > range->max_hfreq_khz)
866 return false;
867
868 if (vrefresh < range->min_vfreq || vrefresh > range->max_vfreq)
869 return false;
870
871 if (range->pixel_clock_mhz && range->pixel_clock_mhz != 0xff) {
872 /* be forgiving since it's in units of 10MHz */
873 int max_clock = range->pixel_clock_mhz * 10 + 9;
874 max_clock *= 1000;
875 if (mode->clock > max_clock)
876 return false;
877 }
878
879 return true;
880}
881
882/*
883 * XXX If drm_dmt_modes ever regrows the CVT-R modes (and it will) this will
884 * need to account for them.
885 */
886static int drm_gtf_modes_for_range(struct drm_connector *connector,
887 struct detailed_timing *timing)
888{
889 int i, modes = 0;
890 struct drm_display_mode *newmode;
891 struct drm_device *dev = connector->dev;
892
893 for (i = 0; i < drm_num_dmt_modes; i++) {
894 if (mode_in_range(drm_dmt_modes + i, timing)) {
895 newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]);
896 if (newmode) {
897 drm_mode_probed_add(connector, newmode);
898 modes++;
899 }
900 }
901 }
902
903 return modes;
904}
905
906static int drm_cvt_modes(struct drm_connector *connector,
907 struct detailed_timing *timing)
908{
909 int i, j, modes = 0;
910 struct drm_display_mode *newmode;
911 struct drm_device *dev = connector->dev;
912 struct cvt_timing *cvt;
913 const int rates[] = { 60, 85, 75, 60, 50 };
914
915 for (i = 0; i < 4; i++) {
916 int width, height;
917 cvt = &(timing->data.other_data.data.cvt[i]);
918
919 height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 8) + 1) * 2;
920 switch (cvt->code[1] & 0xc0) {
921 case 0x00:
922 width = height * 4 / 3;
923 break;
924 case 0x40:
925 width = height * 16 / 9;
926 break;
927 case 0x80:
928 width = height * 16 / 10;
929 break;
930 case 0xc0:
931 width = height * 15 / 9;
932 break;
933 }
934
935 for (j = 1; j < 5; j++) {
936 if (cvt->code[2] & (1 << j)) {
937 newmode = drm_cvt_mode(dev, width, height,
938 rates[j], j == 0,
939 false, false);
940 if (newmode) {
941 drm_mode_probed_add(connector, newmode);
942 modes++;
943 }
944 }
945 }
946 }
947
948 return modes;
949}
950
951static int add_detailed_modes(struct drm_connector *connector,
952 struct detailed_timing *timing,
953 struct edid *edid, u32 quirks, int preferred)
954{
955 int i, modes = 0;
956 struct detailed_non_pixel *data = &timing->data.other_data;
957 int timing_level = standard_timing_level(edid);
958 int gtf = (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF);
959 struct drm_display_mode *newmode;
960 struct drm_device *dev = connector->dev;
961
962 if (timing->pixel_clock) {
963 newmode = drm_mode_detailed(dev, edid, timing, quirks);
964 if (!newmode)
965 return 0;
966
967 if (preferred)
968 newmode->type |= DRM_MODE_TYPE_PREFERRED;
969
970 drm_mode_probed_add(connector, newmode);
971 return 1;
972 }
973
974 /* other timing types */
975 switch (data->type) {
976 case EDID_DETAIL_MONITOR_RANGE:
977 if (gtf)
978 modes += drm_gtf_modes_for_range(connector, timing);
979 break;
980 case EDID_DETAIL_STD_MODES:
981 /* Six modes per detailed section */
982 for (i = 0; i < 6; i++) {
983 struct std_timing *std;
984 struct drm_display_mode *newmode;
985
986 std = &data->data.timings[i];
987 newmode = drm_mode_std(dev, std, edid->revision,
988 timing_level);
989 if (newmode) {
990 drm_mode_probed_add(connector, newmode);
991 modes++;
992 }
993 }
994 break;
995 case EDID_DETAIL_CVT_3BYTE:
996 modes += drm_cvt_modes(connector, timing);
997 break;
998 default:
999 break;
1000 }
1001
1002 return modes;
1003}
1004
837/** 1005/**
838 * add_detailed_modes - get detailed mode info from EDID data 1006 * add_detailed_info - get detailed mode info from EDID data
839 * @connector: attached connector 1007 * @connector: attached connector
840 * @edid: EDID block to scan 1008 * @edid: EDID block to scan
841 * @quirks: quirks to apply 1009 * @quirks: quirks to apply
@@ -846,67 +1014,24 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid
846static int add_detailed_info(struct drm_connector *connector, 1014static int add_detailed_info(struct drm_connector *connector,
847 struct edid *edid, u32 quirks) 1015 struct edid *edid, u32 quirks)
848{ 1016{
849 struct drm_device *dev = connector->dev; 1017 int i, modes = 0;
850 int i, j, modes = 0;
851 int timing_level;
852
853 timing_level = standard_timing_level(edid);
854 1018
855 for (i = 0; i < EDID_DETAILED_TIMINGS; i++) { 1019 for (i = 0; i < EDID_DETAILED_TIMINGS; i++) {
856 struct detailed_timing *timing = &edid->detailed_timings[i]; 1020 struct detailed_timing *timing = &edid->detailed_timings[i];
857 struct detailed_non_pixel *data = &timing->data.other_data; 1021 int preferred = (i == 0) && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING);
858 struct drm_display_mode *newmode;
859
860 /* X server check is version 1.1 or higher */
861 if (edid->version == 1 && edid->revision >= 1 &&
862 !timing->pixel_clock) {
863 /* Other timing or info */
864 switch (data->type) {
865 case EDID_DETAIL_MONITOR_SERIAL:
866 break;
867 case EDID_DETAIL_MONITOR_STRING:
868 break;
869 case EDID_DETAIL_MONITOR_RANGE:
870 /* Get monitor range data */
871 break;
872 case EDID_DETAIL_MONITOR_NAME:
873 break;
874 case EDID_DETAIL_MONITOR_CPDATA:
875 break;
876 case EDID_DETAIL_STD_MODES:
877 for (j = 0; j < 6; i++) {
878 struct std_timing *std;
879 struct drm_display_mode *newmode;
880
881 std = &data->data.timings[j];
882 newmode = drm_mode_std(dev, std,
883 edid->revision,
884 timing_level);
885 if (newmode) {
886 drm_mode_probed_add(connector, newmode);
887 modes++;
888 }
889 }
890 break;
891 default:
892 break;
893 }
894 } else {
895 newmode = drm_mode_detailed(dev, edid, timing, quirks);
896 if (!newmode)
897 continue;
898 1022
899 /* First detailed mode is preferred */ 1023 /* In 1.0, only timings are allowed */
900 if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING)) 1024 if (!timing->pixel_clock && edid->version == 1 &&
901 newmode->type |= DRM_MODE_TYPE_PREFERRED; 1025 edid->revision == 0)
902 drm_mode_probed_add(connector, newmode); 1026 continue;
903 1027
904 modes++; 1028 modes += add_detailed_modes(connector, timing, edid, quirks,
905 } 1029 preferred);
906 } 1030 }
907 1031
908 return modes; 1032 return modes;
909} 1033}
1034
910/** 1035/**
911 * add_detailed_mode_eedid - get detailed mode info from addtional timing 1036 * add_detailed_mode_eedid - get detailed mode info from addtional timing
912 * EDID block 1037 * EDID block
@@ -920,12 +1045,9 @@ static int add_detailed_info(struct drm_connector *connector,
920static int add_detailed_info_eedid(struct drm_connector *connector, 1045static int add_detailed_info_eedid(struct drm_connector *connector,
921 struct edid *edid, u32 quirks) 1046 struct edid *edid, u32 quirks)
922{ 1047{
923 struct drm_device *dev = connector->dev; 1048 int i, modes = 0;
924 int i, j, modes = 0;
925 char *edid_ext = NULL; 1049 char *edid_ext = NULL;
926 struct detailed_timing *timing; 1050 struct detailed_timing *timing;
927 struct detailed_non_pixel *data;
928 struct drm_display_mode *newmode;
929 int edid_ext_num; 1051 int edid_ext_num;
930 int start_offset, end_offset; 1052 int start_offset, end_offset;
931 int timing_level; 1053 int timing_level;
@@ -976,51 +1098,7 @@ static int add_detailed_info_eedid(struct drm_connector *connector,
976 for (i = start_offset; i < end_offset; 1098 for (i = start_offset; i < end_offset;
977 i += sizeof(struct detailed_timing)) { 1099 i += sizeof(struct detailed_timing)) {
978 timing = (struct detailed_timing *)(edid_ext + i); 1100 timing = (struct detailed_timing *)(edid_ext + i);
979 data = &timing->data.other_data; 1101 modes += add_detailed_modes(connector, timing, edid, quirks, 0);
980 /* Detailed mode timing */
981 if (timing->pixel_clock) {
982 newmode = drm_mode_detailed(dev, edid, timing, quirks);
983 if (!newmode)
984 continue;
985
986 drm_mode_probed_add(connector, newmode);
987
988 modes++;
989 continue;
990 }
991
992 /* Other timing or info */
993 switch (data->type) {
994 case EDID_DETAIL_MONITOR_SERIAL:
995 break;
996 case EDID_DETAIL_MONITOR_STRING:
997 break;
998 case EDID_DETAIL_MONITOR_RANGE:
999 /* Get monitor range data */
1000 break;
1001 case EDID_DETAIL_MONITOR_NAME:
1002 break;
1003 case EDID_DETAIL_MONITOR_CPDATA:
1004 break;
1005 case EDID_DETAIL_STD_MODES:
1006 /* Five modes per detailed section */
1007 for (j = 0; j < 5; i++) {
1008 struct std_timing *std;
1009 struct drm_display_mode *newmode;
1010
1011 std = &data->data.timings[j];
1012 newmode = drm_mode_std(dev, std,
1013 edid->revision,
1014 timing_level);
1015 if (newmode) {
1016 drm_mode_probed_add(connector, newmode);
1017 modes++;
1018 }
1019 }
1020 break;
1021 default:
1022 break;
1023 }
1024 } 1102 }
1025 1103
1026 return modes; 1104 return modes;
@@ -1066,19 +1144,19 @@ static int drm_ddc_read_edid(struct drm_connector *connector,
1066 struct i2c_adapter *adapter, 1144 struct i2c_adapter *adapter,
1067 char *buf, int len) 1145 char *buf, int len)
1068{ 1146{
1069 int ret; 1147 int i;
1070 1148
1071 ret = drm_do_probe_ddc_edid(adapter, buf, len); 1149 for (i = 0; i < 4; i++) {
1072 if (ret != 0) { 1150 if (drm_do_probe_ddc_edid(adapter, buf, len))
1073 goto end; 1151 return -1;
1074 } 1152 if (edid_is_valid((struct edid *)buf))
1075 if (!edid_is_valid((struct edid *)buf)) { 1153 return 0;
1076 dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
1077 drm_get_connector_name(connector));
1078 ret = -1;
1079 } 1154 }
1080end: 1155
1081 return ret; 1156 /* repeated checksum failures; warn, but carry on */
1157 dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
1158 drm_get_connector_name(connector));
1159 return -1;
1082} 1160}
1083 1161
1084/** 1162/**
@@ -1296,6 +1374,8 @@ int drm_add_modes_noedid(struct drm_connector *connector,
1296 ptr->vdisplay > vdisplay) 1374 ptr->vdisplay > vdisplay)
1297 continue; 1375 continue;
1298 } 1376 }
1377 if (drm_mode_vrefresh(ptr) > 61)
1378 continue;
1299 mode = drm_mode_duplicate(dev, ptr); 1379 mode = drm_mode_duplicate(dev, ptr);
1300 if (mode) { 1380 if (mode) {
1301 drm_mode_probed_add(connector, mode); 1381 drm_mode_probed_add(connector, mode);