aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbmon.c')
-rw-r--r--drivers/video/fbmon.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index cef65574db6..f1ca1598a3b 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -551,6 +551,9 @@ static int get_dst_timing(unsigned char *block,
551static void get_detailed_timing(unsigned char *block, 551static void get_detailed_timing(unsigned char *block,
552 struct fb_videomode *mode) 552 struct fb_videomode *mode)
553{ 553{
554 int v_size = V_SIZE;
555 int h_size = H_SIZE;
556
554 mode->xres = H_ACTIVE; 557 mode->xres = H_ACTIVE;
555 mode->yres = V_ACTIVE; 558 mode->yres = V_ACTIVE;
556 mode->pixclock = PIXEL_CLOCK; 559 mode->pixclock = PIXEL_CLOCK;
@@ -579,11 +582,19 @@ static void get_detailed_timing(unsigned char *block,
579 } 582 }
580 mode->flag = FB_MODE_IS_DETAILED; 583 mode->flag = FB_MODE_IS_DETAILED;
581 584
585 /* get aspect ratio to set flags for timings which do not have
586 aspect ration like VESA*/
587 if (h_size * 18 > v_size * 31 && h_size * 18 < v_size * 33)
588 mode->flag |= FB_FLAG_RATIO_16_9;
589 if (h_size * 18 > v_size * 23 && h_size * 18 < v_size * 25)
590 mode->flag |= FB_FLAG_RATIO_4_3;
591
582 DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000); 592 DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000);
583 DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET, 593 DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET,
584 H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING); 594 H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING);
585 DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET, 595 DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET,
586 V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING); 596 V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING);
597 DPRINTK("%dmm %dmm ", H_SIZE, V_SIZE);
587 DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-", 598 DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-",
588 (VSYNC_POSITIVE) ? "+" : "-"); 599 (VSYNC_POSITIVE) ? "+" : "-");
589} 600}
@@ -985,7 +996,7 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
985/** 996/**
986 * fb_edid_add_monspecs() - add monitor video modes from E-EDID data 997 * fb_edid_add_monspecs() - add monitor video modes from E-EDID data
987 * @edid: 128 byte array with an E-EDID block 998 * @edid: 128 byte array with an E-EDID block
988 * @spacs: monitor specs to be extended 999 * @specs: monitor specs to be extended
989 */ 1000 */
990void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) 1001void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs)
991{ 1002{
@@ -1010,14 +1021,23 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs)
1010 while (pos < edid[2]) { 1021 while (pos < edid[2]) {
1011 u8 len = edid[pos] & 0x1f, type = (edid[pos] >> 5) & 7; 1022 u8 len = edid[pos] & 0x1f, type = (edid[pos] >> 5) & 7;
1012 pr_debug("Data block %u of %u bytes\n", type, len); 1023 pr_debug("Data block %u of %u bytes\n", type, len);
1013 if (type == 2) 1024
1025 pos++;
1026 if (type == 2) {
1014 for (i = pos; i < pos + len; i++) { 1027 for (i = pos; i < pos + len; i++) {
1015 u8 idx = edid[pos + i] & 0x7f; 1028 u8 idx = edid[i] & 0x7f;
1016 svd[svd_n++] = idx; 1029 svd[svd_n++] = idx;
1017 pr_debug("N%sative mode #%d\n", 1030 pr_debug("N%sative mode #%d\n",
1018 edid[pos + i] & 0x80 ? "" : "on-n", idx); 1031 edid[i] & 0x80 ? "" : "on-n", idx);
1019 } 1032 }
1020 pos += len + 1; 1033 } else if (type == 3 && len >= 3) {
1034 u32 ieee_reg = edid[pos] | (edid[pos + 1] << 8) |
1035 (edid[pos + 2] << 16);
1036 if (ieee_reg == 0x000c03)
1037 specs->misc |= FB_MISC_HDMI;
1038 }
1039
1040 pos += len;
1021 } 1041 }
1022 1042
1023 block = edid + edid[2]; 1043 block = edid + edid[2];
@@ -1050,9 +1070,9 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs)
1050 1070
1051 for (i = specs->modedb_len + num; i < specs->modedb_len + num + svd_n; i++) { 1071 for (i = specs->modedb_len + num; i < specs->modedb_len + num + svd_n; i++) {
1052 int idx = svd[i - specs->modedb_len - num]; 1072 int idx = svd[i - specs->modedb_len - num];
1053 if (!idx || idx > 63) { 1073 if (!idx || idx > (CEA_MODEDB_SIZE - 1)) {
1054 pr_warning("Reserved SVD code %d\n", idx); 1074 pr_warning("Reserved SVD code %d\n", idx);
1055 } else if (idx > ARRAY_SIZE(cea_modes) || !cea_modes[idx].xres) { 1075 } else if (!cea_modes[idx].xres) {
1056 pr_warning("Unimplemented SVD code %d\n", idx); 1076 pr_warning("Unimplemented SVD code %d\n", idx);
1057 } else { 1077 } else {
1058 memcpy(&m[i], cea_modes + idx, sizeof(m[i])); 1078 memcpy(&m[i], cea_modes + idx, sizeof(m[i]));