diff options
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbmon.c | 116 |
1 files changed, 58 insertions, 58 deletions
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 3f3a4e97a300..052e18058498 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2002 James Simmons <jsimmons@users.sf.net> | 4 | * Copyright (C) 2002 James Simmons <jsimmons@users.sf.net> |
5 | * | 5 | * |
6 | * Credits: | 6 | * Credits: |
7 | * | 7 | * |
8 | * The EDID Parser is a conglomeration from the following sources: | 8 | * The EDID Parser is a conglomeration from the following sources: |
9 | * | 9 | * |
10 | * 1. SciTech SNAP Graphics Architecture | 10 | * 1. SciTech SNAP Graphics Architecture |
@@ -12,13 +12,13 @@ | |||
12 | * | 12 | * |
13 | * 2. XFree86 4.3.0, interpret_edid.c | 13 | * 2. XFree86 4.3.0, interpret_edid.c |
14 | * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE> | 14 | * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE> |
15 | * | 15 | * |
16 | * 3. John Fremlin <vii@users.sourceforge.net> and | 16 | * 3. John Fremlin <vii@users.sourceforge.net> and |
17 | * Ani Joshi <ajoshi@unixbox.com> | 17 | * Ani Joshi <ajoshi@unixbox.com> |
18 | * | 18 | * |
19 | * Generalized Timing Formula is derived from: | 19 | * Generalized Timing Formula is derived from: |
20 | * | 20 | * |
21 | * GTF Spreadsheet by Andy Morrish (1/5/97) | 21 | * GTF Spreadsheet by Andy Morrish (1/5/97) |
22 | * available at http://www.vesa.org | 22 | * available at http://www.vesa.org |
23 | * | 23 | * |
24 | * This file is subject to the terms and conditions of the GNU General Public | 24 | * This file is subject to the terms and conditions of the GNU General Public |
@@ -36,7 +36,7 @@ | |||
36 | #endif | 36 | #endif |
37 | #include "edid.h" | 37 | #include "edid.h" |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * EDID parser | 40 | * EDID parser |
41 | */ | 41 | */ |
42 | 42 | ||
@@ -160,8 +160,8 @@ static int check_edid(unsigned char *edid) | |||
160 | for (i = 0; i < ARRAY_SIZE(brokendb); i++) { | 160 | for (i = 0; i < ARRAY_SIZE(brokendb); i++) { |
161 | if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) && | 161 | if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) && |
162 | brokendb[i].model == model) { | 162 | brokendb[i].model == model) { |
163 | fix = brokendb[i].fix; | 163 | fix = brokendb[i].fix; |
164 | break; | 164 | break; |
165 | } | 165 | } |
166 | } | 166 | } |
167 | 167 | ||
@@ -323,7 +323,7 @@ static void get_dpms_capabilities(unsigned char flags, | |||
323 | (flags & DPMS_SUSPEND) ? "yes" : "no", | 323 | (flags & DPMS_SUSPEND) ? "yes" : "no", |
324 | (flags & DPMS_STANDBY) ? "yes" : "no"); | 324 | (flags & DPMS_STANDBY) ? "yes" : "no"); |
325 | } | 325 | } |
326 | 326 | ||
327 | static void get_chroma(unsigned char *block, struct fb_monspecs *specs) | 327 | static void get_chroma(unsigned char *block, struct fb_monspecs *specs) |
328 | { | 328 | { |
329 | int tmp; | 329 | int tmp; |
@@ -365,7 +365,7 @@ static void get_chroma(unsigned char *block, struct fb_monspecs *specs) | |||
365 | tmp += 512; | 365 | tmp += 512; |
366 | specs->chroma.bluey = tmp/1024; | 366 | specs->chroma.bluey = tmp/1024; |
367 | DPRINTK("BlueY: 0.%03d\n", specs->chroma.bluey); | 367 | DPRINTK("BlueY: 0.%03d\n", specs->chroma.bluey); |
368 | 368 | ||
369 | tmp = ((block[6] & (3 << 2)) >> 2) | (block[0xd] << 2); | 369 | tmp = ((block[6] & (3 << 2)) >> 2) | (block[0xd] << 2); |
370 | tmp *= 1000; | 370 | tmp *= 1000; |
371 | tmp += 512; | 371 | tmp += 512; |
@@ -383,7 +383,7 @@ static void calc_mode_timings(int xres, int yres, int refresh, | |||
383 | struct fb_videomode *mode) | 383 | struct fb_videomode *mode) |
384 | { | 384 | { |
385 | struct fb_var_screeninfo *var; | 385 | struct fb_var_screeninfo *var; |
386 | 386 | ||
387 | var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); | 387 | var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); |
388 | 388 | ||
389 | if (var) { | 389 | if (var) { |
@@ -451,11 +451,11 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode) | |||
451 | 451 | ||
452 | c = block[1]; | 452 | c = block[1]; |
453 | if (c&0x80) { | 453 | if (c&0x80) { |
454 | mode[num++] = vesa_modes[9]; | 454 | mode[num++] = vesa_modes[9]; |
455 | DPRINTK(" 800x600@72Hz\n"); | 455 | DPRINTK(" 800x600@72Hz\n"); |
456 | } | 456 | } |
457 | if (c&0x40) { | 457 | if (c&0x40) { |
458 | mode[num++] = vesa_modes[10]; | 458 | mode[num++] = vesa_modes[10]; |
459 | DPRINTK(" 800x600@75Hz\n"); | 459 | DPRINTK(" 800x600@75Hz\n"); |
460 | } | 460 | } |
461 | if (c&0x20) { | 461 | if (c&0x20) { |
@@ -495,7 +495,7 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode) | |||
495 | static int get_std_timing(unsigned char *block, struct fb_videomode *mode) | 495 | static int get_std_timing(unsigned char *block, struct fb_videomode *mode) |
496 | { | 496 | { |
497 | int xres, yres = 0, refresh, ratio, i; | 497 | int xres, yres = 0, refresh, ratio, i; |
498 | 498 | ||
499 | xres = (block[0] + 31) * 8; | 499 | xres = (block[0] + 31) * 8; |
500 | if (xres <= 256) | 500 | if (xres <= 256) |
501 | return 0; | 501 | return 0; |
@@ -519,7 +519,7 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode) | |||
519 | 519 | ||
520 | DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh); | 520 | DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh); |
521 | for (i = 0; i < VESA_MODEDB_SIZE; i++) { | 521 | for (i = 0; i < VESA_MODEDB_SIZE; i++) { |
522 | if (vesa_modes[i].xres == xres && | 522 | if (vesa_modes[i].xres == xres && |
523 | vesa_modes[i].yres == yres && | 523 | vesa_modes[i].yres == yres && |
524 | vesa_modes[i].refresh == refresh) { | 524 | vesa_modes[i].refresh == refresh) { |
525 | *mode = vesa_modes[i]; | 525 | *mode = vesa_modes[i]; |
@@ -536,13 +536,13 @@ static int get_dst_timing(unsigned char *block, | |||
536 | { | 536 | { |
537 | int j, num = 0; | 537 | int j, num = 0; |
538 | 538 | ||
539 | for (j = 0; j < 6; j++, block+= STD_TIMING_DESCRIPTION_SIZE) | 539 | for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE) |
540 | num += get_std_timing(block, &mode[num]); | 540 | num += get_std_timing(block, &mode[num]); |
541 | 541 | ||
542 | return num; | 542 | return num; |
543 | } | 543 | } |
544 | 544 | ||
545 | static void get_detailed_timing(unsigned char *block, | 545 | static void get_detailed_timing(unsigned char *block, |
546 | struct fb_videomode *mode) | 546 | struct fb_videomode *mode) |
547 | { | 547 | { |
548 | mode->xres = H_ACTIVE; | 548 | mode->xres = H_ACTIVE; |
@@ -553,7 +553,7 @@ static void get_detailed_timing(unsigned char *block, | |||
553 | mode->right_margin = H_SYNC_OFFSET; | 553 | mode->right_margin = H_SYNC_OFFSET; |
554 | mode->left_margin = (H_ACTIVE + H_BLANKING) - | 554 | mode->left_margin = (H_ACTIVE + H_BLANKING) - |
555 | (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); | 555 | (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); |
556 | mode->upper_margin = V_BLANKING - V_SYNC_OFFSET - | 556 | mode->upper_margin = V_BLANKING - V_SYNC_OFFSET - |
557 | V_SYNC_WIDTH; | 557 | V_SYNC_WIDTH; |
558 | mode->lower_margin = V_SYNC_OFFSET; | 558 | mode->lower_margin = V_SYNC_OFFSET; |
559 | mode->hsync_len = H_SYNC_WIDTH; | 559 | mode->hsync_len = H_SYNC_WIDTH; |
@@ -597,7 +597,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) | |||
597 | if (mode == NULL) | 597 | if (mode == NULL) |
598 | return NULL; | 598 | return NULL; |
599 | 599 | ||
600 | if (edid == NULL || !edid_checksum(edid) || | 600 | if (edid == NULL || !edid_checksum(edid) || |
601 | !edid_check_header(edid)) { | 601 | !edid_check_header(edid)) { |
602 | kfree(mode); | 602 | kfree(mode); |
603 | return NULL; | 603 | return NULL; |
@@ -632,7 +632,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) | |||
632 | if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa) | 632 | if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa) |
633 | num += get_dst_timing(block + 5, &mode[num]); | 633 | num += get_dst_timing(block + 5, &mode[num]); |
634 | } | 634 | } |
635 | 635 | ||
636 | /* Yikes, EDID data is totally useless */ | 636 | /* Yikes, EDID data is totally useless */ |
637 | if (!num) { | 637 | if (!num) { |
638 | kfree(mode); | 638 | kfree(mode); |
@@ -713,7 +713,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) | |||
713 | hscan = (pixclock + htotal / 2) / htotal; | 713 | hscan = (pixclock + htotal / 2) / htotal; |
714 | hscan = (hscan + 500) / 1000 * 1000; | 714 | hscan = (hscan + 500) / 1000 * 1000; |
715 | hz = (hscan + vtotal / 2) / vtotal; | 715 | hz = (hscan + vtotal / 2) / vtotal; |
716 | 716 | ||
717 | if (specs->dclkmax == 0 || specs->dclkmax < pixclock) | 717 | if (specs->dclkmax == 0 || specs->dclkmax < pixclock) |
718 | specs->dclkmax = pixclock; | 718 | specs->dclkmax = pixclock; |
719 | 719 | ||
@@ -966,8 +966,8 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) | |||
966 | DPRINTK("========================================\n"); | 966 | DPRINTK("========================================\n"); |
967 | } | 967 | } |
968 | 968 | ||
969 | /* | 969 | /* |
970 | * VESA Generalized Timing Formula (GTF) | 970 | * VESA Generalized Timing Formula (GTF) |
971 | */ | 971 | */ |
972 | 972 | ||
973 | #define FLYBACK 550 | 973 | #define FLYBACK 550 |
@@ -996,7 +996,7 @@ struct __fb_timings { | |||
996 | * @hfreq: horizontal freq | 996 | * @hfreq: horizontal freq |
997 | * | 997 | * |
998 | * DESCRIPTION: | 998 | * DESCRIPTION: |
999 | * vblank = right_margin + vsync_len + left_margin | 999 | * vblank = right_margin + vsync_len + left_margin |
1000 | * | 1000 | * |
1001 | * given: right_margin = 1 (V_FRONTPORCH) | 1001 | * given: right_margin = 1 (V_FRONTPORCH) |
1002 | * vsync_len = 3 | 1002 | * vsync_len = 3 |
@@ -1010,12 +1010,12 @@ static u32 fb_get_vblank(u32 hfreq) | |||
1010 | { | 1010 | { |
1011 | u32 vblank; | 1011 | u32 vblank; |
1012 | 1012 | ||
1013 | vblank = (hfreq * FLYBACK)/1000; | 1013 | vblank = (hfreq * FLYBACK)/1000; |
1014 | vblank = (vblank + 500)/1000; | 1014 | vblank = (vblank + 500)/1000; |
1015 | return (vblank + V_FRONTPORCH); | 1015 | return (vblank + V_FRONTPORCH); |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | /** | 1018 | /** |
1019 | * fb_get_hblank_by_freq - get horizontal blank time given hfreq | 1019 | * fb_get_hblank_by_freq - get horizontal blank time given hfreq |
1020 | * @hfreq: horizontal freq | 1020 | * @hfreq: horizontal freq |
1021 | * @xres: horizontal resolution in pixels | 1021 | * @xres: horizontal resolution in pixels |
@@ -1031,7 +1031,7 @@ static u32 fb_get_vblank(u32 hfreq) | |||
1031 | * | 1031 | * |
1032 | * where: C = ((offset - scale factor) * blank_scale) | 1032 | * where: C = ((offset - scale factor) * blank_scale) |
1033 | * -------------------------------------- + scale factor | 1033 | * -------------------------------------- + scale factor |
1034 | * 256 | 1034 | * 256 |
1035 | * M = blank_scale * gradient | 1035 | * M = blank_scale * gradient |
1036 | * | 1036 | * |
1037 | */ | 1037 | */ |
@@ -1039,7 +1039,7 @@ static u32 fb_get_hblank_by_hfreq(u32 hfreq, u32 xres) | |||
1039 | { | 1039 | { |
1040 | u32 c_val, m_val, duty_cycle, hblank; | 1040 | u32 c_val, m_val, duty_cycle, hblank; |
1041 | 1041 | ||
1042 | c_val = (((H_OFFSET - H_SCALEFACTOR) * H_BLANKSCALE)/256 + | 1042 | c_val = (((H_OFFSET - H_SCALEFACTOR) * H_BLANKSCALE)/256 + |
1043 | H_SCALEFACTOR) * 1000; | 1043 | H_SCALEFACTOR) * 1000; |
1044 | m_val = (H_BLANKSCALE * H_GRADIENT)/256; | 1044 | m_val = (H_BLANKSCALE * H_GRADIENT)/256; |
1045 | m_val = (m_val * 1000000)/hfreq; | 1045 | m_val = (m_val * 1000000)/hfreq; |
@@ -1048,7 +1048,7 @@ static u32 fb_get_hblank_by_hfreq(u32 hfreq, u32 xres) | |||
1048 | return (hblank); | 1048 | return (hblank); |
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | /** | 1051 | /** |
1052 | * fb_get_hblank_by_dclk - get horizontal blank time given pixelclock | 1052 | * fb_get_hblank_by_dclk - get horizontal blank time given pixelclock |
1053 | * @dclk: pixelclock in Hz | 1053 | * @dclk: pixelclock in Hz |
1054 | * @xres: horizontal resolution in pixels | 1054 | * @xres: horizontal resolution in pixels |
@@ -1061,7 +1061,7 @@ static u32 fb_get_hblank_by_hfreq(u32 hfreq, u32 xres) | |||
1061 | * | 1061 | * |
1062 | * duty cycle = percent of htotal assigned to inactive display | 1062 | * duty cycle = percent of htotal assigned to inactive display |
1063 | * duty cycle = C - (M * h_period) | 1063 | * duty cycle = C - (M * h_period) |
1064 | * | 1064 | * |
1065 | * where: h_period = SQRT(100 - C + (0.4 * xres * M)/dclk) + C - 100 | 1065 | * where: h_period = SQRT(100 - C + (0.4 * xres * M)/dclk) + C - 100 |
1066 | * ----------------------------------------------- | 1066 | * ----------------------------------------------- |
1067 | * 2 * M | 1067 | * 2 * M |
@@ -1077,11 +1077,11 @@ static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres) | |||
1077 | h_period = 100 - C_VAL; | 1077 | h_period = 100 - C_VAL; |
1078 | h_period *= h_period; | 1078 | h_period *= h_period; |
1079 | h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk); | 1079 | h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk); |
1080 | h_period *=10000; | 1080 | h_period *= 10000; |
1081 | 1081 | ||
1082 | h_period = int_sqrt(h_period); | 1082 | h_period = int_sqrt(h_period); |
1083 | h_period -= (100 - C_VAL) * 100; | 1083 | h_period -= (100 - C_VAL) * 100; |
1084 | h_period *= 1000; | 1084 | h_period *= 1000; |
1085 | h_period /= 2 * M_VAL; | 1085 | h_period /= 2 * M_VAL; |
1086 | 1086 | ||
1087 | duty_cycle = C_VAL * 1000 - (M_VAL * h_period)/100; | 1087 | duty_cycle = C_VAL * 1000 - (M_VAL * h_period)/100; |
@@ -1089,7 +1089,7 @@ static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres) | |||
1089 | hblank &= ~15; | 1089 | hblank &= ~15; |
1090 | return (hblank); | 1090 | return (hblank); |
1091 | } | 1091 | } |
1092 | 1092 | ||
1093 | /** | 1093 | /** |
1094 | * fb_get_hfreq - estimate hsync | 1094 | * fb_get_hfreq - estimate hsync |
1095 | * @vfreq: vertical refresh rate | 1095 | * @vfreq: vertical refresh rate |
@@ -1100,13 +1100,13 @@ static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres) | |||
1100 | * (yres + front_port) * vfreq * 1000000 | 1100 | * (yres + front_port) * vfreq * 1000000 |
1101 | * hfreq = ------------------------------------- | 1101 | * hfreq = ------------------------------------- |
1102 | * (1000000 - (vfreq * FLYBACK) | 1102 | * (1000000 - (vfreq * FLYBACK) |
1103 | * | 1103 | * |
1104 | */ | 1104 | */ |
1105 | 1105 | ||
1106 | static u32 fb_get_hfreq(u32 vfreq, u32 yres) | 1106 | static u32 fb_get_hfreq(u32 vfreq, u32 yres) |
1107 | { | 1107 | { |
1108 | u32 divisor, hfreq; | 1108 | u32 divisor, hfreq; |
1109 | 1109 | ||
1110 | divisor = (1000000 - (vfreq * FLYBACK))/1000; | 1110 | divisor = (1000000 - (vfreq * FLYBACK))/1000; |
1111 | hfreq = (yres + V_FRONTPORCH) * vfreq * 1000; | 1111 | hfreq = (yres + V_FRONTPORCH) * vfreq * 1000; |
1112 | return (hfreq/divisor); | 1112 | return (hfreq/divisor); |
@@ -1117,7 +1117,7 @@ static void fb_timings_vfreq(struct __fb_timings *timings) | |||
1117 | timings->hfreq = fb_get_hfreq(timings->vfreq, timings->vactive); | 1117 | timings->hfreq = fb_get_hfreq(timings->vfreq, timings->vactive); |
1118 | timings->vblank = fb_get_vblank(timings->hfreq); | 1118 | timings->vblank = fb_get_vblank(timings->hfreq); |
1119 | timings->vtotal = timings->vactive + timings->vblank; | 1119 | timings->vtotal = timings->vactive + timings->vblank; |
1120 | timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq, | 1120 | timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq, |
1121 | timings->hactive); | 1121 | timings->hactive); |
1122 | timings->htotal = timings->hactive + timings->hblank; | 1122 | timings->htotal = timings->hactive + timings->hblank; |
1123 | timings->dclk = timings->htotal * timings->hfreq; | 1123 | timings->dclk = timings->htotal * timings->hfreq; |
@@ -1128,7 +1128,7 @@ static void fb_timings_hfreq(struct __fb_timings *timings) | |||
1128 | timings->vblank = fb_get_vblank(timings->hfreq); | 1128 | timings->vblank = fb_get_vblank(timings->hfreq); |
1129 | timings->vtotal = timings->vactive + timings->vblank; | 1129 | timings->vtotal = timings->vactive + timings->vblank; |
1130 | timings->vfreq = timings->hfreq/timings->vtotal; | 1130 | timings->vfreq = timings->hfreq/timings->vtotal; |
1131 | timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq, | 1131 | timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq, |
1132 | timings->hactive); | 1132 | timings->hactive); |
1133 | timings->htotal = timings->hactive + timings->hblank; | 1133 | timings->htotal = timings->hactive + timings->hblank; |
1134 | timings->dclk = timings->htotal * timings->hfreq; | 1134 | timings->dclk = timings->htotal * timings->hfreq; |
@@ -1136,7 +1136,7 @@ static void fb_timings_hfreq(struct __fb_timings *timings) | |||
1136 | 1136 | ||
1137 | static void fb_timings_dclk(struct __fb_timings *timings) | 1137 | static void fb_timings_dclk(struct __fb_timings *timings) |
1138 | { | 1138 | { |
1139 | timings->hblank = fb_get_hblank_by_dclk(timings->dclk, | 1139 | timings->hblank = fb_get_hblank_by_dclk(timings->dclk, |
1140 | timings->hactive); | 1140 | timings->hactive); |
1141 | timings->htotal = timings->hactive + timings->hblank; | 1141 | timings->htotal = timings->hactive + timings->hblank; |
1142 | timings->hfreq = timings->dclk/timings->htotal; | 1142 | timings->hfreq = timings->dclk/timings->htotal; |
@@ -1156,29 +1156,29 @@ static void fb_timings_dclk(struct __fb_timings *timings) | |||
1156 | * @info: pointer to fb_info | 1156 | * @info: pointer to fb_info |
1157 | * | 1157 | * |
1158 | * DESCRIPTION: | 1158 | * DESCRIPTION: |
1159 | * Calculates video mode based on monitor specs using VESA GTF. | 1159 | * Calculates video mode based on monitor specs using VESA GTF. |
1160 | * The GTF is best for VESA GTF compliant monitors but is | 1160 | * The GTF is best for VESA GTF compliant monitors but is |
1161 | * specifically formulated to work for older monitors as well. | 1161 | * specifically formulated to work for older monitors as well. |
1162 | * | 1162 | * |
1163 | * If @flag==0, the function will attempt to maximize the | 1163 | * If @flag==0, the function will attempt to maximize the |
1164 | * refresh rate. Otherwise, it will calculate timings based on | 1164 | * refresh rate. Otherwise, it will calculate timings based on |
1165 | * the flag and accompanying value. | 1165 | * the flag and accompanying value. |
1166 | * | 1166 | * |
1167 | * If FB_IGNOREMON bit is set in @flags, monitor specs will be | 1167 | * If FB_IGNOREMON bit is set in @flags, monitor specs will be |
1168 | * ignored and @var will be filled with the calculated timings. | 1168 | * ignored and @var will be filled with the calculated timings. |
1169 | * | 1169 | * |
1170 | * All calculations are based on the VESA GTF Spreadsheet | 1170 | * All calculations are based on the VESA GTF Spreadsheet |
1171 | * available at VESA's public ftp (http://www.vesa.org). | 1171 | * available at VESA's public ftp (http://www.vesa.org). |
1172 | * | 1172 | * |
1173 | * NOTES: | 1173 | * NOTES: |
1174 | * The timings generated by the GTF will be different from VESA | 1174 | * The timings generated by the GTF will be different from VESA |
1175 | * DMT. It might be a good idea to keep a table of standard | 1175 | * DMT. It might be a good idea to keep a table of standard |
1176 | * VESA modes as well. The GTF may also not work for some displays, | 1176 | * VESA modes as well. The GTF may also not work for some displays, |
1177 | * such as, and especially, analog TV. | 1177 | * such as, and especially, analog TV. |
1178 | * | 1178 | * |
1179 | * REQUIRES: | 1179 | * REQUIRES: |
1180 | * A valid info->monspecs, otherwise 'safe numbers' will be used. | 1180 | * A valid info->monspecs, otherwise 'safe numbers' will be used. |
1181 | */ | 1181 | */ |
1182 | int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info) | 1182 | int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info) |
1183 | { | 1183 | { |
1184 | struct __fb_timings *timings; | 1184 | struct __fb_timings *timings; |
@@ -1191,7 +1191,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf | |||
1191 | if (!timings) | 1191 | if (!timings) |
1192 | return -ENOMEM; | 1192 | return -ENOMEM; |
1193 | 1193 | ||
1194 | /* | 1194 | /* |
1195 | * If monspecs are invalid, use values that are enough | 1195 | * If monspecs are invalid, use values that are enough |
1196 | * for 640x480@60 | 1196 | * for 640x480@60 |
1197 | */ | 1197 | */ |
@@ -1214,7 +1214,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf | |||
1214 | 1214 | ||
1215 | timings->hactive = var->xres; | 1215 | timings->hactive = var->xres; |
1216 | timings->vactive = var->yres; | 1216 | timings->vactive = var->yres; |
1217 | if (var->vmode & FB_VMODE_INTERLACED) { | 1217 | if (var->vmode & FB_VMODE_INTERLACED) { |
1218 | timings->vactive /= 2; | 1218 | timings->vactive /= 2; |
1219 | interlace = 2; | 1219 | interlace = 2; |
1220 | } | 1220 | } |
@@ -1250,9 +1250,9 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf | |||
1250 | break; | 1250 | break; |
1251 | default: | 1251 | default: |
1252 | err = -EINVAL; | 1252 | err = -EINVAL; |
1253 | 1253 | ||
1254 | } | 1254 | } |
1255 | 1255 | ||
1256 | if (err || (!(flags & FB_IGNOREMON) && | 1256 | if (err || (!(flags & FB_IGNOREMON) && |
1257 | (timings->vfreq < vfmin || timings->vfreq > vfmax || | 1257 | (timings->vfreq < vfmin || timings->vfreq > vfmax || |
1258 | timings->hfreq < hfmin || timings->hfreq > hfmax || | 1258 | timings->hfreq < hfmin || timings->hfreq > hfmax || |
@@ -1269,7 +1269,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf | |||
1269 | var->upper_margin = (timings->vblank * interlace)/dscan - | 1269 | var->upper_margin = (timings->vblank * interlace)/dscan - |
1270 | (var->vsync_len + var->lower_margin); | 1270 | (var->vsync_len + var->lower_margin); |
1271 | } | 1271 | } |
1272 | 1272 | ||
1273 | kfree(timings); | 1273 | kfree(timings); |
1274 | return err; | 1274 | return err; |
1275 | } | 1275 | } |
@@ -1291,7 +1291,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, | |||
1291 | return -EINVAL; | 1291 | return -EINVAL; |
1292 | } | 1292 | } |
1293 | #endif /* CONFIG_FB_MODE_HELPERS */ | 1293 | #endif /* CONFIG_FB_MODE_HELPERS */ |
1294 | 1294 | ||
1295 | /* | 1295 | /* |
1296 | * fb_validate_mode - validates var against monitor capabilities | 1296 | * fb_validate_mode - validates var against monitor capabilities |
1297 | * @var: pointer to fb_var_screeninfo | 1297 | * @var: pointer to fb_var_screeninfo |
@@ -1309,7 +1309,7 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info) | |||
1309 | u32 hfreq, vfreq, htotal, vtotal, pixclock; | 1309 | u32 hfreq, vfreq, htotal, vtotal, pixclock; |
1310 | u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax; | 1310 | u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax; |
1311 | 1311 | ||
1312 | /* | 1312 | /* |
1313 | * If monspecs are invalid, use values that are enough | 1313 | * If monspecs are invalid, use values that are enough |
1314 | * for 640x480@60 | 1314 | * for 640x480@60 |
1315 | */ | 1315 | */ |
@@ -1333,10 +1333,10 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info) | |||
1333 | if (!var->pixclock) | 1333 | if (!var->pixclock) |
1334 | return -EINVAL; | 1334 | return -EINVAL; |
1335 | pixclock = PICOS2KHZ(var->pixclock) * 1000; | 1335 | pixclock = PICOS2KHZ(var->pixclock) * 1000; |
1336 | 1336 | ||
1337 | htotal = var->xres + var->right_margin + var->hsync_len + | 1337 | htotal = var->xres + var->right_margin + var->hsync_len + |
1338 | var->left_margin; | 1338 | var->left_margin; |
1339 | vtotal = var->yres + var->lower_margin + var->vsync_len + | 1339 | vtotal = var->yres + var->lower_margin + var->vsync_len + |
1340 | var->upper_margin; | 1340 | var->upper_margin; |
1341 | 1341 | ||
1342 | if (var->vmode & FB_VMODE_INTERLACED) | 1342 | if (var->vmode & FB_VMODE_INTERLACED) |
@@ -1349,7 +1349,7 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info) | |||
1349 | 1349 | ||
1350 | vfreq = hfreq/vtotal; | 1350 | vfreq = hfreq/vtotal; |
1351 | 1351 | ||
1352 | return (vfreq < vfmin || vfreq > vfmax || | 1352 | return (vfreq < vfmin || vfreq > vfmax || |
1353 | hfreq < hfmin || hfreq > hfmax || | 1353 | hfreq < hfmin || hfreq > hfmax || |
1354 | pixclock < dclkmin || pixclock > dclkmax) ? | 1354 | pixclock < dclkmin || pixclock > dclkmax) ? |
1355 | -EINVAL : 0; | 1355 | -EINVAL : 0; |