/* * $XFree86: xc/programs/Xserver/hw/kdrive/kmode.c,v 1.5 2000/05/24 23:57:56 keithp Exp $ * * Copyright 1999 SuSE, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of SuSE not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. SuSE makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Keith Packard, SuSE, Inc. */ #include "kdrive.h" const KdMonitorTiming kdMonitorTimings[] = { /* H V Hz KHz */ /* FP BP BLANK POLARITY */ /* Other VESA modes */ { 640, 350, 85, 31500, /* VESA */ 32, 96, 192, KdSyncPositive, /* 37.861 */ 32, 60, 95, KdSyncNegative, /* 85.080 */ }, { 640, 400, 85, 31500, /* VESA */ 32, 96, 192, KdSyncNegative, /* 37.861 */ 1, 41, 45, KdSyncPositive, /* 85.080 */ }, { 720, 400, 85, 35500, /* VESA */ 36, 108, 216, KdSyncNegative, /* 37.927 */ 1, 42, 46, KdSyncPositive, /* 85.039 */ }, /* Modeline "720x576" 29.000 720 736 800 880 576 577 580 625 */ { 720, 576, 52, 32954, /* PAL Video */ 16, 80, 160, KdSyncPositive, /* 32.954 */ 1, 45, 49, KdSyncPositive, /* 52.727 */ }, /* 640x480 modes */ { 640, 480, 85, 36000, /* VESA */ 56, 80, 192, KdSyncNegative, /* 43.269 */ 1, 25, 29, KdSyncNegative, /* 85.008 */ }, { 640, 480, 75, 31500, /* VESA */ 16, 120, 200, KdSyncNegative, /* 37.500 */ 1, 16, 20, KdSyncNegative, /* 75.000 */ }, { 640, 480, 72, 31500, /* VESA */ 16, 120, 176, KdSyncNegative, /* 37.861 */ 1, 20, 24, KdSyncNegative, /* 72.809 */ }, { 640, 480, 60, 25175, /* VESA */ 16, 48, 160, KdSyncNegative, /* 31.469 */ 10, 33, 45, KdSyncNegative, /* 59.940 */ }, /* 800x600 modes */ { 800, 600, 85, 56250, /* VESA */ 32, 152, 248, KdSyncPositive, /* 53.674 */ 1, 27, 31, KdSyncPositive, /* 85.061 */ }, { 800, 600, 75, 49500, /* VESA */ 16, 160, 256, KdSyncPositive, /* 46.875 */ 1, 21, 25, KdSyncPositive, /* 75.000 */ }, /* DEFAULT */ #define MONITOR_TIMING_DEFAULT 9 { 800, 600, 72, 50000, /* VESA */ 56, 64, 240, KdSyncPositive, /* 48.077 */ 37, 23, 66, KdSyncPositive, /* 72.188 */ }, { 800, 600, 60, 40000, /* VESA */ 40, 88, 256, KdSyncPositive, /* 37.879 */ 1, 23, 28, KdSyncPositive, /* 60.317 */ }, { 800, 600, 56, 36000, /* VESA */ 24, 128, 224, KdSyncPositive, /* 35.156 */ 1, 22, 25, KdSyncPositive, /* 56.250 */ }, /* 1024x768 modes */ { 1024, 768, 85, 94500, /* VESA */ 48, 208, 352, KdSyncPositive, /* 68.677 */ 1, 36, 40, KdSyncPositive, /* 84.997 */ }, { 1024, 768, 75, 78750, /* VESA */ 16, 176, 288, KdSyncPositive, /* 60.023 */ 1, 28, 32, KdSyncPositive, /* 75.029 */ }, { 1024, 768, 70, 75000, /* VESA */ 24, 144, 304, KdSyncNegative, /* 56.476 */ 3, 29, 38, KdSyncNegative, /* 70.069 */ }, { 1024, 768, 60, 65000, /* VESA */ 24, 160, 320, KdSyncNegative, /* 48.363 */ 3, 29, 38, KdSyncNegative, /* 60.004 */ }, /* 1152x864 mode */ { 1152, 864, 75, 108000, /* VESA */ 64, 256, 448, KdSyncPositive, /* 67.500 */ 1, 32, 36, KdSyncPositive, /* 75.000 */ }, /* 1152x900 modes */ { 1152, 900, 85, 122500, /* ADDED */ 48, 208, 384, KdSyncPositive, /* 79.753 */ 1, 32, 38, KdSyncPositive, /* 85.024 */ }, { 1152, 900, 75, 108250, /* ADDED */ 32, 208, 384, KdSyncPositive, /* 70.475 */ 1, 32, 38, KdSyncPositive, /* 75.133 */ }, { 1152, 900, 70, 100250, /* ADDED */ 32, 208, 384, KdSyncPositive, /* 65.267 */ 2, 32, 38, KdSyncPositive, /* 69.581 */ }, { 1152, 900, 66, 95000, /* ADDED */ 32, 208, 384, KdSyncPositive, /* 61.849 */ 1, 32, 38, KdSyncPositive, /* 65.937 */ }, /* 1280x960 modes */ { 1280, 960, 85, 148500, /* VESA */ 64, 224, 448, KdSyncPositive, /* 85.938 */ 1, 47, 51, KdSyncPositive, /* 85.002 */ }, { 1280, 960, 60, 108000, /* VESA */ 96, 312, 520, KdSyncPositive, /* 60.000 */ 1, 36, 40, KdSyncPositive, /* 60.000 */ }, /* 1280x1024 modes */ { 1280, 1024, 85, 157500, /* VESA */ 64, 224, 448, KdSyncPositive, /* 91.146 */ 1, 44, 48, KdSyncPositive, /* 85.024 */ }, { 1280, 1024, 75, 135000, /* VESA */ 16, 248, 408, KdSyncPositive, /* 79.976 */ 1, 38, 42, KdSyncPositive, /* 75.025 */ }, { 1280, 1024, 60, 108000, /* VESA */ 48, 248, 408, KdSyncPositive, /* 63.981 */ 1, 38, 42, KdSyncPositive, /* 60.020 */ }, /* 1600x1200 modes */ { 1600, 1200, 85, 229500, /* VESA */ 64, 304, 560, KdSyncPositive, /* 106.250 */ 1, 46, 50, KdSyncPositive, /* 85.000 */ }, { 1600, 1200, 75, 202500, /* VESA */ 64, 304, 560, KdSyncPositive, /* 93.750 */ 1, 46, 50, KdSyncPositive, /* 75.000 */ }, { 1600, 1200, 70, 189000, /* VESA */ 64, 304, 560, KdSyncPositive, /* 87.500 */ 1, 46, 50, KdSyncPositive, /* 70.000 */ }, { 1600, 1200, 65, 175500, /* VESA */ 64, 304, 560, KdSyncPositive, /* 81.250 */ 1, 46, 50, KdSyncPositive, /* 65.000 */ }, { 1600, 1200, 60, 162000, /* VESA */ 64, 304, 560, KdSyncPositive, /* 75.000 */ 1, 46, 50, KdSyncPositive, /* 60.000 */ }, /* 1792x1344 modes */ { 1792, 1344, 85, 301500, /* ADDED */ 96, 352, 672, KdSyncNegative, /* 122.362 */ 1, 92, 96, KdSyncPositive, /* 84.974 */ }, { 1792, 1344, 75, 261000, /* VESA */ 96, 352, 664, KdSyncNegative, /* 106.270 */ 1, 69, 73, KdSyncPositive, /* 74.997 */ }, { 1792, 1344, 60, 204750, /* VESA */ 128, 328, 656, KdSyncNegative, /* 83.640 */ 1, 46, 50, KdSyncPositive, /* 60.000 */ }, #if 0 { 1800, 1012, 75 }, { 1906, 1072, 68 }, #endif /* 1856x1392 modes */ { 1856, 1392, 85, 330500, /* ADDED */ 160, 352, 736, KdSyncNegative, /* 127.508 */ 1, 104, 108, KdSyncPositive, /* 85.001 */ }, { 1856, 1392, 75, 288000, /* VESA */ 128, 352, 704, KdSyncNegative, /* 112.500 */ 1, 104, 108, KdSyncPositive, /* 75.000 */ }, { 1856, 1392, 60, 218250, /* VESA */ 96, 352, 672, KdSyncNegative, /* 86.333 */ 1, 43, 47, KdSyncPositive, /* 59.995 */ }, /* 1920x1440 modes */ { 1920, 1440, 85, 341750, /* ADDED */ 160, 352, 760, KdSyncNegative, /* 127.512 */ 1, 56, 60, KdSyncPositive, /* 85.012 */ }, { 1920, 1440, 75, 297000, /* VESA */ 144, 352, 720, KdSyncNegative, /* 112.500 */ 1, 56, 60, KdSyncPositive, /* 75.000 */ }, { 1920, 1440, 60, 234000, /* VESA */ 128, 244, 680, KdSyncNegative, /* 90.000 */ 1, 56, 60, KdSyncPositive, /* 60.000 */ }, }; #define NUM_MONITOR_TIMINGS (sizeof kdMonitorTimings/sizeof kdMonitorTimings[0]) const int kdNumMonitorTimings = NUM_MONITOR_TIMINGS; const KdMonitorTiming * KdFindMode (KdScreenInfo *screen, Bool (*supported) (KdScreenInfo *, const KdMonitorTiming *)) { int i; const KdMonitorTiming *t; for (i = 0, t = kdMonitorTimings; i < NUM_MONITOR_TIMINGS; i++, t++) { if ((*supported) (screen, t) && t->horizontal == screen->width && t->vertical == screen->height && (!screen->rate || t->rate <= screen->rate)) { return t; } } return &kdMonitorTimings[MONITOR_TIMING_DEFAULT]; } static const KdMonitorTiming * kdFindPrevSize (const KdMonitorTiming *old) { const KdMonitorTiming *new, *prev; if (old == kdMonitorTimings) return 0; new = old; /* * Search for the previous size */ while (new != kdMonitorTimings) { new--; if (new->horizontal != old->horizontal && new->vertical != old->vertical) { break; } } /* * Match the refresh rate (<=) */ while (new != kdMonitorTimings) { prev = new - 1; if (prev->horizontal == new->horizontal && prev->vertical == new->vertical && prev->rate > old->rate) { break; } new--; } return new; } Bool KdTuneMode (KdScreenInfo *screen, Bool (*usable) (KdScreenInfo *), Bool (*supported) (KdScreenInfo *, const KdMonitorTiming *)) { const KdMonitorTiming *t, *new; while (!(*usable) (screen)) { /* * Fix requested depth and geometry until it works */ if (screen->fb[1].depth) screen->fb[1].depth = 0; else if (screen->fb[0].depth > 16) screen->fb[0].depth = 16; else if (screen->fb[0].depth > 8) screen->fb[0].depth = 8; else { t = kdFindPrevSize (KdFindMode (screen, supported)); if (!t) return FALSE; screen->width = t->horizontal; screen->height = t->vertical; screen->rate = t->rate; } } return TRUE; }