Rev 1179 | Rev 1246 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1179 | Rev 1221 | ||
---|---|---|---|
Line 24... | Line 24... | ||
24 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
24 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
26 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
26 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
27 | * DEALINGS IN THE SOFTWARE. |
27 | * DEALINGS IN THE SOFTWARE. |
28 | */ |
28 | */ |
29 | //#include |
29 | #include |
30 | #include |
- | |
31 | #include |
- | |
32 | - | ||
33 | #include |
30 | #include |
34 | #include |
31 | #include |
35 | #include "drmP.h" |
32 | #include "drmP.h" |
36 | #include "drm_edid.h" |
33 | #include "drm_edid.h" |
Line 110... | Line 107... | ||
110 | { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 }, |
107 | { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 }, |
111 | }; |
108 | }; |
Line 112... | Line 109... | ||
112 | 109 | ||
- | 110 | ||
113 | 111 | /* Valid EDID header has these bytes */ |
|
- | 112 | static const u8 edid_header[] = { |
|
Line 114... | Line 113... | ||
114 | /* Valid EDID header has these bytes */ |
113 | 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 |
115 | static u8 edid_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; |
114 | }; |
116 | 115 | ||
117 | /** |
116 | /** |
Line 501... | Line 500... | ||
501 | break; |
500 | break; |
502 | } |
501 | } |
503 | } |
502 | } |
504 | return mode; |
503 | return mode; |
505 | } |
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 | */ |
|
- | 510 | static int |
|
- | 511 | bad_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 | ||
506 | /** |
518 | /** |
507 | * 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 |
508 | * @t: standard timing params |
520 | * @t: standard timing params |
- | 521 | * @timing_level: standard timing level |
|
509 | * |
522 | * |
510 | * Take the standard timing params (in this case width, aspect, and refresh) |
523 | * Take the standard timing params (in this case width, aspect, and refresh) |
511 | * and convert them into a real mode using CVT. |
524 | * and convert them into a real mode using CVT/GTF/DMT. |
512 | * |
525 | * |
513 | * Punts for now, but should eventually use the FB layer's CVT based mode |
526 | * Punts for now, but should eventually use the FB layer's CVT based mode |
514 | * generation code. |
527 | * generation code. |
515 | */ |
528 | */ |
516 | struct drm_display_mode *drm_mode_std(struct drm_device *dev, |
529 | struct drm_display_mode *drm_mode_std(struct drm_device *dev, |
517 | struct std_timing *t, |
530 | struct std_timing *t, |
- | 531 | int revision, |
|
518 | int timing_level) |
532 | int timing_level) |
519 | { |
533 | { |
520 | struct drm_display_mode *mode; |
534 | struct drm_display_mode *mode; |
521 | int hsize, vsize; |
535 | int hsize, vsize; |
522 | int vrefresh_rate; |
536 | int vrefresh_rate; |
523 | unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) |
537 | unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) |
524 | >> EDID_TIMING_ASPECT_SHIFT; |
538 | >> EDID_TIMING_ASPECT_SHIFT; |
525 | unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK) |
539 | unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK) |
526 | >> EDID_TIMING_VFREQ_SHIFT; |
540 | >> EDID_TIMING_VFREQ_SHIFT; |
Line -... | Line 541... | ||
- | 541 | ||
- | 542 | if (bad_std_timing(t->hsize, t->vfreq_aspect)) |
|
- | 543 | return NULL; |
|
527 | 544 | ||
528 | /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */ |
545 | /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */ |
529 | hsize = t->hsize * 8 + 248; |
546 | hsize = t->hsize * 8 + 248; |
530 | /* vrefresh_rate = vfreq + 60 */ |
547 | /* vrefresh_rate = vfreq + 60 */ |
531 | vrefresh_rate = vfreq + 60; |
548 | vrefresh_rate = vfreq + 60; |
532 | /* the vdisplay is calculated based on the aspect ratio */ |
- | |
533 | 549 | /* the vdisplay is calculated based on the aspect ratio */ |
|
- | 550 | if (aspect_ratio == 0) { |
|
- | 551 | if (revision < 3) |
|
- | 552 | vsize = hsize; |
|
534 | if (aspect_ratio == 0) |
553 | else |
535 | vsize = (hsize * 10) / 16; |
554 | vsize = (hsize * 10) / 16; |
536 | else if (aspect_ratio == 1) |
555 | } else if (aspect_ratio == 1) |
537 | vsize = (hsize * 3) / 4; |
556 | vsize = (hsize * 3) / 4; |
538 | else if (aspect_ratio == 2) |
557 | else if (aspect_ratio == 2) |
539 | vsize = (hsize * 4) / 5; |
558 | vsize = (hsize * 4) / 5; |
540 | else |
559 | else |
541 | vsize = (hsize * 9) / 16; |
560 | vsize = (hsize * 9) / 16; |
542 | /* HDTV hack */ |
561 | /* HDTV hack */ |
543 | if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) { |
562 | if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) { |
- | 563 | mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0, |
|
544 | mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); |
564 | false); |
545 | mode->hdisplay = 1366; |
565 | mode->hdisplay = 1366; |
546 | mode->vsync_start = mode->vsync_start - 1; |
566 | mode->vsync_start = mode->vsync_start - 1; |
547 | mode->vsync_end = mode->vsync_end - 1; |
567 | mode->vsync_end = mode->vsync_end - 1; |
548 | return mode; |
568 | return mode; |
Line 558... | Line 578... | ||
558 | break; |
578 | break; |
559 | case LEVEL_GTF: |
579 | case LEVEL_GTF: |
560 | mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); |
580 | mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); |
561 | break; |
581 | break; |
562 | case LEVEL_CVT: |
582 | case LEVEL_CVT: |
563 | 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); |
|
564 | break; |
585 | break; |
565 | } |
586 | } |
566 | return mode; |
587 | return mode; |
567 | } |
588 | } |
Line 780... | Line 801... | ||
780 | /* If std timings bytes are 1, 1 it's empty */ |
801 | /* If std timings bytes are 1, 1 it's empty */ |
781 | if (t->hsize == 1 && t->vfreq_aspect == 1) |
802 | if (t->hsize == 1 && t->vfreq_aspect == 1) |
782 | continue; |
803 | continue; |
Line 783... | Line 804... | ||
783 | 804 | ||
784 | newmode = drm_mode_std(dev, &edid->standard_timings[i], |
805 | newmode = drm_mode_std(dev, &edid->standard_timings[i], |
785 | timing_level); |
806 | edid->revision, timing_level); |
786 | if (newmode) { |
807 | if (newmode) { |
787 | drm_mode_probed_add(connector, newmode); |
808 | drm_mode_probed_add(connector, newmode); |
788 | modes++; |
809 | modes++; |
789 | } |
810 | } |
Line 830... | Line 851... | ||
830 | case EDID_DETAIL_MONITOR_NAME: |
851 | case EDID_DETAIL_MONITOR_NAME: |
831 | break; |
852 | break; |
832 | case EDID_DETAIL_MONITOR_CPDATA: |
853 | case EDID_DETAIL_MONITOR_CPDATA: |
833 | break; |
854 | break; |
834 | case EDID_DETAIL_STD_MODES: |
855 | case EDID_DETAIL_STD_MODES: |
835 | /* Five modes per detailed section */ |
- | |
836 | for (j = 0; j < 5; i++) { |
856 | for (j = 0; j < 6; i++) { |
837 | struct std_timing *std; |
857 | struct std_timing *std; |
838 | struct drm_display_mode *newmode; |
858 | struct drm_display_mode *newmode; |
Line 839... | Line 859... | ||
839 | 859 | ||
840 | std = &data->data.timings[j]; |
860 | std = &data->data.timings[j]; |
- | 861 | newmode = drm_mode_std(dev, std, |
|
841 | newmode = drm_mode_std(dev, std, |
862 | edid->revision, |
842 | timing_level); |
863 | timing_level); |
843 | if (newmode) { |
864 | if (newmode) { |
844 | drm_mode_probed_add(connector, newmode); |
865 | drm_mode_probed_add(connector, newmode); |
845 | modes++; |
866 | modes++; |
Line 965... | Line 986... | ||
965 | for (j = 0; j < 5; i++) { |
986 | for (j = 0; j < 5; i++) { |
966 | struct std_timing *std; |
987 | struct std_timing *std; |
967 | struct drm_display_mode *newmode; |
988 | struct drm_display_mode *newmode; |
Line 968... | Line 989... | ||
968 | 989 | ||
969 | std = &data->data.timings[j]; |
990 | std = &data->data.timings[j]; |
- | 991 | newmode = drm_mode_std(dev, std, |
|
- | 992 | edid->revision, |
|
970 | newmode = drm_mode_std(dev, std, timing_level); |
993 | timing_level); |
971 | if (newmode) { |
994 | if (newmode) { |
972 | drm_mode_probed_add(connector, newmode); |
995 | drm_mode_probed_add(connector, newmode); |
973 | modes++; |
996 | modes++; |
974 | } |
997 | } |
Line 1012... | Line 1035... | ||
1012 | }; |
1035 | }; |
Line 1013... | Line 1036... | ||
1013 | 1036 | ||
1014 | if (i2c_transfer(adapter, msgs, 2) == 2) |
1037 | if (i2c_transfer(adapter, msgs, 2) == 2) |
Line 1015... | Line -... | ||
1015 | return 0; |
- | |
1016 | 1038 | return 0; |
|
1017 | // dev_info(&adapter->dev, "unable to read EDID block.\n"); |
1039 | |
1018 | return -1; |
1040 | return -1; |
Line 1019... | Line 1041... | ||
1019 | } |
1041 | } |