Merge tag 'for-linus-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
[linux-2.6-microblaze.git] / drivers / video / fbdev / core / fbmon.c
1 /*
2  * linux/drivers/video/fbmon.c
3  *
4  * Copyright (C) 2002 James Simmons <jsimmons@users.sf.net>
5  *
6  * Credits:
7  *
8  * The EDID Parser is a conglomeration from the following sources:
9  *
10  *   1. SciTech SNAP Graphics Architecture
11  *      Copyright (C) 1991-2002 SciTech Software, Inc. All rights reserved.
12  *
13  *   2. XFree86 4.3.0, interpret_edid.c
14  *      Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
15  *
16  *   3. John Fremlin <vii@users.sourceforge.net> and
17  *      Ani Joshi <ajoshi@unixbox.com>
18  *
19  * Generalized Timing Formula is derived from:
20  *
21  *      GTF Spreadsheet by Andy Morrish (1/5/97)
22  *      available at https://www.vesa.org
23  *
24  * This file is subject to the terms and conditions of the GNU General Public
25  * License.  See the file COPYING in the main directory of this archive
26  * for more details.
27  *
28  */
29 #include <linux/fb.h>
30 #include <linux/module.h>
31 #include <linux/pci.h>
32 #include <linux/slab.h>
33 #include <video/edid.h>
34 #include <video/of_videomode.h>
35 #include <video/videomode.h>
36 #include "../edid.h"
37
38 /*
39  * EDID parser
40  */
41
42 #undef DEBUG  /* define this for verbose EDID parsing output */
43
44 #ifdef DEBUG
45 #define DPRINTK(fmt, args...) printk(fmt,## args)
46 #else
47 #define DPRINTK(fmt, args...) no_printk(fmt, ##args)
48 #endif
49
50 #define FBMON_FIX_HEADER  1
51 #define FBMON_FIX_INPUT   2
52 #define FBMON_FIX_TIMINGS 3
53
54 #ifdef CONFIG_FB_MODE_HELPERS
55 struct broken_edid {
56         u8  manufacturer[4];
57         u32 model;
58         u32 fix;
59 };
60
61 static const struct broken_edid brokendb[] = {
62         /* DEC FR-PCXAV-YZ */
63         {
64                 .manufacturer = "DEC",
65                 .model        = 0x073a,
66                 .fix          = FBMON_FIX_HEADER,
67         },
68         /* ViewSonic PF775a */
69         {
70                 .manufacturer = "VSC",
71                 .model        = 0x5a44,
72                 .fix          = FBMON_FIX_INPUT,
73         },
74         /* Sharp UXGA? */
75         {
76                 .manufacturer = "SHP",
77                 .model        = 0x138e,
78                 .fix          = FBMON_FIX_TIMINGS,
79         },
80 };
81
82 static const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff,
83         0xff, 0xff, 0xff, 0x00
84 };
85
86 static void copy_string(unsigned char *c, unsigned char *s)
87 {
88   int i;
89   c = c + 5;
90   for (i = 0; (i < 13 && *c != 0x0A); i++)
91     *(s++) = *(c++);
92   *s = 0;
93   while (i-- && (*--s == 0x20)) *s = 0;
94 }
95
96 static int edid_is_serial_block(unsigned char *block)
97 {
98         if ((block[0] == 0x00) && (block[1] == 0x00) &&
99             (block[2] == 0x00) && (block[3] == 0xff) &&
100             (block[4] == 0x00))
101                 return 1;
102         else
103                 return 0;
104 }
105
106 static int edid_is_ascii_block(unsigned char *block)
107 {
108         if ((block[0] == 0x00) && (block[1] == 0x00) &&
109             (block[2] == 0x00) && (block[3] == 0xfe) &&
110             (block[4] == 0x00))
111                 return 1;
112         else
113                 return 0;
114 }
115
116 static int edid_is_limits_block(unsigned char *block)
117 {
118         if ((block[0] == 0x00) && (block[1] == 0x00) &&
119             (block[2] == 0x00) && (block[3] == 0xfd) &&
120             (block[4] == 0x00))
121                 return 1;
122         else
123                 return 0;
124 }
125
126 static int edid_is_monitor_block(unsigned char *block)
127 {
128         if ((block[0] == 0x00) && (block[1] == 0x00) &&
129             (block[2] == 0x00) && (block[3] == 0xfc) &&
130             (block[4] == 0x00))
131                 return 1;
132         else
133                 return 0;
134 }
135
136 static int edid_is_timing_block(unsigned char *block)
137 {
138         if ((block[0] != 0x00) || (block[1] != 0x00) ||
139             (block[2] != 0x00) || (block[4] != 0x00))
140                 return 1;
141         else
142                 return 0;
143 }
144
145 static int check_edid(unsigned char *edid)
146 {
147         unsigned char *block = edid + ID_MANUFACTURER_NAME, manufacturer[4];
148         unsigned char *b;
149         u32 model;
150         int i, fix = 0, ret = 0;
151
152         manufacturer[0] = ((block[0] & 0x7c) >> 2) + '@';
153         manufacturer[1] = ((block[0] & 0x03) << 3) +
154                 ((block[1] & 0xe0) >> 5) + '@';
155         manufacturer[2] = (block[1] & 0x1f) + '@';
156         manufacturer[3] = 0;
157         model = block[2] + (block[3] << 8);
158
159         for (i = 0; i < ARRAY_SIZE(brokendb); i++) {
160                 if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) &&
161                         brokendb[i].model == model) {
162                         fix = brokendb[i].fix;
163                         break;
164                 }
165         }
166
167         switch (fix) {
168         case FBMON_FIX_HEADER:
169                 for (i = 0; i < 8; i++) {
170                         if (edid[i] != edid_v1_header[i]) {
171                                 ret = fix;
172                                 break;
173                         }
174                 }
175                 break;
176         case FBMON_FIX_INPUT:
177                 b = edid + EDID_STRUCT_DISPLAY;
178                 /* Only if display is GTF capable will
179                    the input type be reset to analog */
180                 if (b[4] & 0x01 && b[0] & 0x80)
181                         ret = fix;
182                 break;
183         case FBMON_FIX_TIMINGS:
184                 b = edid + DETAILED_TIMING_DESCRIPTIONS_START;
185                 ret = fix;
186
187                 for (i = 0; i < 4; i++) {
188                         if (edid_is_limits_block(b)) {
189                                 ret = 0;
190                                 break;
191                         }
192
193                         b += DETAILED_TIMING_DESCRIPTION_SIZE;
194                 }
195
196                 break;
197         }
198
199         if (ret)
200                 printk("fbmon: The EDID Block of "
201                        "Manufacturer: %s Model: 0x%x is known to "
202                        "be broken,\n",  manufacturer, model);
203
204         return ret;
205 }
206
207 static void fix_edid(unsigned char *edid, int fix)
208 {
209         int i;
210         unsigned char *b, csum = 0;
211
212         switch (fix) {
213         case FBMON_FIX_HEADER:
214                 printk("fbmon: trying a header reconstruct\n");
215                 memcpy(edid, edid_v1_header, 8);
216                 break;
217         case FBMON_FIX_INPUT:
218                 printk("fbmon: trying to fix input type\n");
219                 b = edid + EDID_STRUCT_DISPLAY;
220                 b[0] &= ~0x80;
221                 edid[127] += 0x80;
222                 break;
223         case FBMON_FIX_TIMINGS:
224                 printk("fbmon: trying to fix monitor timings\n");
225                 b = edid + DETAILED_TIMING_DESCRIPTIONS_START;
226                 for (i = 0; i < 4; i++) {
227                         if (!(edid_is_serial_block(b) ||
228                               edid_is_ascii_block(b) ||
229                               edid_is_monitor_block(b) ||
230                               edid_is_timing_block(b))) {
231                                 b[0] = 0x00;
232                                 b[1] = 0x00;
233                                 b[2] = 0x00;
234                                 b[3] = 0xfd;
235                                 b[4] = 0x00;
236                                 b[5] = 60;   /* vfmin */
237                                 b[6] = 60;   /* vfmax */
238                                 b[7] = 30;   /* hfmin */
239                                 b[8] = 75;   /* hfmax */
240                                 b[9] = 17;   /* pixclock - 170 MHz*/
241                                 b[10] = 0;   /* GTF */
242                                 break;
243                         }
244
245                         b += DETAILED_TIMING_DESCRIPTION_SIZE;
246                 }
247
248                 for (i = 0; i < EDID_LENGTH - 1; i++)
249                         csum += edid[i];
250
251                 edid[127] = 256 - csum;
252                 break;
253         }
254 }
255
256 static int edid_checksum(unsigned char *edid)
257 {
258         unsigned char csum = 0, all_null = 0;
259         int i, err = 0, fix = check_edid(edid);
260
261         if (fix)
262                 fix_edid(edid, fix);
263
264         for (i = 0; i < EDID_LENGTH; i++) {
265                 csum += edid[i];
266                 all_null |= edid[i];
267         }
268
269         if (csum == 0x00 && all_null) {
270                 /* checksum passed, everything's good */
271                 err = 1;
272         }
273
274         return err;
275 }
276
277 static int edid_check_header(unsigned char *edid)
278 {
279         int i, err = 1, fix = check_edid(edid);
280
281         if (fix)
282                 fix_edid(edid, fix);
283
284         for (i = 0; i < 8; i++) {
285                 if (edid[i] != edid_v1_header[i])
286                         err = 0;
287         }
288
289         return err;
290 }
291
292 static void parse_vendor_block(unsigned char *block, struct fb_monspecs *specs)
293 {
294         specs->manufacturer[0] = ((block[0] & 0x7c) >> 2) + '@';
295         specs->manufacturer[1] = ((block[0] & 0x03) << 3) +
296                 ((block[1] & 0xe0) >> 5) + '@';
297         specs->manufacturer[2] = (block[1] & 0x1f) + '@';
298         specs->manufacturer[3] = 0;
299         specs->model = block[2] + (block[3] << 8);
300         specs->serial = block[4] + (block[5] << 8) +
301                (block[6] << 16) + (block[7] << 24);
302         specs->year = block[9] + 1990;
303         specs->week = block[8];
304         DPRINTK("   Manufacturer: %s\n", specs->manufacturer);
305         DPRINTK("   Model: %x\n", specs->model);
306         DPRINTK("   Serial#: %u\n", specs->serial);
307         DPRINTK("   Year: %u Week %u\n", specs->year, specs->week);
308 }
309
310 static void get_dpms_capabilities(unsigned char flags,
311                                   struct fb_monspecs *specs)
312 {
313         specs->dpms = 0;
314         if (flags & DPMS_ACTIVE_OFF)
315                 specs->dpms |= FB_DPMS_ACTIVE_OFF;
316         if (flags & DPMS_SUSPEND)
317                 specs->dpms |= FB_DPMS_SUSPEND;
318         if (flags & DPMS_STANDBY)
319                 specs->dpms |= FB_DPMS_STANDBY;
320         DPRINTK("      DPMS: Active %s, Suspend %s, Standby %s\n",
321                (flags & DPMS_ACTIVE_OFF) ? "yes" : "no",
322                (flags & DPMS_SUSPEND)    ? "yes" : "no",
323                (flags & DPMS_STANDBY)    ? "yes" : "no");
324 }
325
326 static void get_chroma(unsigned char *block, struct fb_monspecs *specs)
327 {
328         int tmp;
329
330         DPRINTK("      Chroma\n");
331         /* Chromaticity data */
332         tmp = ((block[5] & (3 << 6)) >> 6) | (block[0x7] << 2);
333         tmp *= 1000;
334         tmp += 512;
335         specs->chroma.redx = tmp/1024;
336         DPRINTK("         RedX:     0.%03d ", specs->chroma.redx);
337
338         tmp = ((block[5] & (3 << 4)) >> 4) | (block[0x8] << 2);
339         tmp *= 1000;
340         tmp += 512;
341         specs->chroma.redy = tmp/1024;
342         DPRINTK("RedY:     0.%03d\n", specs->chroma.redy);
343
344         tmp = ((block[5] & (3 << 2)) >> 2) | (block[0x9] << 2);
345         tmp *= 1000;
346         tmp += 512;
347         specs->chroma.greenx = tmp/1024;
348         DPRINTK("         GreenX:   0.%03d ", specs->chroma.greenx);
349
350         tmp = (block[5] & 3) | (block[0xa] << 2);
351         tmp *= 1000;
352         tmp += 512;
353         specs->chroma.greeny = tmp/1024;
354         DPRINTK("GreenY:   0.%03d\n", specs->chroma.greeny);
355
356         tmp = ((block[6] & (3 << 6)) >> 6) | (block[0xb] << 2);
357         tmp *= 1000;
358         tmp += 512;
359         specs->chroma.bluex = tmp/1024;
360         DPRINTK("         BlueX:    0.%03d ", specs->chroma.bluex);
361
362         tmp = ((block[6] & (3 << 4)) >> 4) | (block[0xc] << 2);
363         tmp *= 1000;
364         tmp += 512;
365         specs->chroma.bluey = tmp/1024;
366         DPRINTK("BlueY:    0.%03d\n", specs->chroma.bluey);
367
368         tmp = ((block[6] & (3 << 2)) >> 2) | (block[0xd] << 2);
369         tmp *= 1000;
370         tmp += 512;
371         specs->chroma.whitex = tmp/1024;
372         DPRINTK("         WhiteX:   0.%03d ", specs->chroma.whitex);
373
374         tmp = (block[6] & 3) | (block[0xe] << 2);
375         tmp *= 1000;
376         tmp += 512;
377         specs->chroma.whitey = tmp/1024;
378         DPRINTK("WhiteY:   0.%03d\n", specs->chroma.whitey);
379 }
380
381 static void calc_mode_timings(int xres, int yres, int refresh,
382                               struct fb_videomode *mode)
383 {
384         struct fb_var_screeninfo *var;
385
386         var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL);
387
388         if (var) {
389                 var->xres = xres;
390                 var->yres = yres;
391                 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON,
392                             refresh, var, NULL);
393                 mode->xres = xres;
394                 mode->yres = yres;
395                 mode->pixclock = var->pixclock;
396                 mode->refresh = refresh;
397                 mode->left_margin = var->left_margin;
398                 mode->right_margin = var->right_margin;
399                 mode->upper_margin = var->upper_margin;
400                 mode->lower_margin = var->lower_margin;
401                 mode->hsync_len = var->hsync_len;
402                 mode->vsync_len = var->vsync_len;
403                 mode->vmode = 0;
404                 mode->sync = 0;
405                 kfree(var);
406         }
407 }
408
409 static int get_est_timing(unsigned char *block, struct fb_videomode *mode)
410 {
411         int num = 0;
412         unsigned char c;
413
414         c = block[0];
415         if (c&0x80) {
416                 calc_mode_timings(720, 400, 70, &mode[num]);
417                 mode[num++].flag = FB_MODE_IS_CALCULATED;
418                 DPRINTK("      720x400@70Hz\n");
419         }
420         if (c&0x40) {
421                 calc_mode_timings(720, 400, 88, &mode[num]);
422                 mode[num++].flag = FB_MODE_IS_CALCULATED;
423                 DPRINTK("      720x400@88Hz\n");
424         }
425         if (c&0x20) {
426                 mode[num++] = vesa_modes[3];
427                 DPRINTK("      640x480@60Hz\n");
428         }
429         if (c&0x10) {
430                 calc_mode_timings(640, 480, 67, &mode[num]);
431                 mode[num++].flag = FB_MODE_IS_CALCULATED;
432                 DPRINTK("      640x480@67Hz\n");
433         }
434         if (c&0x08) {
435                 mode[num++] = vesa_modes[4];
436                 DPRINTK("      640x480@72Hz\n");
437         }
438         if (c&0x04) {
439                 mode[num++] = vesa_modes[5];
440                 DPRINTK("      640x480@75Hz\n");
441         }
442         if (c&0x02) {
443                 mode[num++] = vesa_modes[7];
444                 DPRINTK("      800x600@56Hz\n");
445         }
446         if (c&0x01) {
447                 mode[num++] = vesa_modes[8];
448                 DPRINTK("      800x600@60Hz\n");
449         }
450
451         c = block[1];
452         if (c&0x80) {
453                 mode[num++] = vesa_modes[9];
454                 DPRINTK("      800x600@72Hz\n");
455         }
456         if (c&0x40) {
457                 mode[num++] = vesa_modes[10];
458                 DPRINTK("      800x600@75Hz\n");
459         }
460         if (c&0x20) {
461                 calc_mode_timings(832, 624, 75, &mode[num]);
462                 mode[num++].flag = FB_MODE_IS_CALCULATED;
463                 DPRINTK("      832x624@75Hz\n");
464         }
465         if (c&0x10) {
466                 mode[num++] = vesa_modes[12];
467                 DPRINTK("      1024x768@87Hz Interlaced\n");
468         }
469         if (c&0x08) {
470                 mode[num++] = vesa_modes[13];
471                 DPRINTK("      1024x768@60Hz\n");
472         }
473         if (c&0x04) {
474                 mode[num++] = vesa_modes[14];
475                 DPRINTK("      1024x768@70Hz\n");
476         }
477         if (c&0x02) {
478                 mode[num++] = vesa_modes[15];
479                 DPRINTK("      1024x768@75Hz\n");
480         }
481         if (c&0x01) {
482                 mode[num++] = vesa_modes[21];
483                 DPRINTK("      1280x1024@75Hz\n");
484         }
485         c = block[2];
486         if (c&0x80) {
487                 mode[num++] = vesa_modes[17];
488                 DPRINTK("      1152x870@75Hz\n");
489         }
490         DPRINTK("      Manufacturer's mask: %x\n",c&0x7F);
491         return num;
492 }
493
494 static int get_std_timing(unsigned char *block, struct fb_videomode *mode,
495                           int ver, int rev, const struct fb_monspecs *specs)
496 {
497         int i;
498
499         for (i = 0; i < DMT_SIZE; i++) {
500                 u32 std_2byte_code = block[0] << 8 | block[1];
501                 if (std_2byte_code == dmt_modes[i].std_2byte_code)
502                         break;
503         }
504
505         if (i < DMT_SIZE && dmt_modes[i].mode) {
506                 /* DMT mode found */
507                 *mode = *dmt_modes[i].mode;
508                 mode->flag |= FB_MODE_IS_STANDARD;
509                 DPRINTK("        DMT id=%d\n", dmt_modes[i].dmt_id);
510
511         } else {
512                 int xres, yres = 0, refresh, ratio;
513
514                 xres = (block[0] + 31) * 8;
515                 if (xres <= 256)
516                         return 0;
517
518                 ratio = (block[1] & 0xc0) >> 6;
519                 switch (ratio) {
520                 case 0:
521                         /* in EDID 1.3 the meaning of 0 changed to 16:10 (prior 1:1) */
522                         if (ver < 1 || (ver == 1 && rev < 3))
523                                 yres = xres;
524                         else
525                                 yres = (xres * 10)/16;
526                         break;
527                 case 1:
528                         yres = (xres * 3)/4;
529                         break;
530                 case 2:
531                         yres = (xres * 4)/5;
532                         break;
533                 case 3:
534                         yres = (xres * 9)/16;
535                         break;
536                 }
537                 refresh = (block[1] & 0x3f) + 60;
538                 DPRINTK("      %dx%d@%dHz\n", xres, yres, refresh);
539
540                 calc_mode_timings(xres, yres, refresh, mode);
541         }
542
543         /* Check the mode we got is within valid spec of the monitor */
544         if (specs && specs->dclkmax
545             && PICOS2KHZ(mode->pixclock) * 1000 > specs->dclkmax) {
546                 DPRINTK("        mode exceed max DCLK\n");
547                 return 0;
548         }
549
550         return 1;
551 }
552
553 static int get_dst_timing(unsigned char *block, struct fb_videomode *mode,
554                           int ver, int rev, const struct fb_monspecs *specs)
555 {
556         int j, num = 0;
557
558         for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE)
559                 num += get_std_timing(block, &mode[num], ver, rev, specs);
560
561         return num;
562 }
563
564 static void get_detailed_timing(unsigned char *block,
565                                 struct fb_videomode *mode)
566 {
567         mode->xres = H_ACTIVE;
568         mode->yres = V_ACTIVE;
569         mode->pixclock = PIXEL_CLOCK;
570         mode->pixclock /= 1000;
571         mode->pixclock = KHZ2PICOS(mode->pixclock);
572         mode->right_margin = H_SYNC_OFFSET;
573         mode->left_margin = (H_ACTIVE + H_BLANKING) -
574                 (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
575         mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
576                 V_SYNC_WIDTH;
577         mode->lower_margin = V_SYNC_OFFSET;
578         mode->hsync_len = H_SYNC_WIDTH;
579         mode->vsync_len = V_SYNC_WIDTH;
580         if (HSYNC_POSITIVE)
581                 mode->sync |= FB_SYNC_HOR_HIGH_ACT;
582         if (VSYNC_POSITIVE)
583                 mode->sync |= FB_SYNC_VERT_HIGH_ACT;
584         mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
585                                      (V_ACTIVE + V_BLANKING));
586         if (INTERLACED) {
587                 mode->yres *= 2;
588                 mode->upper_margin *= 2;
589                 mode->lower_margin *= 2;
590                 mode->vsync_len *= 2;
591                 mode->vmode |= FB_VMODE_INTERLACED;
592         }
593         mode->flag = FB_MODE_IS_DETAILED;
594
595         DPRINTK("      %d MHz ",  PIXEL_CLOCK/1000000);
596         DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET,
597                H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING);
598         DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET,
599                V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING);
600         DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-",
601                (VSYNC_POSITIVE) ? "+" : "-");
602 }
603
604 /**
605  * fb_create_modedb - create video mode database
606  * @edid: EDID data
607  * @dbsize: database size
608  * @specs: monitor specifications, may be NULL
609  *
610  * RETURNS: struct fb_videomode, @dbsize contains length of database
611  *
612  * DESCRIPTION:
613  * This function builds a mode database using the contents of the EDID
614  * data
615  */
616 static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize,
617                                              const struct fb_monspecs *specs)
618 {
619         struct fb_videomode *mode, *m;
620         unsigned char *block;
621         int num = 0, i, first = 1;
622         int ver, rev;
623
624         mode = kcalloc(50, sizeof(struct fb_videomode), GFP_KERNEL);
625         if (mode == NULL)
626                 return NULL;
627
628         if (edid == NULL || !edid_checksum(edid) ||
629             !edid_check_header(edid)) {
630                 kfree(mode);
631                 return NULL;
632         }
633
634         ver = edid[EDID_STRUCT_VERSION];
635         rev = edid[EDID_STRUCT_REVISION];
636
637         *dbsize = 0;
638
639         DPRINTK("   Detailed Timings\n");
640         block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
641         for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
642                 if (!(block[0] == 0x00 && block[1] == 0x00)) {
643                         get_detailed_timing(block, &mode[num]);
644                         if (first) {
645                                 mode[num].flag |= FB_MODE_IS_FIRST;
646                                 first = 0;
647                         }
648                         num++;
649                 }
650         }
651
652         DPRINTK("   Supported VESA Modes\n");
653         block = edid + ESTABLISHED_TIMING_1;
654         num += get_est_timing(block, &mode[num]);
655
656         DPRINTK("   Standard Timings\n");
657         block = edid + STD_TIMING_DESCRIPTIONS_START;
658         for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
659                 num += get_std_timing(block, &mode[num], ver, rev, specs);
660
661         block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
662         for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
663                 if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
664                         num += get_dst_timing(block + 5, &mode[num],
665                                               ver, rev, specs);
666         }
667
668         /* Yikes, EDID data is totally useless */
669         if (!num) {
670                 kfree(mode);
671                 return NULL;
672         }
673
674         *dbsize = num;
675         m = kmalloc_array(num, sizeof(struct fb_videomode), GFP_KERNEL);
676         if (!m)
677                 return mode;
678         memmove(m, mode, num * sizeof(struct fb_videomode));
679         kfree(mode);
680         return m;
681 }
682
683 /**
684  * fb_destroy_modedb - destroys mode database
685  * @modedb: mode database to destroy
686  *
687  * DESCRIPTION:
688  * Destroy mode database created by fb_create_modedb
689  */
690 void fb_destroy_modedb(struct fb_videomode *modedb)
691 {
692         kfree(modedb);
693 }
694
695 static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
696 {
697         int i, retval = 1;
698         unsigned char *block;
699
700         block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
701
702         DPRINTK("      Monitor Operating Limits: ");
703
704         for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) {
705                 if (edid_is_limits_block(block)) {
706                         specs->hfmin = H_MIN_RATE * 1000;
707                         specs->hfmax = H_MAX_RATE * 1000;
708                         specs->vfmin = V_MIN_RATE;
709                         specs->vfmax = V_MAX_RATE;
710                         specs->dclkmax = MAX_PIXEL_CLOCK * 1000000;
711                         specs->gtf = (GTF_SUPPORT) ? 1 : 0;
712                         retval = 0;
713                         DPRINTK("From EDID\n");
714                         break;
715                 }
716         }
717
718         /* estimate monitor limits based on modes supported */
719         if (retval) {
720                 struct fb_videomode *modes, *mode;
721                 int num_modes, hz, hscan, pixclock;
722                 int vtotal, htotal;
723
724                 modes = fb_create_modedb(edid, &num_modes, specs);
725                 if (!modes) {
726                         DPRINTK("None Available\n");
727                         return 1;
728                 }
729
730                 retval = 0;
731                 for (i = 0; i < num_modes; i++) {
732                         mode = &modes[i];
733                         pixclock = PICOS2KHZ(modes[i].pixclock) * 1000;
734                         htotal = mode->xres + mode->right_margin + mode->hsync_len
735                                 + mode->left_margin;
736                         vtotal = mode->yres + mode->lower_margin + mode->vsync_len
737                                 + mode->upper_margin;
738
739                         if (mode->vmode & FB_VMODE_INTERLACED)
740                                 vtotal /= 2;
741
742                         if (mode->vmode & FB_VMODE_DOUBLE)
743                                 vtotal *= 2;
744
745                         hscan = (pixclock + htotal / 2) / htotal;
746                         hscan = (hscan + 500) / 1000 * 1000;
747                         hz = (hscan + vtotal / 2) / vtotal;
748
749                         if (specs->dclkmax == 0 || specs->dclkmax < pixclock)
750                                 specs->dclkmax = pixclock;
751
752                         if (specs->dclkmin == 0 || specs->dclkmin > pixclock)
753                                 specs->dclkmin = pixclock;
754
755                         if (specs->hfmax == 0 || specs->hfmax < hscan)
756                                 specs->hfmax = hscan;
757
758                         if (specs->hfmin == 0 || specs->hfmin > hscan)
759                                 specs->hfmin = hscan;
760
761                         if (specs->vfmax == 0 || specs->vfmax < hz)
762                                 specs->vfmax = hz;
763
764                         if (specs->vfmin == 0 || specs->vfmin > hz)
765                                 specs->vfmin = hz;
766                 }
767                 DPRINTK("Extrapolated\n");
768                 fb_destroy_modedb(modes);
769         }
770         DPRINTK("           H: %d-%dKHz V: %d-%dHz DCLK: %dMHz\n",
771                 specs->hfmin/1000, specs->hfmax/1000, specs->vfmin,
772                 specs->vfmax, specs->dclkmax/1000000);
773         return retval;
774 }
775
776 static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs)
777 {
778         unsigned char c, *block;
779
780         block = edid + EDID_STRUCT_DISPLAY;
781
782         fb_get_monitor_limits(edid, specs);
783
784         c = block[0] & 0x80;
785         specs->input = 0;
786         if (c) {
787                 specs->input |= FB_DISP_DDI;
788                 DPRINTK("      Digital Display Input");
789         } else {
790                 DPRINTK("      Analog Display Input: Input Voltage - ");
791                 switch ((block[0] & 0x60) >> 5) {
792                 case 0:
793                         DPRINTK("0.700V/0.300V");
794                         specs->input |= FB_DISP_ANA_700_300;
795                         break;
796                 case 1:
797                         DPRINTK("0.714V/0.286V");
798                         specs->input |= FB_DISP_ANA_714_286;
799                         break;
800                 case 2:
801                         DPRINTK("1.000V/0.400V");
802                         specs->input |= FB_DISP_ANA_1000_400;
803                         break;
804                 case 3:
805                         DPRINTK("0.700V/0.000V");
806                         specs->input |= FB_DISP_ANA_700_000;
807                         break;
808                 }
809         }
810         DPRINTK("\n      Sync: ");
811         c = block[0] & 0x10;
812         if (c)
813                 DPRINTK("      Configurable signal level\n");
814         c = block[0] & 0x0f;
815         specs->signal = 0;
816         if (c & 0x10) {
817                 DPRINTK("Blank to Blank ");
818                 specs->signal |= FB_SIGNAL_BLANK_BLANK;
819         }
820         if (c & 0x08) {
821                 DPRINTK("Separate ");
822                 specs->signal |= FB_SIGNAL_SEPARATE;
823         }
824         if (c & 0x04) {
825                 DPRINTK("Composite ");
826                 specs->signal |= FB_SIGNAL_COMPOSITE;
827         }
828         if (c & 0x02) {
829                 DPRINTK("Sync on Green ");
830                 specs->signal |= FB_SIGNAL_SYNC_ON_GREEN;
831         }
832         if (c & 0x01) {
833                 DPRINTK("Serration on ");
834                 specs->signal |= FB_SIGNAL_SERRATION_ON;
835         }
836         DPRINTK("\n");
837         specs->max_x = block[1];
838         specs->max_y = block[2];
839         DPRINTK("      Max H-size in cm: ");
840         if (specs->max_x)
841                 DPRINTK("%d\n", specs->max_x);
842         else
843                 DPRINTK("variable\n");
844         DPRINTK("      Max V-size in cm: ");
845         if (specs->max_y)
846                 DPRINTK("%d\n", specs->max_y);
847         else
848                 DPRINTK("variable\n");
849
850         c = block[3];
851         specs->gamma = c+100;
852         DPRINTK("      Gamma: ");
853         DPRINTK("%d.%d\n", specs->gamma/100, specs->gamma % 100);
854
855         get_dpms_capabilities(block[4], specs);
856
857         switch ((block[4] & 0x18) >> 3) {
858         case 0:
859                 DPRINTK("      Monochrome/Grayscale\n");
860                 specs->input |= FB_DISP_MONO;
861                 break;
862         case 1:
863                 DPRINTK("      RGB Color Display\n");
864                 specs->input |= FB_DISP_RGB;
865                 break;
866         case 2:
867                 DPRINTK("      Non-RGB Multicolor Display\n");
868                 specs->input |= FB_DISP_MULTI;
869                 break;
870         default:
871                 DPRINTK("      Unknown\n");
872                 specs->input |= FB_DISP_UNKNOWN;
873                 break;
874         }
875
876         get_chroma(block, specs);
877
878         specs->misc = 0;
879         c = block[4] & 0x7;
880         if (c & 0x04) {
881                 DPRINTK("      Default color format is primary\n");
882                 specs->misc |= FB_MISC_PRIM_COLOR;
883         }
884         if (c & 0x02) {
885                 DPRINTK("      First DETAILED Timing is preferred\n");
886                 specs->misc |= FB_MISC_1ST_DETAIL;
887         }
888         if (c & 0x01) {
889                 printk("      Display is GTF capable\n");
890                 specs->gtf = 1;
891         }
892 }
893
894 int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
895 {
896         int i;
897         unsigned char *block;
898
899         if (edid == NULL || var == NULL)
900                 return 1;
901
902         if (!(edid_checksum(edid)))
903                 return 1;
904
905         if (!(edid_check_header(edid)))
906                 return 1;
907
908         block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
909
910         for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) {
911                 if (edid_is_timing_block(block)) {
912                         var->xres = var->xres_virtual = H_ACTIVE;
913                         var->yres = var->yres_virtual = V_ACTIVE;
914                         var->height = var->width = 0;
915                         var->right_margin = H_SYNC_OFFSET;
916                         var->left_margin = (H_ACTIVE + H_BLANKING) -
917                                 (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
918                         var->upper_margin = V_BLANKING - V_SYNC_OFFSET -
919                                 V_SYNC_WIDTH;
920                         var->lower_margin = V_SYNC_OFFSET;
921                         var->hsync_len = H_SYNC_WIDTH;
922                         var->vsync_len = V_SYNC_WIDTH;
923                         var->pixclock = PIXEL_CLOCK;
924                         var->pixclock /= 1000;
925                         var->pixclock = KHZ2PICOS(var->pixclock);
926
927                         if (HSYNC_POSITIVE)
928                                 var->sync |= FB_SYNC_HOR_HIGH_ACT;
929                         if (VSYNC_POSITIVE)
930                                 var->sync |= FB_SYNC_VERT_HIGH_ACT;
931                         return 0;
932                 }
933         }
934         return 1;
935 }
936
937 void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
938 {
939         unsigned char *block;
940         int i, found = 0;
941
942         if (edid == NULL)
943                 return;
944
945         if (!(edid_checksum(edid)))
946                 return;
947
948         if (!(edid_check_header(edid)))
949                 return;
950
951         memset(specs, 0, sizeof(struct fb_monspecs));
952
953         specs->version = edid[EDID_STRUCT_VERSION];
954         specs->revision = edid[EDID_STRUCT_REVISION];
955
956         DPRINTK("========================================\n");
957         DPRINTK("Display Information (EDID)\n");
958         DPRINTK("========================================\n");
959         DPRINTK("   EDID Version %d.%d\n", (int) specs->version,
960                (int) specs->revision);
961
962         parse_vendor_block(edid + ID_MANUFACTURER_NAME, specs);
963
964         block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
965         for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) {
966                 if (edid_is_serial_block(block)) {
967                         copy_string(block, specs->serial_no);
968                         DPRINTK("   Serial Number: %s\n", specs->serial_no);
969                 } else if (edid_is_ascii_block(block)) {
970                         copy_string(block, specs->ascii);
971                         DPRINTK("   ASCII Block: %s\n", specs->ascii);
972                 } else if (edid_is_monitor_block(block)) {
973                         copy_string(block, specs->monitor);
974                         DPRINTK("   Monitor Name: %s\n", specs->monitor);
975                 }
976         }
977
978         DPRINTK("   Display Characteristics:\n");
979         get_monspecs(edid, specs);
980
981         specs->modedb = fb_create_modedb(edid, &specs->modedb_len, specs);
982         if (!specs->modedb)
983                 return;
984
985         /*
986          * Workaround for buggy EDIDs that sets that the first
987          * detailed timing is preferred but has not detailed
988          * timing specified
989          */
990         for (i = 0; i < specs->modedb_len; i++) {
991                 if (specs->modedb[i].flag & FB_MODE_IS_DETAILED) {
992                         found = 1;
993                         break;
994                 }
995         }
996
997         if (!found)
998                 specs->misc &= ~FB_MISC_1ST_DETAIL;
999
1000         DPRINTK("========================================\n");
1001 }
1002
1003 /*
1004  * VESA Generalized Timing Formula (GTF)
1005  */
1006
1007 #define FLYBACK                     550
1008 #define V_FRONTPORCH                1
1009 #define H_OFFSET                    40
1010 #define H_SCALEFACTOR               20
1011 #define H_BLANKSCALE                128
1012 #define H_GRADIENT                  600
1013 #define C_VAL                       30
1014 #define M_VAL                       300
1015
1016 struct __fb_timings {
1017         u32 dclk;
1018         u32 hfreq;
1019         u32 vfreq;
1020         u32 hactive;
1021         u32 vactive;
1022         u32 hblank;
1023         u32 vblank;
1024         u32 htotal;
1025         u32 vtotal;
1026 };
1027
1028 /**
1029  * fb_get_vblank - get vertical blank time
1030  * @hfreq: horizontal freq
1031  *
1032  * DESCRIPTION:
1033  * vblank = right_margin + vsync_len + left_margin
1034  *
1035  *    given: right_margin = 1 (V_FRONTPORCH)
1036  *           vsync_len    = 3
1037  *           flyback      = 550
1038  *
1039  *                          flyback * hfreq
1040  *           left_margin  = --------------- - vsync_len
1041  *                           1000000
1042  */
1043 static u32 fb_get_vblank(u32 hfreq)
1044 {
1045         u32 vblank;
1046
1047         vblank = (hfreq * FLYBACK)/1000;
1048         vblank = (vblank + 500)/1000;
1049         return (vblank + V_FRONTPORCH);
1050 }
1051
1052 /**
1053  * fb_get_hblank_by_freq - get horizontal blank time given hfreq
1054  * @hfreq: horizontal freq
1055  * @xres: horizontal resolution in pixels
1056  *
1057  * DESCRIPTION:
1058  *
1059  *           xres * duty_cycle
1060  * hblank = ------------------
1061  *           100 - duty_cycle
1062  *
1063  * duty cycle = percent of htotal assigned to inactive display
1064  * duty cycle = C - (M/Hfreq)
1065  *
1066  * where: C = ((offset - scale factor) * blank_scale)
1067  *            -------------------------------------- + scale factor
1068  *                        256
1069  *        M = blank_scale * gradient
1070  *
1071  */
1072 static u32 fb_get_hblank_by_hfreq(u32 hfreq, u32 xres)
1073 {
1074         u32 c_val, m_val, duty_cycle, hblank;
1075
1076         c_val = (((H_OFFSET - H_SCALEFACTOR) * H_BLANKSCALE)/256 +
1077                  H_SCALEFACTOR) * 1000;
1078         m_val = (H_BLANKSCALE * H_GRADIENT)/256;
1079         m_val = (m_val * 1000000)/hfreq;
1080         duty_cycle = c_val - m_val;
1081         hblank = (xres * duty_cycle)/(100000 - duty_cycle);
1082         return (hblank);
1083 }
1084
1085 /**
1086  * fb_get_hblank_by_dclk - get horizontal blank time given pixelclock
1087  * @dclk: pixelclock in Hz
1088  * @xres: horizontal resolution in pixels
1089  *
1090  * DESCRIPTION:
1091  *
1092  *           xres * duty_cycle
1093  * hblank = ------------------
1094  *           100 - duty_cycle
1095  *
1096  * duty cycle = percent of htotal assigned to inactive display
1097  * duty cycle = C - (M * h_period)
1098  *
1099  * where: h_period = SQRT(100 - C + (0.4 * xres * M)/dclk) + C - 100
1100  *                   -----------------------------------------------
1101  *                                    2 * M
1102  *        M = 300;
1103  *        C = 30;
1104  */
1105 static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres)
1106 {
1107         u32 duty_cycle, h_period, hblank;
1108
1109         dclk /= 1000;
1110         h_period = 100 - C_VAL;
1111         h_period *= h_period;
1112         h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk);
1113         h_period *= 10000;
1114
1115         h_period = int_sqrt(h_period);
1116         h_period -= (100 - C_VAL) * 100;
1117         h_period *= 1000;
1118         h_period /= 2 * M_VAL;
1119
1120         duty_cycle = C_VAL * 1000 - (M_VAL * h_period)/100;
1121         hblank = (xres * duty_cycle)/(100000 - duty_cycle) + 8;
1122         hblank &= ~15;
1123         return (hblank);
1124 }
1125
1126 /**
1127  * fb_get_hfreq - estimate hsync
1128  * @vfreq: vertical refresh rate
1129  * @yres: vertical resolution
1130  *
1131  * DESCRIPTION:
1132  *
1133  *          (yres + front_port) * vfreq * 1000000
1134  * hfreq = -------------------------------------
1135  *          (1000000 - (vfreq * FLYBACK)
1136  *
1137  */
1138
1139 static u32 fb_get_hfreq(u32 vfreq, u32 yres)
1140 {
1141         u32 divisor, hfreq;
1142
1143         divisor = (1000000 - (vfreq * FLYBACK))/1000;
1144         hfreq = (yres + V_FRONTPORCH) * vfreq  * 1000;
1145         return (hfreq/divisor);
1146 }
1147
1148 static void fb_timings_vfreq(struct __fb_timings *timings)
1149 {
1150         timings->hfreq = fb_get_hfreq(timings->vfreq, timings->vactive);
1151         timings->vblank = fb_get_vblank(timings->hfreq);
1152         timings->vtotal = timings->vactive + timings->vblank;
1153         timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq,
1154                                                  timings->hactive);
1155         timings->htotal = timings->hactive + timings->hblank;
1156         timings->dclk = timings->htotal * timings->hfreq;
1157 }
1158
1159 static void fb_timings_hfreq(struct __fb_timings *timings)
1160 {
1161         timings->vblank = fb_get_vblank(timings->hfreq);
1162         timings->vtotal = timings->vactive + timings->vblank;
1163         timings->vfreq = timings->hfreq/timings->vtotal;
1164         timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq,
1165                                                  timings->hactive);
1166         timings->htotal = timings->hactive + timings->hblank;
1167         timings->dclk = timings->htotal * timings->hfreq;
1168 }
1169
1170 static void fb_timings_dclk(struct __fb_timings *timings)
1171 {
1172         timings->hblank = fb_get_hblank_by_dclk(timings->dclk,
1173                                                 timings->hactive);
1174         timings->htotal = timings->hactive + timings->hblank;
1175         timings->hfreq = timings->dclk/timings->htotal;
1176         timings->vblank = fb_get_vblank(timings->hfreq);
1177         timings->vtotal = timings->vactive + timings->vblank;
1178         timings->vfreq = timings->hfreq/timings->vtotal;
1179 }
1180
1181 /*
1182  * fb_get_mode - calculates video mode using VESA GTF
1183  * @flags: if: 0 - maximize vertical refresh rate
1184  *             1 - vrefresh-driven calculation;
1185  *             2 - hscan-driven calculation;
1186  *             3 - pixelclock-driven calculation;
1187  * @val: depending on @flags, ignored, vrefresh, hsync or pixelclock
1188  * @var: pointer to fb_var_screeninfo
1189  * @info: pointer to fb_info
1190  *
1191  * DESCRIPTION:
1192  * Calculates video mode based on monitor specs using VESA GTF.
1193  * The GTF is best for VESA GTF compliant monitors but is
1194  * specifically formulated to work for older monitors as well.
1195  *
1196  * If @flag==0, the function will attempt to maximize the
1197  * refresh rate.  Otherwise, it will calculate timings based on
1198  * the flag and accompanying value.
1199  *
1200  * If FB_IGNOREMON bit is set in @flags, monitor specs will be
1201  * ignored and @var will be filled with the calculated timings.
1202  *
1203  * All calculations are based on the VESA GTF Spreadsheet
1204  * available at VESA's public ftp (https://www.vesa.org).
1205  *
1206  * NOTES:
1207  * The timings generated by the GTF will be different from VESA
1208  * DMT.  It might be a good idea to keep a table of standard
1209  * VESA modes as well.  The GTF may also not work for some displays,
1210  * such as, and especially, analog TV.
1211  *
1212  * REQUIRES:
1213  * A valid info->monspecs, otherwise 'safe numbers' will be used.
1214  */
1215 int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info)
1216 {
1217         struct __fb_timings *timings;
1218         u32 interlace = 1, dscan = 1;
1219         u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax, err = 0;
1220
1221
1222         timings = kzalloc(sizeof(struct __fb_timings), GFP_KERNEL);
1223
1224         if (!timings)
1225                 return -ENOMEM;
1226
1227         /*
1228          * If monspecs are invalid, use values that are enough
1229          * for 640x480@60
1230          */
1231         if (!info || !info->monspecs.hfmax || !info->monspecs.vfmax ||
1232             !info->monspecs.dclkmax ||
1233             info->monspecs.hfmax < info->monspecs.hfmin ||
1234             info->monspecs.vfmax < info->monspecs.vfmin ||
1235             info->monspecs.dclkmax < info->monspecs.dclkmin) {
1236                 hfmin = 29000; hfmax = 30000;
1237                 vfmin = 60; vfmax = 60;
1238                 dclkmin = 0; dclkmax = 25000000;
1239         } else {
1240                 hfmin = info->monspecs.hfmin;
1241                 hfmax = info->monspecs.hfmax;
1242                 vfmin = info->monspecs.vfmin;
1243                 vfmax = info->monspecs.vfmax;
1244                 dclkmin = info->monspecs.dclkmin;
1245                 dclkmax = info->monspecs.dclkmax;
1246         }
1247
1248         timings->hactive = var->xres;
1249         timings->vactive = var->yres;
1250         if (var->vmode & FB_VMODE_INTERLACED) {
1251                 timings->vactive /= 2;
1252                 interlace = 2;
1253         }
1254         if (var->vmode & FB_VMODE_DOUBLE) {
1255                 timings->vactive *= 2;
1256                 dscan = 2;
1257         }
1258
1259         switch (flags & ~FB_IGNOREMON) {
1260         case FB_MAXTIMINGS: /* maximize refresh rate */
1261                 timings->hfreq = hfmax;
1262                 fb_timings_hfreq(timings);
1263                 if (timings->vfreq > vfmax) {
1264                         timings->vfreq = vfmax;
1265                         fb_timings_vfreq(timings);
1266                 }
1267                 if (timings->dclk > dclkmax) {
1268                         timings->dclk = dclkmax;
1269                         fb_timings_dclk(timings);
1270                 }
1271                 break;
1272         case FB_VSYNCTIMINGS: /* vrefresh driven */
1273                 timings->vfreq = val;
1274                 fb_timings_vfreq(timings);
1275                 break;
1276         case FB_HSYNCTIMINGS: /* hsync driven */
1277                 timings->hfreq = val;
1278                 fb_timings_hfreq(timings);
1279                 break;
1280         case FB_DCLKTIMINGS: /* pixelclock driven */
1281                 timings->dclk = PICOS2KHZ(val) * 1000;
1282                 fb_timings_dclk(timings);
1283                 break;
1284         default:
1285                 err = -EINVAL;
1286
1287         }
1288
1289         if (err || (!(flags & FB_IGNOREMON) &&
1290             (timings->vfreq < vfmin || timings->vfreq > vfmax ||
1291              timings->hfreq < hfmin || timings->hfreq > hfmax ||
1292              timings->dclk < dclkmin || timings->dclk > dclkmax))) {
1293                 err = -EINVAL;
1294         } else {
1295                 var->pixclock = KHZ2PICOS(timings->dclk/1000);
1296                 var->hsync_len = (timings->htotal * 8)/100;
1297                 var->right_margin = (timings->hblank/2) - var->hsync_len;
1298                 var->left_margin = timings->hblank - var->right_margin -
1299                         var->hsync_len;
1300                 var->vsync_len = (3 * interlace)/dscan;
1301                 var->lower_margin = (1 * interlace)/dscan;
1302                 var->upper_margin = (timings->vblank * interlace)/dscan -
1303                         (var->vsync_len + var->lower_margin);
1304         }
1305
1306         kfree(timings);
1307         return err;
1308 }
1309
1310 #ifdef CONFIG_VIDEOMODE_HELPERS
1311 int fb_videomode_from_videomode(const struct videomode *vm,
1312                                 struct fb_videomode *fbmode)
1313 {
1314         unsigned int htotal, vtotal;
1315
1316         fbmode->xres = vm->hactive;
1317         fbmode->left_margin = vm->hback_porch;
1318         fbmode->right_margin = vm->hfront_porch;
1319         fbmode->hsync_len = vm->hsync_len;
1320
1321         fbmode->yres = vm->vactive;
1322         fbmode->upper_margin = vm->vback_porch;
1323         fbmode->lower_margin = vm->vfront_porch;
1324         fbmode->vsync_len = vm->vsync_len;
1325
1326         /* prevent division by zero in KHZ2PICOS macro */
1327         fbmode->pixclock = vm->pixelclock ?
1328                         KHZ2PICOS(vm->pixelclock / 1000) : 0;
1329
1330         fbmode->sync = 0;
1331         fbmode->vmode = 0;
1332         if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH)
1333                 fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
1334         if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH)
1335                 fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
1336         if (vm->flags & DISPLAY_FLAGS_INTERLACED)
1337                 fbmode->vmode |= FB_VMODE_INTERLACED;
1338         if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN)
1339                 fbmode->vmode |= FB_VMODE_DOUBLE;
1340         fbmode->flag = 0;
1341
1342         htotal = vm->hactive + vm->hfront_porch + vm->hback_porch +
1343                  vm->hsync_len;
1344         vtotal = vm->vactive + vm->vfront_porch + vm->vback_porch +
1345                  vm->vsync_len;
1346         /* prevent division by zero */
1347         if (htotal && vtotal) {
1348                 fbmode->refresh = vm->pixelclock / (htotal * vtotal);
1349         /* a mode must have htotal and vtotal != 0 or it is invalid */
1350         } else {
1351                 fbmode->refresh = 0;
1352                 return -EINVAL;
1353         }
1354
1355         return 0;
1356 }
1357 EXPORT_SYMBOL_GPL(fb_videomode_from_videomode);
1358
1359 #ifdef CONFIG_OF
1360 static inline void dump_fb_videomode(const struct fb_videomode *m)
1361 {
1362         pr_debug("fb_videomode = %ux%u@%uHz (%ukHz) %u %u %u %u %u %u %u %u %u\n",
1363                  m->xres, m->yres, m->refresh, m->pixclock, m->left_margin,
1364                  m->right_margin, m->upper_margin, m->lower_margin,
1365                  m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
1366 }
1367
1368 /**
1369  * of_get_fb_videomode - get a fb_videomode from devicetree
1370  * @np: device_node with the timing specification
1371  * @fb: will be set to the return value
1372  * @index: index into the list of display timings in devicetree
1373  *
1374  * DESCRIPTION:
1375  * This function is expensive and should only be used, if only one mode is to be
1376  * read from DT. To get multiple modes start with of_get_display_timings ond
1377  * work with that instead.
1378  */
1379 int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fb,
1380                         int index)
1381 {
1382         struct videomode vm;
1383         int ret;
1384
1385         ret = of_get_videomode(np, &vm, index);
1386         if (ret)
1387                 return ret;
1388
1389         ret = fb_videomode_from_videomode(&vm, fb);
1390         if (ret)
1391                 return ret;
1392
1393         pr_debug("%pOF: got %dx%d display mode\n",
1394                 np, vm.hactive, vm.vactive);
1395         dump_fb_videomode(fb);
1396
1397         return 0;
1398 }
1399 EXPORT_SYMBOL_GPL(of_get_fb_videomode);
1400 #endif /* CONFIG_OF */
1401 #endif /* CONFIG_VIDEOMODE_HELPERS */
1402
1403 #else
1404 int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
1405 {
1406         return 1;
1407 }
1408 void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
1409 {
1410 }
1411 void fb_destroy_modedb(struct fb_videomode *modedb)
1412 {
1413 }
1414 int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var,
1415                 struct fb_info *info)
1416 {
1417         return -EINVAL;
1418 }
1419 #endif /* CONFIG_FB_MODE_HELPERS */
1420
1421 /*
1422  * fb_validate_mode - validates var against monitor capabilities
1423  * @var: pointer to fb_var_screeninfo
1424  * @info: pointer to fb_info
1425  *
1426  * DESCRIPTION:
1427  * Validates video mode against monitor capabilities specified in
1428  * info->monspecs.
1429  *
1430  * REQUIRES:
1431  * A valid info->monspecs.
1432  */
1433 int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info)
1434 {
1435         u32 hfreq, vfreq, htotal, vtotal, pixclock;
1436         u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax;
1437
1438         /*
1439          * If monspecs are invalid, use values that are enough
1440          * for 640x480@60
1441          */
1442         if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
1443             !info->monspecs.dclkmax ||
1444             info->monspecs.hfmax < info->monspecs.hfmin ||
1445             info->monspecs.vfmax < info->monspecs.vfmin ||
1446             info->monspecs.dclkmax < info->monspecs.dclkmin) {
1447                 hfmin = 29000; hfmax = 30000;
1448                 vfmin = 60; vfmax = 60;
1449                 dclkmin = 0; dclkmax = 25000000;
1450         } else {
1451                 hfmin = info->monspecs.hfmin;
1452                 hfmax = info->monspecs.hfmax;
1453                 vfmin = info->monspecs.vfmin;
1454                 vfmax = info->monspecs.vfmax;
1455                 dclkmin = info->monspecs.dclkmin;
1456                 dclkmax = info->monspecs.dclkmax;
1457         }
1458
1459         if (!var->pixclock)
1460                 return -EINVAL;
1461         pixclock = PICOS2KHZ(var->pixclock) * 1000;
1462
1463         htotal = var->xres + var->right_margin + var->hsync_len +
1464                 var->left_margin;
1465         vtotal = var->yres + var->lower_margin + var->vsync_len +
1466                 var->upper_margin;
1467
1468         if (var->vmode & FB_VMODE_INTERLACED)
1469                 vtotal /= 2;
1470         if (var->vmode & FB_VMODE_DOUBLE)
1471                 vtotal *= 2;
1472
1473         hfreq = pixclock/htotal;
1474         hfreq = (hfreq + 500) / 1000 * 1000;
1475
1476         vfreq = hfreq/vtotal;
1477
1478         return (vfreq < vfmin || vfreq > vfmax ||
1479                 hfreq < hfmin || hfreq > hfmax ||
1480                 pixclock < dclkmin || pixclock > dclkmax) ?
1481                 -EINVAL : 0;
1482 }
1483
1484 #if defined(CONFIG_FIRMWARE_EDID) && defined(CONFIG_X86)
1485
1486 /*
1487  * We need to ensure that the EDID block is only returned for
1488  * the primary graphics adapter.
1489  */
1490
1491 const unsigned char *fb_firmware_edid(struct device *device)
1492 {
1493         struct pci_dev *dev = NULL;
1494         struct resource *res = NULL;
1495         unsigned char *edid = NULL;
1496
1497         if (device)
1498                 dev = to_pci_dev(device);
1499
1500         if (dev)
1501                 res = &dev->resource[PCI_ROM_RESOURCE];
1502
1503         if (res && res->flags & IORESOURCE_ROM_SHADOW)
1504                 edid = edid_info.dummy;
1505
1506         return edid;
1507 }
1508 #else
1509 const unsigned char *fb_firmware_edid(struct device *device)
1510 {
1511         return NULL;
1512 }
1513 #endif
1514 EXPORT_SYMBOL(fb_firmware_edid);
1515
1516 EXPORT_SYMBOL(fb_parse_edid);
1517 EXPORT_SYMBOL(fb_edid_to_monspecs);
1518 EXPORT_SYMBOL(fb_get_mode);
1519 EXPORT_SYMBOL(fb_validate_mode);
1520 EXPORT_SYMBOL(fb_destroy_modedb);