Merge branch 'android-2.6.36' into android-tegra-2.6.36
[firefly-linux-kernel-4.4.55.git] / drivers / video / modedb.c
1 /*
2  *  linux/drivers/video/modedb.c -- Standard video mode database management
3  *
4  *      Copyright (C) 1999 Geert Uytterhoeven
5  *
6  *      2001 - Documented with DocBook
7  *      - Brad Douglas <brad@neruo.com>
8  *
9  *  This file is subject to the terms and conditions of the GNU General Public
10  *  License. See the file COPYING in the main directory of this archive for
11  *  more details.
12  */
13
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/fb.h>
17 #include <linux/kernel.h>
18
19 #undef DEBUG
20
21 #define name_matches(v, s, l) \
22     ((v).name && !strncmp((s), (v).name, (l)) && strlen((v).name) == (l))
23 #define res_matches(v, x, y) \
24     ((v).xres == (x) && (v).yres == (y))
25
26 #ifdef DEBUG
27 #define DPRINTK(fmt, args...)   printk("modedb %s: " fmt, __func__ , ## args)
28 #else
29 #define DPRINTK(fmt, args...)
30 #endif
31
32 const char *fb_mode_option;
33 EXPORT_SYMBOL_GPL(fb_mode_option);
34
35     /*
36      *  Standard video mode definitions (taken from XFree86)
37      */
38
39 static const struct fb_videomode modedb[] = {
40     {
41         /* 640x400 @ 70 Hz, 31.5 kHz hsync */
42         NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
43         0, FB_VMODE_NONINTERLACED
44     }, {
45         /* 640x480 @ 60 Hz, 31.5 kHz hsync */
46         NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
47         0, FB_VMODE_NONINTERLACED
48     }, {
49         /* 800x600 @ 56 Hz, 35.15 kHz hsync */
50         NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
51         0, FB_VMODE_NONINTERLACED
52     }, {
53         /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
54         NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
55         0, FB_VMODE_INTERLACED
56     }, {
57         /* 640x400 @ 85 Hz, 37.86 kHz hsync */
58         NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
59         FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
60     }, {
61         /* 640x480 @ 72 Hz, 36.5 kHz hsync */
62         NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
63         0, FB_VMODE_NONINTERLACED
64     }, {
65         /* 640x480 @ 75 Hz, 37.50 kHz hsync */
66         NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
67         0, FB_VMODE_NONINTERLACED
68     }, {
69         /* 800x600 @ 60 Hz, 37.8 kHz hsync */
70         NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
71         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
72     }, {
73         /* 640x480 @ 85 Hz, 43.27 kHz hsync */
74         NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
75         0, FB_VMODE_NONINTERLACED
76     }, {
77         /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
78         NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
79         0, FB_VMODE_INTERLACED
80     }, {
81         /* 800x600 @ 72 Hz, 48.0 kHz hsync */
82         NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
83         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
84     }, {
85         /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
86         NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
87         0, FB_VMODE_NONINTERLACED
88     }, {
89         /* 640x480 @ 100 Hz, 53.01 kHz hsync */
90         NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
91         0, FB_VMODE_NONINTERLACED
92     }, {
93         /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
94         NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
95         0, FB_VMODE_NONINTERLACED
96     }, {
97         /* 800x600 @ 85 Hz, 55.84 kHz hsync */
98         NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
99         0, FB_VMODE_NONINTERLACED
100     }, {
101         /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
102         NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
103         0, FB_VMODE_NONINTERLACED
104     }, {
105         /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
106         NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
107         0, FB_VMODE_INTERLACED
108     }, {
109         /* 800x600 @ 100 Hz, 64.02 kHz hsync */
110         NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
111         0, FB_VMODE_NONINTERLACED
112     }, {
113         /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
114         NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
115         0, FB_VMODE_NONINTERLACED
116     }, {
117         /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
118         NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
119         0, FB_VMODE_NONINTERLACED
120     }, {
121         /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
122         NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
123         0, FB_VMODE_NONINTERLACED
124     }, {
125         /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
126         NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
127         0, FB_VMODE_NONINTERLACED       
128     }, {
129         /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
130         NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
131         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
132     }, {
133         /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
134         NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
135         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
136     }, {
137         /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
138         NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
139         0, FB_VMODE_NONINTERLACED
140     }, {
141         /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
142         NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
143         0, FB_VMODE_NONINTERLACED
144     }, {
145         /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
146         NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
147         0, FB_VMODE_NONINTERLACED
148     }, {
149         /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
150         NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
151         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
152     }, {
153         /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
154         NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
155         0, FB_VMODE_NONINTERLACED
156     }, {
157         /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
158         NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
159         0, FB_VMODE_NONINTERLACED
160     }, {
161         /* 1024x768 @ 100Hz, 80.21 kHz hsync */
162         NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
163         0, FB_VMODE_NONINTERLACED
164     }, {
165         /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
166         NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
167         0, FB_VMODE_NONINTERLACED
168     }, {
169         /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
170         NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
171         0, FB_VMODE_NONINTERLACED
172     }, {
173         /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
174         NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
175         0, FB_VMODE_NONINTERLACED
176     }, {
177         /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
178         NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
179         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
180     }, {
181         /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
182         NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
183         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
184     }, {
185         /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
186         NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
187         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
188     }, {
189         /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
190         NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
191         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
192     }, {
193         /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
194         NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
195         0, FB_VMODE_NONINTERLACED
196     }, {
197         /* 1800x1440 @ 64Hz, 96.15 kHz hsync  */
198         NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
199         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
200     }, {
201         /* 1800x1440 @ 70Hz, 104.52 kHz hsync  */
202         NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
203         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
204     }, {
205         /* 512x384 @ 78 Hz, 31.50 kHz hsync */
206         NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
207         0, FB_VMODE_NONINTERLACED
208     }, {
209         /* 512x384 @ 85 Hz, 34.38 kHz hsync */
210         NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
211         0, FB_VMODE_NONINTERLACED
212     }, {
213         /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
214         NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
215         0, FB_VMODE_DOUBLE
216     }, {
217         /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
218         NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
219         0, FB_VMODE_DOUBLE
220     }, {
221         /* 320x240 @ 72 Hz, 36.5 kHz hsync */
222         NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
223         0, FB_VMODE_DOUBLE
224     }, {
225         /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
226         NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
227         0, FB_VMODE_DOUBLE
228     }, {
229         /* 400x300 @ 60 Hz, 37.8 kHz hsync */
230         NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
231         0, FB_VMODE_DOUBLE
232     }, {
233         /* 400x300 @ 72 Hz, 48.0 kHz hsync */
234         NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
235         0, FB_VMODE_DOUBLE
236     }, {
237         /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
238         NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
239         0, FB_VMODE_DOUBLE
240     }, {
241         /* 480x300 @ 60 Hz, 37.8 kHz hsync */
242         NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
243         0, FB_VMODE_DOUBLE
244     }, {
245         /* 480x300 @ 63 Hz, 39.6 kHz hsync */
246         NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
247         0, FB_VMODE_DOUBLE
248     }, {
249         /* 480x300 @ 72 Hz, 48.0 kHz hsync */
250         NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
251         0, FB_VMODE_DOUBLE
252     }, {
253         /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
254         NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
255         FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
256         FB_VMODE_NONINTERLACED
257     }, {
258         /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
259         NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
260         FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
261     }, {
262         /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
263         NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
264         0, FB_VMODE_NONINTERLACED
265    }, {
266         /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
267         NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
268         0, FB_VMODE_NONINTERLACED
269     }, {
270        /* 720x576i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */
271        NULL, 50, 720, 576, 74074, 64, 16, 39, 5, 64, 5,
272        0, FB_VMODE_INTERLACED
273     }, {
274        /* 800x520i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */
275        NULL, 50, 800, 520, 58823, 144, 64, 72, 28, 80, 5,
276        0, FB_VMODE_INTERLACED
277     },
278 };
279
280 #ifdef CONFIG_FB_MODE_HELPERS
281 const struct fb_videomode vesa_modes[] = {
282         /* 0 640x350-85 VESA */
283         { NULL, 85, 640, 350, 31746,  96, 32, 60, 32, 64, 3,
284           FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA},
285         /* 1 640x400-85 VESA */
286         { NULL, 85, 640, 400, 31746,  96, 32, 41, 01, 64, 3,
287           FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
288         /* 2 720x400-85 VESA */
289         { NULL, 85, 721, 400, 28169, 108, 36, 42, 01, 72, 3,
290           FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
291         /* 3 640x480-60 VESA */
292         { NULL, 60, 640, 480, 39682,  48, 16, 33, 10, 96, 2, 
293           0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
294         /* 4 640x480-72 VESA */
295         { NULL, 72, 640, 480, 31746, 128, 24, 29, 9, 40, 2, 
296           0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
297         /* 5 640x480-75 VESA */
298         { NULL, 75, 640, 480, 31746, 120, 16, 16, 01, 64, 3,
299           0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
300         /* 6 640x480-85 VESA */
301         { NULL, 85, 640, 480, 27777, 80, 56, 25, 01, 56, 3,
302           0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
303         /* 7 800x600-56 VESA */
304         { NULL, 56, 800, 600, 27777, 128, 24, 22, 01, 72, 2,
305           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
306           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
307         /* 8 800x600-60 VESA */
308         { NULL, 60, 800, 600, 25000, 88, 40, 23, 01, 128, 4,
309           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
310           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
311         /* 9 800x600-72 VESA */
312         { NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
313           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
314           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
315         /* 10 800x600-75 VESA */
316         { NULL, 75, 800, 600, 20202, 160, 16, 21, 01, 80, 3,
317           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
318           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
319         /* 11 800x600-85 VESA */
320         { NULL, 85, 800, 600, 17761, 152, 32, 27, 01, 64, 3,
321           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
322           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
323         /* 12 1024x768i-43 VESA */
324         { NULL, 43, 1024, 768, 22271, 56, 8, 41, 0, 176, 8,
325           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
326           FB_VMODE_INTERLACED, FB_MODE_IS_VESA },
327         /* 13 1024x768-60 VESA */
328         { NULL, 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6,
329           0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
330         /* 14 1024x768-70 VESA */
331         { NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
332           0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
333         /* 15 1024x768-75 VESA */
334         { NULL, 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3,
335           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
336           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
337         /* 16 1024x768-85 VESA */
338         { NULL, 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3,
339           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
340           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
341         /* 17 1152x864-75 VESA */
342         { NULL, 75, 1152, 864, 9259, 256, 64, 32, 1, 128, 3,
343           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
344           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
345         /* 18 1280x960-60 VESA */
346         { NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3,
347           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
348           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
349         /* 19 1280x960-85 VESA */
350         { NULL, 85, 1280, 960, 6734, 224, 64, 47, 1, 160, 3,
351           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
352           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
353         /* 20 1280x1024-60 VESA */
354         { NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
355           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
356           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
357         /* 21 1280x1024-75 VESA */
358         { NULL, 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3,
359           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
360           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
361         /* 22 1280x1024-85 VESA */
362         { NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
363           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
364           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
365         /* 23 1600x1200-60 VESA */
366         { NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
367           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
368           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
369         /* 24 1600x1200-65 VESA */
370         { NULL, 65, 1600, 1200, 5698, 304,  64, 46, 1, 192, 3,
371           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
372           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
373         /* 25 1600x1200-70 VESA */
374         { NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
375           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
376           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
377         /* 26 1600x1200-75 VESA */
378         { NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, 
379           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
380           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
381         /* 27 1600x1200-85 VESA */
382         { NULL, 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3,
383           FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
384           FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
385         /* 28 1792x1344-60 VESA */
386         { NULL, 60, 1792, 1344, 4882, 328, 128, 46, 1, 200, 3,
387           FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
388         /* 29 1792x1344-75 VESA */
389         { NULL, 75, 1792, 1344, 3831, 352, 96, 69, 1, 216, 3,
390           FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
391         /* 30 1856x1392-60 VESA */
392         { NULL, 60, 1856, 1392, 4580, 352, 96, 43, 1, 224, 3,
393           FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
394         /* 31 1856x1392-75 VESA */
395         { NULL, 75, 1856, 1392, 3472, 352, 128, 104, 1, 224, 3,
396           FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
397         /* 32 1920x1440-60 VESA */
398         { NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 200, 3,
399           FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
400         /* 33 1920x1440-75 VESA */
401         { NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
402           FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
403 };
404 EXPORT_SYMBOL(vesa_modes);
405
406 const struct fb_videomode cea_modes[CEA_MODEDB_SIZE] = {
407         {},
408         /* 1: 640x480p @ 59.94Hz/60Hz */
409         {.refresh = 59, .xres = 640, .yres = 480, .pixclock = 39721,
410          .left_margin = 48, .right_margin = 16,
411          .upper_margin = 33, .lower_margin = 1,
412          .hsync_len = 96, .vsync_len = 2,
413          .sync = 0,
414          .vmode = FB_VMODE_NONINTERLACED},
415         /* 2: 720x480p @ 59.94Hz/60Hz */
416         {.refresh = 59, .xres = 720, .yres = 480, .pixclock = 37037,
417          .left_margin = 60, .right_margin = 16,
418          .upper_margin = 30, .lower_margin = 9,
419          .hsync_len = 62, .vsync_len = 6,
420          .sync = 0,
421          .vmode = FB_VMODE_NONINTERLACED},
422         /* 3: 720x480p @ 59.94Hz/60Hz */
423         {.refresh = 59, .xres = 720, .yres = 480, .pixclock = 37037,
424          .left_margin = 60, .right_margin = 16,
425          .upper_margin = 30, .lower_margin = 9,
426          .hsync_len = 62, .vsync_len = 6,
427          .sync = 0,
428          .vmode = FB_VMODE_NONINTERLACED},
429         /* 4: 1280x720p @ 59.94Hz/60Hz */
430         {.refresh = 60, .xres = 1280, .yres = 720, .pixclock = 13468,
431          .left_margin = 220, .right_margin = 110,
432          .upper_margin = 20, .lower_margin = 5,
433          .hsync_len = 40, .vsync_len = 5,
434          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
435          .vmode = FB_VMODE_NONINTERLACED},
436         /* 5: 1920x1080i @ 59.94Hz/60Hz */
437         {.refresh = 60, .xres = 1920, .yres = 1080, .pixclock = 13468,
438          .left_margin = 148, .right_margin = 88,
439          .upper_margin = 15, .lower_margin = 2,
440          .hsync_len = 44, .vsync_len = 5,
441          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
442          .vmode = FB_VMODE_INTERLACED},
443         /* 6: 720(1440)x480i @ 59.94Hz/60Hz */
444         {.refresh = 59, .xres = 1440, .yres = 480, .pixclock = 37037,
445          .left_margin = 114, .right_margin = 38,
446          .upper_margin = 15, .lower_margin = 4,
447          .hsync_len = 124, .vsync_len = 3,
448          .sync = 0,
449          .vmode = FB_VMODE_INTERLACED},
450         /* 7: 720(1440)x480i @ 59.94Hz/60Hz */
451         {.refresh = 59, .xres = 1440, .yres = 480, .pixclock = 37037,
452          .left_margin = 114, .right_margin = 38,
453          .upper_margin = 15, .lower_margin = 4,
454          .hsync_len = 124, .vsync_len = 3,
455          .sync = 0,
456          .vmode = FB_VMODE_INTERLACED},
457         /* 8: 720(1440)x240p @ 59.94Hz/60Hz */
458         {.refresh = 59, .xres = 1440, .yres = 240, .pixclock = 37037,
459          .left_margin = 114, .right_margin = 38,
460          .upper_margin = 15, .lower_margin = 5,
461          .hsync_len = 124, .vsync_len = 3,
462          .sync = 0,
463          .vmode = FB_VMODE_NONINTERLACED},
464         /* 9: 720(1440)x240p @ 59.94Hz/60Hz */
465         {.refresh = 59, .xres = 1440, .yres = 240, .pixclock = 37037,
466          .left_margin = 114, .right_margin = 38,
467          .upper_margin = 15, .lower_margin = 5,
468          .hsync_len = 124, .vsync_len = 3,
469          .sync = 0,
470          .vmode = FB_VMODE_NONINTERLACED},
471         /* 10: 2880x480i @ 59.94Hz/60Hz */
472         {.refresh = 59, .xres = 2880, .yres = 480, .pixclock = 18518,
473          .left_margin = 228, .right_margin = 76,
474          .upper_margin = 15, .lower_margin = 4,
475          .hsync_len = 248, .vsync_len = 3,
476          .sync = 0,
477          .vmode = FB_VMODE_INTERLACED},
478         /* 11: 2880x480i @ 59.94Hz/60Hz */
479         {.refresh = 59, .xres = 2880, .yres = 480, .pixclock = 18518,
480          .left_margin = 228, .right_margin = 76,
481          .upper_margin = 15, .lower_margin = 4,
482          .hsync_len = 248, .vsync_len = 3,
483          .sync = 0,
484          .vmode = FB_VMODE_INTERLACED},
485         /* 12: 2880x240p @ 59.94Hz/60Hz */
486         {.refresh = 59, .xres = 2880, .yres = 240, .pixclock = 18518,
487          .left_margin = 228, .right_margin = 76,
488          .upper_margin = 15, .lower_margin = 5,
489          .hsync_len = 248, .vsync_len = 3,
490          .sync = 0,
491          .vmode = FB_VMODE_NONINTERLACED},
492         /* 13: 2880x240p @ 59.94Hz/60Hz */
493         {.refresh = 59, .xres = 2880, .yres = 240, .pixclock = 18518,
494          .left_margin = 228, .right_margin = 76,
495          .upper_margin = 15, .lower_margin = 5,
496          .hsync_len = 248, .vsync_len = 3,
497          .sync = 0,
498          .vmode = FB_VMODE_NONINTERLACED},
499         /* 14: 1440x480p @ 59.94Hz/60Hz */
500         {.refresh = 59, .xres = 1440, .yres = 480, .pixclock = 18518,
501          .left_margin = 120, .right_margin = 32,
502          .upper_margin = 30, .lower_margin = 9,
503          .hsync_len = 124, .vsync_len = 6,
504          .sync = 0,
505          .vmode = FB_VMODE_NONINTERLACED},
506         /* 15: 1440x480p @ 59.94Hz/60Hz */
507         {.refresh = 59, .xres = 1440, .yres = 480, .pixclock = 18518,
508          .left_margin = 120, .right_margin = 32,
509          .upper_margin = 30, .lower_margin = 9,
510          .hsync_len = 124, .vsync_len = 6,
511          .sync = 0,
512          .vmode = FB_VMODE_NONINTERLACED},
513         /* 16: 1920x1080p @ 59.94Hz/60Hz */
514         {.refresh = 60, .xres = 1920, .yres = 1080, .pixclock = 6734,
515          .left_margin = 148, .right_margin = 88,
516          .upper_margin = 36, .lower_margin = 4,
517          .hsync_len = 44, .vsync_len = 5,
518          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
519          .vmode = FB_VMODE_NONINTERLACED},
520         /* 17: 720x576p @ 50Hz */
521         {.refresh = 50, .xres = 720, .yres = 576, .pixclock = 37037,
522          .left_margin = 68, .right_margin = 12,
523          .upper_margin = 39, .lower_margin = 5,
524          .hsync_len = 64, .vsync_len = 5,
525          .sync = 0,
526          .vmode = FB_VMODE_NONINTERLACED},
527         /* 18: 720x576p @ 50Hz */
528         {.refresh = 50, .xres = 720, .yres = 576, .pixclock = 37037,
529          .left_margin = 68, .right_margin = 12,
530          .upper_margin = 39, .lower_margin = 5,
531          .hsync_len = 64, .vsync_len = 5,
532          .sync = 0,
533          .vmode = FB_VMODE_NONINTERLACED},
534         /* 19: 1280x720p @ 50Hz */
535         {.refresh = 50, .xres = 1280, .yres = 720, .pixclock = 13468,
536          .left_margin = 220, .right_margin = 440,
537          .upper_margin = 20, .lower_margin = 5,
538          .hsync_len = 40, .vsync_len = 5,
539          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
540          .vmode = FB_VMODE_NONINTERLACED},
541         /* 20: 1920x1080i @ 50Hz */
542         {.refresh = 50, .xres = 1920, .yres = 1080, .pixclock = 13468,
543          .left_margin = 148, .right_margin = 528,
544          .upper_margin = 15, .lower_margin = 2,
545          .hsync_len = 44, .vsync_len = 5,
546          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
547          .vmode = FB_VMODE_INTERLACED},
548         /* 21: 720(1440)x576i @ 50Hz */
549         {.refresh = 50, .xres = 1440, .yres = 576, .pixclock = 37037,
550          .left_margin = 138, .right_margin = 24,
551          .upper_margin = 19, .lower_margin = 2,
552          .hsync_len = 126, .vsync_len = 3,
553          .sync = 0,
554          .vmode = FB_VMODE_INTERLACED},
555         /* 22: 720(1440)x576i @ 50Hz */
556         {.refresh = 50, .xres = 1440, .yres = 576, .pixclock = 37037,
557          .left_margin = 138, .right_margin = 24,
558          .upper_margin = 19, .lower_margin = 2,
559          .hsync_len = 126, .vsync_len = 3,
560          .sync = 0,
561          .vmode = FB_VMODE_INTERLACED},
562         /* 23: 720(1440)x288p @ 50Hz */
563         {.refresh = 49, .xres = 1440, .yres = 288, .pixclock = 37037,
564          .left_margin = 138, .right_margin = 24,
565          .upper_margin = 19, .lower_margin = 4,
566          .hsync_len = 126, .vsync_len = 3,
567          .sync = 0,
568          .vmode = FB_VMODE_NONINTERLACED},
569         /* 24: 720(1440)x288p @ 50Hz */
570         {.refresh = 49, .xres = 1440, .yres = 288, .pixclock = 37037,
571          .left_margin = 138, .right_margin = 24,
572          .upper_margin = 19, .lower_margin = 4,
573          .hsync_len = 126, .vsync_len = 3,
574          .sync = 0,
575          .vmode = FB_VMODE_NONINTERLACED},
576         /* 25: 2880x576i @ 50Hz */
577         {.refresh = 50, .xres = 2880, .yres = 576, .pixclock = 18518,
578          .left_margin = 276, .right_margin = 48,
579          .upper_margin = 19, .lower_margin = 2,
580          .hsync_len = 252, .vsync_len = 3,
581          .sync = 0,
582          .vmode = FB_VMODE_INTERLACED},
583         /* 26: 2880x576i @ 50Hz */
584         {.refresh = 50, .xres = 2880, .yres = 576, .pixclock = 18518,
585          .left_margin = 276, .right_margin = 48,
586          .upper_margin = 19, .lower_margin = 2,
587          .hsync_len = 252, .vsync_len = 3,
588          .sync = 0,
589          .vmode = FB_VMODE_INTERLACED},
590         /* 27: 2880x288p @ 50Hz */
591         {.refresh = 49, .xres = 2880, .yres = 288, .pixclock = 18518,
592          .left_margin = 276, .right_margin = 48,
593          .upper_margin = 19, .lower_margin = 4,
594          .hsync_len = 252, .vsync_len = 3,
595          .sync = 0,
596          .vmode = FB_VMODE_NONINTERLACED},
597         /* 28: 2880x288p @ 50Hz */
598         {.refresh = 49, .xres = 2880, .yres = 288, .pixclock = 18518,
599          .left_margin = 276, .right_margin = 48,
600          .upper_margin = 19, .lower_margin = 4,
601          .hsync_len = 252, .vsync_len = 3,
602          .sync = 0,
603          .vmode = FB_VMODE_NONINTERLACED},
604         /* 29: 1440x576p @ 50Hz */
605         {.refresh = 50, .xres = 1440, .yres = 576, .pixclock = 18518,
606          .left_margin = 136, .right_margin = 24,
607          .upper_margin = 39, .lower_margin = 5,
608          .hsync_len = 128, .vsync_len = 5,
609          .sync = 0,
610          .vmode = FB_VMODE_NONINTERLACED},
611         /* 30: 1440x576p @ 50Hz */
612         {.refresh = 50, .xres = 1440, .yres = 576, .pixclock = 18518,
613          .left_margin = 136, .right_margin = 24,
614          .upper_margin = 39, .lower_margin = 5,
615          .hsync_len = 128, .vsync_len = 5,
616          .sync = 0,
617          .vmode = FB_VMODE_NONINTERLACED},
618         /* 31: 1920x1080p @ 50Hz */
619         {.refresh = 50, .xres = 1920, .yres = 1080, .pixclock = 6734,
620          .left_margin = 148, .right_margin = 528,
621          .upper_margin = 36, .lower_margin = 4,
622          .hsync_len = 44, .vsync_len = 5,
623          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
624          .vmode = FB_VMODE_NONINTERLACED},
625         /* 32: 1920x1080p @ 23.97Hz/24Hz */
626         {.refresh = 24, .xres = 1920, .yres = 1080, .pixclock = 13468,
627          .left_margin = 148, .right_margin = 638,
628          .upper_margin = 36, .lower_margin = 4,
629          .hsync_len = 44, .vsync_len = 5,
630          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
631          .vmode = FB_VMODE_NONINTERLACED},
632         /* 33: 1920x1080p @ 25Hz */
633         {.refresh = 25, .xres = 1920, .yres = 1080, .pixclock = 13468,
634          .left_margin = 148, .right_margin = 528,
635          .upper_margin = 36, .lower_margin = 4,
636          .hsync_len = 44, .vsync_len = 5,
637          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
638          .vmode = FB_VMODE_NONINTERLACED},
639         /* 34: 1920x1080p @ 29.97Hz/30Hz */
640         {.refresh = 30, .xres = 1920, .yres = 1080, .pixclock = 13468,
641          .left_margin = 148, .right_margin = 88,
642          .upper_margin = 36, .lower_margin = 4,
643          .hsync_len = 44, .vsync_len = 5,
644          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
645          .vmode = FB_VMODE_NONINTERLACED},
646         /* 35: 2880x480p @ 59.94Hz/60Hz */
647         {.refresh = 59, .xres = 2880, .yres = 480, .pixclock = 9259,
648          .left_margin = 240, .right_margin = 64,
649          .upper_margin = 30, .lower_margin = 9,
650          .hsync_len = 248, .vsync_len = 6,
651          .sync = 0,
652          .vmode = FB_VMODE_NONINTERLACED},
653         /* 36: 2880x480p @ 59.94Hz/60Hz */
654         {.refresh = 59, .xres = 2880, .yres = 480, .pixclock = 9259,
655          .left_margin = 240, .right_margin = 64,
656          .upper_margin = 30, .lower_margin = 9,
657          .hsync_len = 248, .vsync_len = 6,
658          .sync = 0,
659          .vmode = FB_VMODE_NONINTERLACED},
660         /* 37: 2880x576p @ 50Hz */
661         {.refresh = 50, .xres = 2880, .yres = 576, .pixclock = 9259,
662          .left_margin = 272, .right_margin = 48,
663          .upper_margin = 39, .lower_margin = 5,
664          .hsync_len = 256, .vsync_len = 5,
665          .sync = 0,
666          .vmode = FB_VMODE_NONINTERLACED},
667         /* 38: 2880x576p @ 50Hz */
668         {.refresh = 50, .xres = 2880, .yres = 576, .pixclock = 9259,
669          .left_margin = 272, .right_margin = 48,
670          .upper_margin = 39, .lower_margin = 5,
671          .hsync_len = 256, .vsync_len = 5,
672          .sync = 0,
673          .vmode = FB_VMODE_NONINTERLACED},
674         /* 39: 1920x1080i @ 50Hz */
675         {.refresh = 50, .xres = 1920, .yres = 1080, .pixclock = 13888,
676          .left_margin = 184, .right_margin = 32,
677          .upper_margin = 57, .lower_margin = 2,
678          .hsync_len = 168, .vsync_len = 5,
679          .sync = FB_SYNC_HOR_HIGH_ACT,
680          .vmode = FB_VMODE_INTERLACED},
681         /* 40: 1920x1080i @ 100Hz */
682         {.refresh = 100, .xres = 1920, .yres = 1080, .pixclock = 6734,
683          .left_margin = 148, .right_margin = 528,
684          .upper_margin = 15, .lower_margin = 2,
685          .hsync_len = 44, .vsync_len = 5,
686          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
687          .vmode = FB_VMODE_INTERLACED},
688         /* 41: 1280x720p @ 100Hz */
689         {.refresh = 100, .xres = 1280, .yres = 720, .pixclock = 6734,
690          .left_margin = 220, .right_margin = 440,
691          .upper_margin = 20, .lower_margin = 5,
692          .hsync_len = 40, .vsync_len = 5,
693          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
694          .vmode = FB_VMODE_NONINTERLACED},
695         /* 42: 720x576p @ 100Hz */
696         {.refresh = 100, .xres = 720, .yres = 576, .pixclock = 18518,
697          .left_margin = 68, .right_margin = 12,
698          .upper_margin = 39, .lower_margin = 5,
699          .hsync_len = 64, .vsync_len = 5,
700          .sync = 0,
701          .vmode = FB_VMODE_NONINTERLACED},
702         /* 43: 720x576p @ 100Hz */
703         {.refresh = 100, .xres = 720, .yres = 576, .pixclock = 18518,
704          .left_margin = 68, .right_margin = 12,
705          .upper_margin = 39, .lower_margin = 5,
706          .hsync_len = 64, .vsync_len = 5,
707          .sync = 0,
708          .vmode = FB_VMODE_NONINTERLACED},
709         /* 44: 720(1440)x576i @ 100Hz */
710         {.refresh = 100, .xres = 1440, .yres = 576, .pixclock = 18518,
711          .left_margin = 138, .right_margin = 24,
712          .upper_margin = 19, .lower_margin = 2,
713          .hsync_len = 126, .vsync_len = 3,
714          .sync = 0,
715          .vmode = FB_VMODE_INTERLACED},
716         /* 45: 720(1440)x576i @ 100Hz */
717         {.refresh = 100, .xres = 1440, .yres = 576, .pixclock = 18518,
718          .left_margin = 138, .right_margin = 24,
719          .upper_margin = 19, .lower_margin = 2,
720          .hsync_len = 126, .vsync_len = 3,
721          .sync = 0,
722          .vmode = FB_VMODE_INTERLACED},
723         /* 46: 1920x1080i @ 119.88/120Hz */
724         {.refresh = 120, .xres = 1920, .yres = 1080, .pixclock = 6734,
725          .left_margin = 148, .right_margin = 88,
726          .upper_margin = 15, .lower_margin = 2,
727          .hsync_len = 44, .vsync_len = 5,
728          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
729          .vmode = FB_VMODE_INTERLACED},
730         /* 47: 1280x720p @ 119.88/120Hz */
731         {.refresh = 120, .xres = 1280, .yres = 720, .pixclock = 6734,
732          .left_margin = 220, .right_margin = 110,
733          .upper_margin = 20, .lower_margin = 5,
734          .hsync_len = 40, .vsync_len = 5,
735          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
736          .vmode = FB_VMODE_NONINTERLACED},
737         /* 48: 720x480p @ 119.88/120Hz */
738         {.refresh = 119, .xres = 720, .yres = 480, .pixclock = 18518,
739          .left_margin = 60, .right_margin = 16,
740          .upper_margin = 30, .lower_margin = 9,
741          .hsync_len = 62, .vsync_len = 6,
742          .sync = 0,
743          .vmode = FB_VMODE_NONINTERLACED},
744         /* 49: 720x480p @ 119.88/120Hz */
745         {.refresh = 119, .xres = 720, .yres = 480, .pixclock = 18518,
746          .left_margin = 60, .right_margin = 16,
747          .upper_margin = 30, .lower_margin = 9,
748          .hsync_len = 62, .vsync_len = 6,
749          .sync = 0,
750          .vmode = FB_VMODE_NONINTERLACED},
751         /* 50: 720(1440)x480i @ 119.88/120Hz */
752         {.refresh = 119, .xres = 1440, .yres = 480, .pixclock = 18518,
753          .left_margin = 114, .right_margin = 38,
754          .upper_margin = 15, .lower_margin = 4,
755          .hsync_len = 124, .vsync_len = 3,
756          .sync = 0,
757          .vmode = FB_VMODE_INTERLACED},
758         /* 51: 720(1440)x480i @ 119.88/120Hz */
759         {.refresh = 119, .xres = 1440, .yres = 480, .pixclock = 18518,
760          .left_margin = 114, .right_margin = 38,
761          .upper_margin = 15, .lower_margin = 4,
762          .hsync_len = 124, .vsync_len = 3,
763          .sync = 0,
764          .vmode = FB_VMODE_INTERLACED},
765         /* 52: 720x576p @ 200Hz */
766         {.refresh = 200, .xres = 720, .yres = 576, .pixclock = 9259,
767          .left_margin = 68, .right_margin = 12,
768          .upper_margin = 39, .lower_margin = 5,
769          .hsync_len = 64, .vsync_len = 5,
770          .sync = 0,
771          .vmode = FB_VMODE_NONINTERLACED},
772         /* 53: 720x576p @ 200Hz */
773         {.refresh = 200, .xres = 720, .yres = 576, .pixclock = 9259,
774          .left_margin = 68, .right_margin = 12,
775          .upper_margin = 39, .lower_margin = 5,
776          .hsync_len = 64, .vsync_len = 5,
777          .sync = 0,
778          .vmode = FB_VMODE_NONINTERLACED},
779         /* 54: 720(1440)x576i @ 200Hz */
780         {.refresh = 200, .xres = 1440, .yres = 576, .pixclock = 9259,
781          .left_margin = 138, .right_margin = 24,
782          .upper_margin = 19, .lower_margin = 2,
783          .hsync_len = 126, .vsync_len = 3,
784          .sync = 0,
785          .vmode = FB_VMODE_INTERLACED},
786         /* 55: 720(1440)x576i @ 200Hz */
787         {.refresh = 200, .xres = 1440, .yres = 576, .pixclock = 9259,
788          .left_margin = 138, .right_margin = 24,
789          .upper_margin = 19, .lower_margin = 2,
790          .hsync_len = 126, .vsync_len = 3,
791          .sync = 0,
792          .vmode = FB_VMODE_INTERLACED},
793         /* 56: 720x480p @ 239.76/240Hz */
794         {.refresh = 239, .xres = 720, .yres = 480, .pixclock = 9259,
795          .left_margin = 60, .right_margin = 16,
796          .upper_margin = 30, .lower_margin = 9,
797          .hsync_len = 62, .vsync_len = 6,
798          .sync = 0,
799          .vmode = FB_VMODE_NONINTERLACED},
800         /* 57: 720x480p @ 239.76/240Hz */
801         {.refresh = 239, .xres = 720, .yres = 480, .pixclock = 9259,
802          .left_margin = 60, .right_margin = 16,
803          .upper_margin = 30, .lower_margin = 9,
804          .hsync_len = 62, .vsync_len = 6,
805          .sync = 0,
806          .vmode = FB_VMODE_NONINTERLACED},
807         /* 58: 720(1440)x480i @ 239.76/240Hz */
808         {.refresh = 239, .xres = 1440, .yres = 480, .pixclock = 9259,
809          .left_margin = 114, .right_margin = 38,
810          .upper_margin = 15, .lower_margin = 4,
811          .hsync_len = 124, .vsync_len = 3,
812          .sync = 0,
813          .vmode = FB_VMODE_INTERLACED},
814         /* 59: 720(1440)x480i @ 239.76/240Hz */
815         {.refresh = 239, .xres = 1440, .yres = 480, .pixclock = 9259,
816          .left_margin = 114, .right_margin = 38,
817          .upper_margin = 15, .lower_margin = 4,
818          .hsync_len = 124, .vsync_len = 3,
819          .sync = 0,
820          .vmode = FB_VMODE_INTERLACED},
821         /* 60: 1280x720p @ 23.97Hz/24Hz */
822         {.refresh = 24, .xres = 1280, .yres = 720, .pixclock = 16835,
823          .left_margin = 220, .right_margin = 1760,
824          .upper_margin = 20, .lower_margin = 5,
825          .hsync_len = 40, .vsync_len = 5,
826          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
827          .vmode = FB_VMODE_NONINTERLACED},
828         /* 61: 1280x720p @ 25Hz */
829         {.refresh = 25, .xres = 1280, .yres = 720, .pixclock = 13468,
830          .left_margin = 220, .right_margin = 2420,
831          .upper_margin = 20, .lower_margin = 5,
832          .hsync_len = 40, .vsync_len = 5,
833          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
834          .vmode = FB_VMODE_NONINTERLACED},
835         /* 62: 1280x720p @ 29.97Hz/30Hz */
836         {.refresh = 30, .xres = 1280, .yres = 720, .pixclock = 13468,
837          .left_margin = 220, .right_margin = 1760,
838          .upper_margin = 20, .lower_margin = 5,
839          .hsync_len = 40, .vsync_len = 5,
840          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
841          .vmode = FB_VMODE_NONINTERLACED},
842         /* 63: 1920x1080p @ 119.88/120Hz */
843         {.refresh = 120, .xres = 1920, .yres = 1080, .pixclock = 3367,
844          .left_margin = 148, .right_margin = 88,
845          .upper_margin = 36, .lower_margin = 4,
846          .hsync_len = 44, .vsync_len = 5,
847          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
848          .vmode = FB_VMODE_NONINTERLACED},
849         /* 64: 1920x1080p @ 100Hz */
850         {.refresh = 100, .xres = 1920, .yres = 1080, .pixclock = 3367,
851          .left_margin = 148, .right_margin = 528,
852          .upper_margin = 36, .lower_margin = 4,
853          .hsync_len = 44, .vsync_len = 5,
854          .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
855          .vmode = FB_VMODE_NONINTERLACED},
856 };
857 EXPORT_SYMBOL(cea_modes);
858 #endif /* CONFIG_FB_MODE_HELPERS */
859
860 /**
861  *      fb_try_mode - test a video mode
862  *      @var: frame buffer user defined part of display
863  *      @info: frame buffer info structure
864  *      @mode: frame buffer video mode structure
865  *      @bpp: color depth in bits per pixel
866  *
867  *      Tries a video mode to test it's validity for device @info.
868  *
869  *      Returns 1 on success.
870  *
871  */
872
873 static int fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
874                        const struct fb_videomode *mode, unsigned int bpp)
875 {
876     int err = 0;
877
878     DPRINTK("Trying mode %s %dx%d-%d@%d\n", mode->name ? mode->name : "noname",
879             mode->xres, mode->yres, bpp, mode->refresh);
880     var->xres = mode->xres;
881     var->yres = mode->yres;
882     var->xres_virtual = mode->xres;
883     var->yres_virtual = mode->yres;
884     var->xoffset = 0;
885     var->yoffset = 0;
886     var->bits_per_pixel = bpp;
887     var->activate |= FB_ACTIVATE_TEST;
888     var->pixclock = mode->pixclock;
889     var->left_margin = mode->left_margin;
890     var->right_margin = mode->right_margin;
891     var->upper_margin = mode->upper_margin;
892     var->lower_margin = mode->lower_margin;
893     var->hsync_len = mode->hsync_len;
894     var->vsync_len = mode->vsync_len;
895     var->sync = mode->sync;
896     var->vmode = mode->vmode;
897     if (info->fbops->fb_check_var)
898         err = info->fbops->fb_check_var(var, info);
899     var->activate &= ~FB_ACTIVATE_TEST;
900     return err;
901 }
902
903 /**
904  *      fb_find_mode - finds a valid video mode
905  *      @var: frame buffer user defined part of display
906  *      @info: frame buffer info structure
907  *      @mode_option: string video mode to find
908  *      @db: video mode database
909  *      @dbsize: size of @db
910  *      @default_mode: default video mode to fall back to
911  *      @default_bpp: default color depth in bits per pixel
912  *
913  *      Finds a suitable video mode, starting with the specified mode
914  *      in @mode_option with fallback to @default_mode.  If
915  *      @default_mode fails, all modes in the video mode database will
916  *      be tried.
917  *
918  *      Valid mode specifiers for @mode_option:
919  *
920  *      <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m] or
921  *      <name>[-<bpp>][@<refresh>]
922  *
923  *      with <xres>, <yres>, <bpp> and <refresh> decimal numbers and
924  *      <name> a string.
925  *
926  *      If 'M' is present after yres (and before refresh/bpp if present),
927  *      the function will compute the timings using VESA(tm) Coordinated
928  *      Video Timings (CVT).  If 'R' is present after 'M', will compute with
929  *      reduced blanking (for flatpanels).  If 'i' is present, compute
930  *      interlaced mode.  If 'm' is present, add margins equal to 1.8%
931  *      of xres rounded down to 8 pixels, and 1.8% of yres. The char
932  *      'i' and 'm' must be after 'M' and 'R'. Example:
933  *
934  *      1024x768MR-8@60m - Reduced blank with margins at 60Hz.
935  *
936  *      NOTE: The passed struct @var is _not_ cleared!  This allows you
937  *      to supply values for e.g. the grayscale and accel_flags fields.
938  *
939  *      Returns zero for failure, 1 if using specified @mode_option,
940  *      2 if using specified @mode_option with an ignored refresh rate,
941  *      3 if default mode is used, 4 if fall back to any valid mode.
942  *
943  */
944
945 int fb_find_mode(struct fb_var_screeninfo *var,
946                  struct fb_info *info, const char *mode_option,
947                  const struct fb_videomode *db, unsigned int dbsize,
948                  const struct fb_videomode *default_mode,
949                  unsigned int default_bpp)
950 {
951     int i;
952
953     /* Set up defaults */
954     if (!db) {
955         db = modedb;
956         dbsize = ARRAY_SIZE(modedb);
957     }
958
959     if (!default_mode)
960         default_mode = &db[0];
961
962     if (!default_bpp)
963         default_bpp = 8;
964
965     /* Did the user specify a video mode? */
966     if (!mode_option)
967         mode_option = fb_mode_option;
968     if (mode_option) {
969         const char *name = mode_option;
970         unsigned int namelen = strlen(name);
971         int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
972         unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
973         int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0;
974         u32 best, diff, tdiff;
975
976         for (i = namelen-1; i >= 0; i--) {
977             switch (name[i]) {
978                 case '@':
979                     namelen = i;
980                     if (!refresh_specified && !bpp_specified &&
981                         !yres_specified) {
982                         refresh = simple_strtol(&name[i+1], NULL, 10);
983                         refresh_specified = 1;
984                         if (cvt || rb)
985                             cvt = 0;
986                     } else
987                         goto done;
988                     break;
989                 case '-':
990                     namelen = i;
991                     if (!bpp_specified && !yres_specified) {
992                         bpp = simple_strtol(&name[i+1], NULL, 10);
993                         bpp_specified = 1;
994                         if (cvt || rb)
995                             cvt = 0;
996                     } else
997                         goto done;
998                     break;
999                 case 'x':
1000                     if (!yres_specified) {
1001                         yres = simple_strtol(&name[i+1], NULL, 10);
1002                         yres_specified = 1;
1003                     } else
1004                         goto done;
1005                     break;
1006                 case '0' ... '9':
1007                     break;
1008                 case 'M':
1009                     if (!yres_specified)
1010                         cvt = 1;
1011                     break;
1012                 case 'R':
1013                     if (!cvt)
1014                         rb = 1;
1015                     break;
1016                 case 'm':
1017                     if (!cvt)
1018                         margins = 1;
1019                     break;
1020                 case 'i':
1021                     if (!cvt)
1022                         interlace = 1;
1023                     break;
1024                 default:
1025                     goto done;
1026             }
1027         }
1028         if (i < 0 && yres_specified) {
1029             xres = simple_strtol(name, NULL, 10);
1030             res_specified = 1;
1031         }
1032 done:
1033         if (cvt) {
1034             struct fb_videomode cvt_mode;
1035             int ret;
1036
1037             DPRINTK("CVT mode %dx%d@%dHz%s%s%s\n", xres, yres,
1038                     (refresh) ? refresh : 60, (rb) ? " reduced blanking" :
1039                     "", (margins) ? " with margins" : "", (interlace) ?
1040                     " interlaced" : "");
1041
1042             memset(&cvt_mode, 0, sizeof(cvt_mode));
1043             cvt_mode.xres = xres;
1044             cvt_mode.yres = yres;
1045             cvt_mode.refresh = (refresh) ? refresh : 60;
1046
1047             if (interlace)
1048                 cvt_mode.vmode |= FB_VMODE_INTERLACED;
1049             else
1050                 cvt_mode.vmode &= ~FB_VMODE_INTERLACED;
1051
1052             ret = fb_find_mode_cvt(&cvt_mode, margins, rb);
1053
1054             if (!ret && !fb_try_mode(var, info, &cvt_mode, bpp)) {
1055                 DPRINTK("modedb CVT: CVT mode ok\n");
1056                 return 1;
1057             }
1058
1059             DPRINTK("CVT mode invalid, getting mode from database\n");
1060         }
1061
1062         DPRINTK("Trying specified video mode%s %ix%i\n",
1063             refresh_specified ? "" : " (ignoring refresh rate)", xres, yres);
1064
1065         if (!refresh_specified) {
1066                 /*
1067                  * If the caller has provided a custom mode database and a
1068                  * valid monspecs structure, we look for the mode with the
1069                  * highest refresh rate.  Otherwise we play it safe it and
1070                  * try to find a mode with a refresh rate closest to the
1071                  * standard 60 Hz.
1072                  */
1073                 if (db != modedb &&
1074                     info->monspecs.vfmin && info->monspecs.vfmax &&
1075                     info->monspecs.hfmin && info->monspecs.hfmax &&
1076                     info->monspecs.dclkmax) {
1077                         refresh = 1000;
1078                 } else {
1079                         refresh = 60;
1080                 }
1081         }
1082
1083         diff = -1;
1084         best = -1;
1085         for (i = 0; i < dbsize; i++) {
1086                 if ((name_matches(db[i], name, namelen) ||
1087                     (res_specified && res_matches(db[i], xres, yres))) &&
1088                     !fb_try_mode(var, info, &db[i], bpp)) {
1089                         if (refresh_specified && db[i].refresh == refresh) {
1090                                 return 1;
1091                         } else {
1092                                 if (abs(db[i].refresh - refresh) < diff) {
1093                                         diff = abs(db[i].refresh - refresh);
1094                                         best = i;
1095                                 }
1096                         }
1097                 }
1098         }
1099         if (best != -1) {
1100                 fb_try_mode(var, info, &db[best], bpp);
1101                 return (refresh_specified) ? 2 : 1;
1102         }
1103
1104         diff = 2 * (xres + yres);
1105         best = -1;
1106         DPRINTK("Trying best-fit modes\n");
1107         for (i = 0; i < dbsize; i++) {
1108                 DPRINTK("Trying %ix%i\n", db[i].xres, db[i].yres);
1109                 if (!fb_try_mode(var, info, &db[i], bpp)) {
1110                         tdiff = abs(db[i].xres - xres) +
1111                                 abs(db[i].yres - yres);
1112
1113                         /*
1114                          * Penalize modes with resolutions smaller
1115                          * than requested.
1116                          */
1117                         if (xres > db[i].xres || yres > db[i].yres)
1118                                 tdiff += xres + yres;
1119
1120                         if (diff > tdiff) {
1121                                 diff = tdiff;
1122                                 best = i;
1123                         }
1124                 }
1125         }
1126         if (best != -1) {
1127             fb_try_mode(var, info, &db[best], bpp);
1128             return 5;
1129         }
1130     }
1131
1132     DPRINTK("Trying default video mode\n");
1133     if (!fb_try_mode(var, info, default_mode, default_bpp))
1134         return 3;
1135
1136     DPRINTK("Trying all modes\n");
1137     for (i = 0; i < dbsize; i++)
1138         if (!fb_try_mode(var, info, &db[i], default_bpp))
1139             return 4;
1140
1141     DPRINTK("No valid mode found\n");
1142     return 0;
1143 }
1144
1145 /**
1146  * fb_var_to_videomode - convert fb_var_screeninfo to fb_videomode
1147  * @mode: pointer to struct fb_videomode
1148  * @var: pointer to struct fb_var_screeninfo
1149  */
1150 void fb_var_to_videomode(struct fb_videomode *mode,
1151                          const struct fb_var_screeninfo *var)
1152 {
1153         u32 pixclock, hfreq, htotal, vtotal;
1154
1155         mode->name = NULL;
1156         mode->xres = var->xres;
1157         mode->yres = var->yres;
1158         mode->pixclock = var->pixclock;
1159         mode->hsync_len = var->hsync_len;
1160         mode->vsync_len = var->vsync_len;
1161         mode->left_margin = var->left_margin;
1162         mode->right_margin = var->right_margin;
1163         mode->upper_margin = var->upper_margin;
1164         mode->lower_margin = var->lower_margin;
1165         mode->sync = var->sync;
1166         mode->vmode = var->vmode & FB_VMODE_MASK;
1167         mode->flag = FB_MODE_IS_FROM_VAR;
1168         mode->refresh = 0;
1169
1170         if (!var->pixclock)
1171                 return;
1172
1173         pixclock = PICOS2KHZ(var->pixclock) * 1000;
1174
1175         htotal = var->xres + var->right_margin + var->hsync_len +
1176                 var->left_margin;
1177         vtotal = var->yres + var->lower_margin + var->vsync_len +
1178                 var->upper_margin;
1179
1180         if (var->vmode & FB_VMODE_INTERLACED)
1181                 vtotal /= 2;
1182         if (var->vmode & FB_VMODE_DOUBLE)
1183                 vtotal *= 2;
1184
1185         hfreq = pixclock/htotal;
1186         mode->refresh = hfreq/vtotal;
1187 }
1188
1189 /**
1190  * fb_videomode_to_var - convert fb_videomode to fb_var_screeninfo
1191  * @var: pointer to struct fb_var_screeninfo
1192  * @mode: pointer to struct fb_videomode
1193  */
1194 void fb_videomode_to_var(struct fb_var_screeninfo *var,
1195                          const struct fb_videomode *mode)
1196 {
1197         var->xres = mode->xres;
1198         var->yres = mode->yres;
1199         var->xres_virtual = mode->xres;
1200         var->yres_virtual = mode->yres;
1201         var->xoffset = 0;
1202         var->yoffset = 0;
1203         var->pixclock = mode->pixclock;
1204         var->left_margin = mode->left_margin;
1205         var->right_margin = mode->right_margin;
1206         var->upper_margin = mode->upper_margin;
1207         var->lower_margin = mode->lower_margin;
1208         var->hsync_len = mode->hsync_len;
1209         var->vsync_len = mode->vsync_len;
1210         var->sync = mode->sync;
1211         var->vmode = mode->vmode & FB_VMODE_MASK;
1212 }
1213
1214 /**
1215  * fb_mode_is_equal - compare 2 videomodes
1216  * @mode1: first videomode
1217  * @mode2: second videomode
1218  *
1219  * RETURNS:
1220  * 1 if equal, 0 if not
1221  */
1222 int fb_mode_is_equal(const struct fb_videomode *mode1,
1223                      const struct fb_videomode *mode2)
1224 {
1225         return (mode1->xres         == mode2->xres &&
1226                 mode1->yres         == mode2->yres &&
1227                 mode1->pixclock     == mode2->pixclock &&
1228                 mode1->hsync_len    == mode2->hsync_len &&
1229                 mode1->vsync_len    == mode2->vsync_len &&
1230                 mode1->left_margin  == mode2->left_margin &&
1231                 mode1->right_margin == mode2->right_margin &&
1232                 mode1->upper_margin == mode2->upper_margin &&
1233                 mode1->lower_margin == mode2->lower_margin &&
1234                 mode1->sync         == mode2->sync &&
1235                 mode1->vmode        == mode2->vmode);
1236 }
1237
1238 /**
1239  * fb_find_best_mode - find best matching videomode
1240  * @var: pointer to struct fb_var_screeninfo
1241  * @head: pointer to struct list_head of modelist
1242  *
1243  * RETURNS:
1244  * struct fb_videomode, NULL if none found
1245  *
1246  * IMPORTANT:
1247  * This function assumes that all modelist entries in
1248  * info->modelist are valid.
1249  *
1250  * NOTES:
1251  * Finds best matching videomode which has an equal or greater dimension than
1252  * var->xres and var->yres.  If more than 1 videomode is found, will return
1253  * the videomode with the highest refresh rate
1254  */
1255 const struct fb_videomode *fb_find_best_mode(const struct fb_var_screeninfo *var,
1256                                              struct list_head *head)
1257 {
1258         struct list_head *pos;
1259         struct fb_modelist *modelist;
1260         struct fb_videomode *mode, *best = NULL;
1261         u32 diff = -1;
1262
1263         list_for_each(pos, head) {
1264                 u32 d;
1265
1266                 modelist = list_entry(pos, struct fb_modelist, list);
1267                 mode = &modelist->mode;
1268
1269                 if (mode->xres >= var->xres && mode->yres >= var->yres) {
1270                         d = (mode->xres - var->xres) +
1271                                 (mode->yres - var->yres);
1272                         if (diff > d) {
1273                                 diff = d;
1274                                 best = mode;
1275                         } else if (diff == d && best &&
1276                                    mode->refresh > best->refresh)
1277                                 best = mode;
1278                 }
1279         }
1280         return best;
1281 }
1282
1283 /**
1284  * fb_find_nearest_mode - find closest videomode
1285  *
1286  * @mode: pointer to struct fb_videomode
1287  * @head: pointer to modelist
1288  *
1289  * Finds best matching videomode, smaller or greater in dimension.
1290  * If more than 1 videomode is found, will return the videomode with
1291  * the closest refresh rate.
1292  */
1293 const struct fb_videomode *fb_find_nearest_mode(const struct fb_videomode *mode,
1294                                                 struct list_head *head)
1295 {
1296         struct list_head *pos;
1297         struct fb_modelist *modelist;
1298         struct fb_videomode *cmode, *best = NULL;
1299         u32 diff = -1, diff_refresh = -1;
1300
1301         list_for_each(pos, head) {
1302                 u32 d;
1303
1304                 modelist = list_entry(pos, struct fb_modelist, list);
1305                 cmode = &modelist->mode;
1306
1307                 d = abs(cmode->xres - mode->xres) +
1308                         abs(cmode->yres - mode->yres);
1309                 if (diff > d) {
1310                         diff = d;
1311                         best = cmode;
1312                 } else if (diff == d) {
1313                         d = abs(cmode->refresh - mode->refresh);
1314                         if (diff_refresh > d) {
1315                                 diff_refresh = d;
1316                                 best = cmode;
1317                         }
1318                 }
1319         }
1320
1321         return best;
1322 }
1323
1324 /**
1325  * fb_match_mode - find a videomode which exactly matches the timings in var
1326  * @var: pointer to struct fb_var_screeninfo
1327  * @head: pointer to struct list_head of modelist
1328  *
1329  * RETURNS:
1330  * struct fb_videomode, NULL if none found
1331  */
1332 const struct fb_videomode *fb_match_mode(const struct fb_var_screeninfo *var,
1333                                          struct list_head *head)
1334 {
1335         struct list_head *pos;
1336         struct fb_modelist *modelist;
1337         struct fb_videomode *m, mode;
1338
1339         fb_var_to_videomode(&mode, var);
1340         list_for_each(pos, head) {
1341                 modelist = list_entry(pos, struct fb_modelist, list);
1342                 m = &modelist->mode;
1343                 if (fb_mode_is_equal(m, &mode))
1344                         return m;
1345         }
1346         return NULL;
1347 }
1348
1349 /**
1350  * fb_add_videomode - adds videomode entry to modelist
1351  * @mode: videomode to add
1352  * @head: struct list_head of modelist
1353  *
1354  * NOTES:
1355  * Will only add unmatched mode entries
1356  */
1357 int fb_add_videomode(const struct fb_videomode *mode, struct list_head *head)
1358 {
1359         struct list_head *pos;
1360         struct fb_modelist *modelist;
1361         struct fb_videomode *m;
1362         int found = 0;
1363
1364         list_for_each(pos, head) {
1365                 modelist = list_entry(pos, struct fb_modelist, list);
1366                 m = &modelist->mode;
1367                 if (fb_mode_is_equal(m, mode)) {
1368                         found = 1;
1369                         break;
1370                 }
1371         }
1372         if (!found) {
1373                 modelist = kmalloc(sizeof(struct fb_modelist),
1374                                                   GFP_KERNEL);
1375
1376                 if (!modelist)
1377                         return -ENOMEM;
1378                 modelist->mode = *mode;
1379                 list_add_tail(&modelist->list, head);
1380         }
1381         return 0;
1382 }
1383
1384 /**
1385  * fb_delete_videomode - removed videomode entry from modelist
1386  * @mode: videomode to remove
1387  * @head: struct list_head of modelist
1388  *
1389  * NOTES:
1390  * Will remove all matching mode entries
1391  */
1392 void fb_delete_videomode(const struct fb_videomode *mode,
1393                          struct list_head *head)
1394 {
1395         struct list_head *pos, *n;
1396         struct fb_modelist *modelist;
1397         struct fb_videomode *m;
1398
1399         list_for_each_safe(pos, n, head) {
1400                 modelist = list_entry(pos, struct fb_modelist, list);
1401                 m = &modelist->mode;
1402                 if (fb_mode_is_equal(m, mode)) {
1403                         list_del(pos);
1404                         kfree(pos);
1405                 }
1406         }
1407 }
1408
1409 /**
1410  * fb_destroy_modelist - destroy modelist
1411  * @head: struct list_head of modelist
1412  */
1413 void fb_destroy_modelist(struct list_head *head)
1414 {
1415         struct list_head *pos, *n;
1416
1417         list_for_each_safe(pos, n, head) {
1418                 list_del(pos);
1419                 kfree(pos);
1420         }
1421 }
1422 EXPORT_SYMBOL_GPL(fb_destroy_modelist);
1423
1424 /**
1425  * fb_videomode_to_modelist - convert mode array to mode list
1426  * @modedb: array of struct fb_videomode
1427  * @num: number of entries in array
1428  * @head: struct list_head of modelist
1429  */
1430 void fb_videomode_to_modelist(const struct fb_videomode *modedb, int num,
1431                               struct list_head *head)
1432 {
1433         int i;
1434
1435         INIT_LIST_HEAD(head);
1436
1437         for (i = 0; i < num; i++) {
1438                 if (fb_add_videomode(&modedb[i], head))
1439                         return;
1440         }
1441 }
1442
1443 const struct fb_videomode *fb_find_best_display(const struct fb_monspecs *specs,
1444                                                 struct list_head *head)
1445 {
1446         struct list_head *pos;
1447         struct fb_modelist *modelist;
1448         const struct fb_videomode *m, *m1 = NULL, *md = NULL, *best = NULL;
1449         int first = 0;
1450
1451         if (!head->prev || !head->next || list_empty(head))
1452                 goto finished;
1453
1454         /* get the first detailed mode and the very first mode */
1455         list_for_each(pos, head) {
1456                 modelist = list_entry(pos, struct fb_modelist, list);
1457                 m = &modelist->mode;
1458
1459                 if (!first) {
1460                         m1 = m;
1461                         first = 1;
1462                 }
1463
1464                 if (m->flag & FB_MODE_IS_FIRST) {
1465                         md = m;
1466                         break;
1467                 }
1468         }
1469
1470         /* first detailed timing is preferred */
1471         if (specs->misc & FB_MISC_1ST_DETAIL) {
1472                 best = md;
1473                 goto finished;
1474         }
1475
1476         /* find best mode based on display width and height */
1477         if (specs->max_x && specs->max_y) {
1478                 struct fb_var_screeninfo var;
1479
1480                 memset(&var, 0, sizeof(struct fb_var_screeninfo));
1481                 var.xres = (specs->max_x * 7200)/254;
1482                 var.yres = (specs->max_y * 7200)/254;
1483                 m = fb_find_best_mode(&var, head);
1484                 if (m) {
1485                         best = m;
1486                         goto finished;
1487                 }
1488         }
1489
1490         /* use first detailed mode */
1491         if (md) {
1492                 best = md;
1493                 goto finished;
1494         }
1495
1496         /* last resort, use the very first mode */
1497         best = m1;
1498 finished:
1499         return best;
1500 }
1501 EXPORT_SYMBOL(fb_find_best_display);
1502
1503 EXPORT_SYMBOL(fb_videomode_to_var);
1504 EXPORT_SYMBOL(fb_var_to_videomode);
1505 EXPORT_SYMBOL(fb_mode_is_equal);
1506 EXPORT_SYMBOL(fb_add_videomode);
1507 EXPORT_SYMBOL(fb_match_mode);
1508 EXPORT_SYMBOL(fb_find_best_mode);
1509 EXPORT_SYMBOL(fb_find_nearest_mode);
1510 EXPORT_SYMBOL(fb_videomode_to_modelist);
1511 EXPORT_SYMBOL(fb_find_mode);