aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_edid.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_edid.c')
-rw-r--r--drivers/gpu/drm/drm_edid.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 90d76bacff17..3c0d2b3aed76 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -109,7 +109,9 @@ static struct edid_quirk {
109 109
110 110
111/* Valid EDID header has these bytes */ 111/* Valid EDID header has these bytes */
112static u8 edid_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; 112static const u8 edid_header[] = {
113 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
114};
113 115
114/** 116/**
115 * edid_is_valid - sanity check EDID data 117 * edid_is_valid - sanity check EDID data
@@ -500,6 +502,19 @@ static struct drm_display_mode *drm_find_dmt(struct drm_device *dev,
500 } 502 }
501 return mode; 503 return mode;
502} 504}
505
506/*
507 * 0 is reserved. The spec says 0x01 fill for unused timings. Some old
508 * monitors fill with ascii space (0x20) instead.
509 */
510static int
511bad_std_timing(u8 a, u8 b)
512{
513 return (a == 0x00 && b == 0x00) ||
514 (a == 0x01 && b == 0x01) ||
515 (a == 0x20 && b == 0x20);
516}
517
503/** 518/**
504 * drm_mode_std - convert standard mode info (width, height, refresh) into mode 519 * drm_mode_std - convert standard mode info (width, height, refresh) into mode
505 * @t: standard timing params 520 * @t: standard timing params
@@ -513,6 +528,7 @@ static struct drm_display_mode *drm_find_dmt(struct drm_device *dev,
513 */ 528 */
514struct drm_display_mode *drm_mode_std(struct drm_device *dev, 529struct drm_display_mode *drm_mode_std(struct drm_device *dev,
515 struct std_timing *t, 530 struct std_timing *t,
531 int revision,
516 int timing_level) 532 int timing_level)
517{ 533{
518 struct drm_display_mode *mode; 534 struct drm_display_mode *mode;
@@ -523,14 +539,20 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
523 unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK) 539 unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK)
524 >> EDID_TIMING_VFREQ_SHIFT; 540 >> EDID_TIMING_VFREQ_SHIFT;
525 541
542 if (bad_std_timing(t->hsize, t->vfreq_aspect))
543 return NULL;
544
526 /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */ 545 /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */
527 hsize = t->hsize * 8 + 248; 546 hsize = t->hsize * 8 + 248;
528 /* vrefresh_rate = vfreq + 60 */ 547 /* vrefresh_rate = vfreq + 60 */
529 vrefresh_rate = vfreq + 60; 548 vrefresh_rate = vfreq + 60;
530 /* the vdisplay is calculated based on the aspect ratio */ 549 /* the vdisplay is calculated based on the aspect ratio */
531 if (aspect_ratio == 0) 550 if (aspect_ratio == 0) {
532 vsize = (hsize * 10) / 16; 551 if (revision < 3)
533 else if (aspect_ratio == 1) 552 vsize = hsize;
553 else
554 vsize = (hsize * 10) / 16;
555 } else if (aspect_ratio == 1)
534 vsize = (hsize * 3) / 4; 556 vsize = (hsize * 3) / 4;
535 else if (aspect_ratio == 2) 557 else if (aspect_ratio == 2)
536 vsize = (hsize * 4) / 5; 558 vsize = (hsize * 4) / 5;
@@ -538,7 +560,8 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
538 vsize = (hsize * 9) / 16; 560 vsize = (hsize * 9) / 16;
539 /* HDTV hack */ 561 /* HDTV hack */
540 if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) { 562 if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) {
541 mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); 563 mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0,
564 false);
542 mode->hdisplay = 1366; 565 mode->hdisplay = 1366;
543 mode->vsync_start = mode->vsync_start - 1; 566 mode->vsync_start = mode->vsync_start - 1;
544 mode->vsync_end = mode->vsync_end - 1; 567 mode->vsync_end = mode->vsync_end - 1;
@@ -557,7 +580,8 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
557 mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); 580 mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
558 break; 581 break;
559 case LEVEL_CVT: 582 case LEVEL_CVT:
560 mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); 583 mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0,
584 false);
561 break; 585 break;
562 } 586 }
563 return mode; 587 return mode;
@@ -779,7 +803,7 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid
779 continue; 803 continue;
780 804
781 newmode = drm_mode_std(dev, &edid->standard_timings[i], 805 newmode = drm_mode_std(dev, &edid->standard_timings[i],
782 timing_level); 806 edid->revision, timing_level);
783 if (newmode) { 807 if (newmode) {
784 drm_mode_probed_add(connector, newmode); 808 drm_mode_probed_add(connector, newmode);
785 modes++; 809 modes++;
@@ -829,13 +853,13 @@ static int add_detailed_info(struct drm_connector *connector,
829 case EDID_DETAIL_MONITOR_CPDATA: 853 case EDID_DETAIL_MONITOR_CPDATA:
830 break; 854 break;
831 case EDID_DETAIL_STD_MODES: 855 case EDID_DETAIL_STD_MODES:
832 /* Five modes per detailed section */ 856 for (j = 0; j < 6; i++) {
833 for (j = 0; j < 5; i++) {
834 struct std_timing *std; 857 struct std_timing *std;
835 struct drm_display_mode *newmode; 858 struct drm_display_mode *newmode;
836 859
837 std = &data->data.timings[j]; 860 std = &data->data.timings[j];
838 newmode = drm_mode_std(dev, std, 861 newmode = drm_mode_std(dev, std,
862 edid->revision,
839 timing_level); 863 timing_level);
840 if (newmode) { 864 if (newmode) {
841 drm_mode_probed_add(connector, newmode); 865 drm_mode_probed_add(connector, newmode);
@@ -964,7 +988,9 @@ static int add_detailed_info_eedid(struct drm_connector *connector,
964 struct drm_display_mode *newmode; 988 struct drm_display_mode *newmode;
965 989
966 std = &data->data.timings[j]; 990 std = &data->data.timings[j];
967 newmode = drm_mode_std(dev, std, timing_level); 991 newmode = drm_mode_std(dev, std,
992 edid->revision,
993 timing_level);
968 if (newmode) { 994 if (newmode) {
969 drm_mode_probed_add(connector, newmode); 995 drm_mode_probed_add(connector, newmode);
970 modes++; 996 modes++;