14 #include <linux/module.h>
15 #include <linux/slab.h>
17 #include <linux/kernel.h>
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))
27 #define DPRINTK(fmt, args...) printk("modedb %s: " fmt, __func__ , ## args)
29 #define DPRINTK(fmt, args...)
42 {
NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, 0,
46 {
NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, 0,
50 {
NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, 0,
54 {
NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8, 0,
58 {
NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
62 {
NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3, 0,
66 {
NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, 0,
70 {
NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
75 {
NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3, 0,
79 {
NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, 0,
82 {
NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
87 {
NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6, 0,
91 {
NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6, 0,
95 {
NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8, 0,
99 {
NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5, 0,
103 {
NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, 0,
107 {
NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, 0,
111 {
NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6, 0,
115 {
NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3, 0,
119 {
NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10, 0,
123 {
NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3, 0,
127 {
NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, 0,
131 {
NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
136 {
NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
141 {
NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6, 0,
145 {
NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12, 0,
149 {
NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8, 0,
153 {
NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
158 {
NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12, 0,
162 {
NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3, 0,
166 {
NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10, 0,
170 {
NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3, 0,
174 {
NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, 0,
178 {
NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19, 0,
182 {
NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
187 {
NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
192 {
NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
197 {
NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
202 {
NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15, 0,
206 {
NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
211 {
NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
216 {
NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3, 0,
220 {
NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3, 0,
224 {
NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1, 0,
228 {
NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1, 0,
232 {
NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2, 0,
236 {
NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1, 0,
240 {
NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2, 0,
244 {
NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3, 0,
248 {
NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1, 0,
252 {
NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2, 0,
256 {
NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2, 0,
260 {
NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, 0,
264 {
NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
269 {
NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
274 {
NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5, 0,
278 {
NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3, 0,
282 {
NULL, 50, 720, 576, 74074, 64, 16, 39, 5, 64, 5, 0,
286 {
NULL, 50, 800, 520, 58823, 144, 64, 72, 28, 80, 5, 0,
290 {
NULL, 60, 864, 480, 27777, 1, 1, 1, 1, 0, 0,
294 #ifdef CONFIG_FB_MODE_HELPERS
298 NULL, 60, 640, 480, 39722, 48, 16, 33, 10, 96, 2, 0,
303 NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
308 NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5,
314 NULL, 60, 1440, 480, 18554, 114, 38, 15, 4, 124, 3, 0,
319 NULL, 60, 1440, 240, 18554, 114, 38, 16, 4, 124, 3, 0,
324 NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
329 NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5,
335 NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5,
341 NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5,
347 NULL, 60, 2880, 480, 9250, 240, 64, 30, 9, 248, 6, 0,
354 {
NULL, 85, 640, 350, 31746, 96, 32, 60, 32, 64, 3,
357 {
NULL, 85, 640, 400, 31746, 96, 32, 41, 01, 64, 3,
360 {
NULL, 85, 721, 400, 28169, 108, 36, 42, 01, 72, 3,
363 {
NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
366 {
NULL, 72, 640, 480, 31746, 128, 24, 29, 9, 40, 2,
369 {
NULL, 75, 640, 480, 31746, 120, 16, 16, 01, 64, 3,
372 {
NULL, 85, 640, 480, 27777, 80, 56, 25, 01, 56, 3,
375 {
NULL, 56, 800, 600, 27777, 128, 24, 22, 01, 72, 2,
379 {
NULL, 60, 800, 600, 25000, 88, 40, 23, 01, 128, 4,
383 {
NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
387 {
NULL, 75, 800, 600, 20202, 160, 16, 21, 01, 80, 3,
391 {
NULL, 85, 800, 600, 17761, 152, 32, 27, 01, 64, 3,
395 {
NULL, 43, 1024, 768, 22271, 56, 8, 41, 0, 176, 8,
399 {
NULL, 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6,
402 {
NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
405 {
NULL, 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3,
409 {
NULL, 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3,
413 {
NULL, 75, 1152, 864, 9259, 256, 64, 32, 1, 128, 3,
417 {
NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3,
421 {
NULL, 85, 1280, 960, 6734, 224, 64, 47, 1, 160, 3,
425 {
NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
429 {
NULL, 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3,
433 {
NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
437 {
NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
441 {
NULL, 65, 1600, 1200, 5698, 304, 64, 46, 1, 192, 3,
445 {
NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
449 {
NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
453 {
NULL, 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3,
457 {
NULL, 60, 1792, 1344, 4882, 328, 128, 46, 1, 200, 3,
460 {
NULL, 75, 1792, 1344, 3831, 352, 96, 69, 1, 216, 3,
463 {
NULL, 60, 1856, 1392, 4580, 352, 96, 43, 1, 224, 3,
466 {
NULL, 75, 1856, 1392, 3472, 352, 128, 104, 1, 224, 3,
469 {
NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 200, 3,
472 {
NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
496 DPRINTK(
"Trying mode %s %dx%d-%d@%d\n",
516 if (info->
fbops->fb_check_var)
517 err = info->
fbops->fb_check_var(var, info);
565 struct fb_info *info,
const char *mode_option,
568 unsigned int default_bpp)
579 default_mode = &db[0];
588 const char *
name = mode_option;
590 int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
594 u32 best, diff, tdiff;
596 for (i = namelen-1; i >= 0; i--) {
600 if (!refresh_specified && !bpp_specified &&
604 refresh_specified = 1;
612 if (!bpp_specified && !yres_specified) {
622 if (!yres_specified) {
651 if (i < 0 && yres_specified) {
661 (refresh) ? refresh : 60,
662 (
rb) ?
" reduced blanking" :
"",
663 (margins) ?
" with margins" :
"",
666 memset(&cvt_mode, 0,
sizeof(cvt_mode));
678 if (!ret && !fb_try_mode(var, info, &cvt_mode, bpp)) {
679 DPRINTK(
"modedb CVT: CVT mode ok\n");
683 DPRINTK(
"CVT mode invalid, getting mode from database\n");
686 DPRINTK(
"Trying specified video mode%s %ix%i\n",
687 refresh_specified ?
"" :
" (ignoring refresh rate)",
690 if (!refresh_specified) {
710 for (i = 0; i < dbsize; i++) {
713 !fb_try_mode(var, info, &db[i], bpp)) {
714 if (refresh_specified && db[i].refresh == refresh)
717 if (
abs(db[i].refresh - refresh) < diff) {
718 diff =
abs(db[i].refresh - refresh);
724 fb_try_mode(var, info, &db[best], bpp);
725 return (refresh_specified) ? 2 : 1;
728 diff = 2 * (xres +
yres);
730 DPRINTK(
"Trying best-fit modes\n");
731 for (i = 0; i < dbsize; i++) {
733 if (!fb_try_mode(var, info, &db[i], bpp)) {
734 tdiff =
abs(db[i].xres - xres) +
735 abs(db[i].yres - yres);
741 if (xres > db[i].xres || yres > db[i].yres)
742 tdiff += xres +
yres;
751 fb_try_mode(var, info, &db[best], bpp);
756 DPRINTK(
"Trying default video mode\n");
757 if (!fb_try_mode(var, info, default_mode, default_bpp))
761 for (i = 0; i < dbsize; i++)
762 if (!fb_try_mode(var, info, &db[i], default_bpp))
765 DPRINTK(
"No valid mode found\n");
809 hfreq = pixclock/htotal;
849 return (mode1->
xres == mode2->
xres &&
891 mode = &modelist->
mode;
899 }
else if (diff == d && best &&
923 u32 diff = -1, diff_refresh = -1;
929 cmode = &modelist->
mode;
937 }
else if (diff == d) {
939 if (diff_refresh > d) {
1004 list_add(&modelist->
list, head);
1026 m = &modelist->
mode;
1060 INIT_LIST_HEAD(head);
1062 for (i = 0; i < num; i++) {
1076 if (!head->
prev || !head->
next || list_empty(head))
1082 m = &modelist->
mode;