1ed6184dfSmrg#define DEBUG_VERB 2 2ed6184dfSmrg/* 3ed6184dfSmrg * Copyright © 2002 David Dawes 4ed6184dfSmrg * 5ed6184dfSmrg * Permission is hereby granted, free of charge, to any person obtaining a 6ed6184dfSmrg * copy of this software and associated documentation files (the "Software"), 7ed6184dfSmrg * to deal in the Software without restriction, including without limitation 8ed6184dfSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9ed6184dfSmrg * and/or sell copies of the Software, and to permit persons to whom the 10ed6184dfSmrg * Software is furnished to do so, subject to the following conditions: 11ed6184dfSmrg * 12ed6184dfSmrg * The above copyright notice and this permission notice shall be included in 13ed6184dfSmrg * all copies or substantial portions of the Software. 14ed6184dfSmrg * 15ed6184dfSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16ed6184dfSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17ed6184dfSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18ed6184dfSmrg * THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19ed6184dfSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 20ed6184dfSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21ed6184dfSmrg * SOFTWARE. 22ed6184dfSmrg * 23ed6184dfSmrg * Except as contained in this notice, the name of the author(s) shall 24ed6184dfSmrg * not be used in advertising or otherwise to promote the sale, use or other 25ed6184dfSmrg * dealings in this Software without prior written authorization from 26ed6184dfSmrg * the author(s). 27ed6184dfSmrg * 28ed6184dfSmrg * Authors: David Dawes <dawes@xfree86.org> 29ed6184dfSmrg * 30ed6184dfSmrg */ 31ed6184dfSmrg 32ed6184dfSmrg#ifdef HAVE_XORG_CONFIG_H 33ed6184dfSmrg#include <xorg-config.h> 34ed6184dfSmrg#endif 35ed6184dfSmrg 36ed6184dfSmrg#include <stdio.h> 37ed6184dfSmrg#include <string.h> 38ed6184dfSmrg 39ed6184dfSmrg#include "xf86.h" 40ed6184dfSmrg#include "vbe.h" 41ed6184dfSmrg#include "vbeModes.h" 42ed6184dfSmrg 43ed6184dfSmrgstatic int 44ed6184dfSmrgGetDepthFlag(vbeInfoPtr pVbe, int id) 45ed6184dfSmrg{ 46ed6184dfSmrg VbeModeInfoBlock *mode; 47ed6184dfSmrg int bpp; 48ed6184dfSmrg 49ed6184dfSmrg if ((mode = VBEGetModeInfo(pVbe, id)) == NULL) 50ed6184dfSmrg return 0; 51ed6184dfSmrg 52ed6184dfSmrg if (VBE_MODE_USABLE(mode, 0)) { 53ed6184dfSmrg int depth; 54ed6184dfSmrg 55ed6184dfSmrg if (VBE_MODE_COLOR(mode)) { 56ed6184dfSmrg depth = mode->RedMaskSize + mode->GreenMaskSize + 57ed6184dfSmrg mode->BlueMaskSize; 58ed6184dfSmrg } 59ed6184dfSmrg else { 60ed6184dfSmrg depth = 1; 61ed6184dfSmrg } 62ed6184dfSmrg bpp = mode->BitsPerPixel; 63ed6184dfSmrg VBEFreeModeInfo(mode); 64ed6184dfSmrg mode = NULL; 65ed6184dfSmrg switch (depth) { 66ed6184dfSmrg case 1: 67ed6184dfSmrg return V_DEPTH_1; 68ed6184dfSmrg case 4: 69ed6184dfSmrg return V_DEPTH_4; 70ed6184dfSmrg case 8: 71ed6184dfSmrg return V_DEPTH_8; 72ed6184dfSmrg case 15: 73ed6184dfSmrg return V_DEPTH_15; 74ed6184dfSmrg case 16: 75ed6184dfSmrg return V_DEPTH_16; 76ed6184dfSmrg case 24: 77ed6184dfSmrg switch (bpp) { 78ed6184dfSmrg case 24: 79ed6184dfSmrg return V_DEPTH_24_24; 80ed6184dfSmrg case 32: 81ed6184dfSmrg return V_DEPTH_24_32; 82ed6184dfSmrg } 83ed6184dfSmrg } 84ed6184dfSmrg } 85ed6184dfSmrg if (mode) 86ed6184dfSmrg VBEFreeModeInfo(mode); 87ed6184dfSmrg return 0; 88ed6184dfSmrg} 89ed6184dfSmrg 90ed6184dfSmrg/* 91ed6184dfSmrg * Find supported mode depths. 92ed6184dfSmrg */ 93ed6184dfSmrgint 94ed6184dfSmrgVBEFindSupportedDepths(vbeInfoPtr pVbe, VbeInfoBlock * vbe, int *flags24, 95ed6184dfSmrg int modeTypes) 96ed6184dfSmrg{ 97ed6184dfSmrg int i = 0; 98ed6184dfSmrg int depths = 0; 99ed6184dfSmrg 100ed6184dfSmrg if (modeTypes & V_MODETYPE_VBE) { 101ed6184dfSmrg while (vbe->VideoModePtr[i] != 0xffff) { 102ed6184dfSmrg depths |= GetDepthFlag(pVbe, vbe->VideoModePtr[i++]); 103ed6184dfSmrg } 104ed6184dfSmrg } 105ed6184dfSmrg 106ed6184dfSmrg /* 107ed6184dfSmrg * XXX This possibly only works with VBE 3.0 and later. 108ed6184dfSmrg */ 109ed6184dfSmrg if (modeTypes & V_MODETYPE_VGA) { 110ed6184dfSmrg for (i = 0; i < 0x7F; i++) { 111ed6184dfSmrg depths |= GetDepthFlag(pVbe, i); 112ed6184dfSmrg } 113ed6184dfSmrg } 114ed6184dfSmrg 115ed6184dfSmrg if (flags24) { 116ed6184dfSmrg if (depths & V_DEPTH_24_24) 117ed6184dfSmrg *flags24 |= Support24bppFb; 118ed6184dfSmrg if (depths & V_DEPTH_24_32) 119ed6184dfSmrg *flags24 |= Support32bppFb; 120ed6184dfSmrg } 121ed6184dfSmrg 122ed6184dfSmrg return depths; 123ed6184dfSmrg} 124ed6184dfSmrg 125ed6184dfSmrgstatic DisplayModePtr 126ed6184dfSmrgCheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock * vbe, int id, 127ed6184dfSmrg int flags) 128ed6184dfSmrg{ 129ed6184dfSmrg CARD16 major; 130ed6184dfSmrg VbeModeInfoBlock *mode; 131ed6184dfSmrg DisplayModePtr pMode; 132ed6184dfSmrg VbeModeInfoData *data; 133ed6184dfSmrg Bool modeOK = FALSE; 134ed6184dfSmrg 135ed6184dfSmrg major = (unsigned) (vbe->VESAVersion >> 8); 136ed6184dfSmrg 137ed6184dfSmrg if ((mode = VBEGetModeInfo(pVbe, id)) == NULL) 138ed6184dfSmrg return NULL; 139ed6184dfSmrg 140ed6184dfSmrg /* Does the mode match the depth/bpp? */ 141ed6184dfSmrg /* Some BIOS's set BitsPerPixel to 15 instead of 16 for 15/16 */ 142ed6184dfSmrg if (VBE_MODE_USABLE(mode, flags) && 143ed6184dfSmrg ((pScrn->bitsPerPixel == 1 && !VBE_MODE_COLOR(mode)) || 144ed6184dfSmrg (mode->BitsPerPixel > 8 && 145ed6184dfSmrg (mode->RedMaskSize + mode->GreenMaskSize + 146ed6184dfSmrg mode->BlueMaskSize) == pScrn->depth && 147ed6184dfSmrg mode->BitsPerPixel == pScrn->bitsPerPixel) || 148ed6184dfSmrg (mode->BitsPerPixel == 15 && pScrn->depth == 15) || 149ed6184dfSmrg (mode->BitsPerPixel <= 8 && 150ed6184dfSmrg mode->BitsPerPixel == pScrn->bitsPerPixel))) { 151ed6184dfSmrg modeOK = TRUE; 152ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, "*"); 153ed6184dfSmrg } 154ed6184dfSmrg 155ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 156ed6184dfSmrg "Mode: %x (%dx%d)\n", id, mode->XResolution, 157ed6184dfSmrg mode->YResolution); 158ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " ModeAttributes: 0x%x\n", 159ed6184dfSmrg mode->ModeAttributes); 160ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " WinAAttributes: 0x%x\n", 161ed6184dfSmrg mode->WinAAttributes); 162ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " WinBAttributes: 0x%x\n", 163ed6184dfSmrg mode->WinBAttributes); 164ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " WinGranularity: %d\n", 165ed6184dfSmrg mode->WinGranularity); 166ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " WinSize: %d\n", mode->WinSize); 167ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 168ed6184dfSmrg " WinASegment: 0x%x\n", mode->WinASegment); 169ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 170ed6184dfSmrg " WinBSegment: 0x%x\n", mode->WinBSegment); 171ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 172ed6184dfSmrg " WinFuncPtr: 0x%lx\n", (unsigned long) mode->WinFuncPtr); 173ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 174ed6184dfSmrg " BytesPerScanline: %d\n", mode->BytesPerScanline); 175ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " XResolution: %d\n", mode->XResolution); 176ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " YResolution: %d\n", mode->YResolution); 177ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " XCharSize: %d\n", mode->XCharSize); 178ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " YCharSize: %d\n", mode->YCharSize); 179ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 180ed6184dfSmrg " NumberOfPlanes: %d\n", mode->NumberOfPlanes); 181ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 182ed6184dfSmrg " BitsPerPixel: %d\n", mode->BitsPerPixel); 183ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 184ed6184dfSmrg " NumberOfBanks: %d\n", mode->NumberOfBanks); 185ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " MemoryModel: %d\n", mode->MemoryModel); 186ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " BankSize: %d\n", mode->BankSize); 187ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 188ed6184dfSmrg " NumberOfImages: %d\n", mode->NumberOfImages); 189ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " RedMaskSize: %d\n", mode->RedMaskSize); 190ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 191ed6184dfSmrg " RedFieldPosition: %d\n", mode->RedFieldPosition); 192ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 193ed6184dfSmrg " GreenMaskSize: %d\n", mode->GreenMaskSize); 194ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 195ed6184dfSmrg " GreenFieldPosition: %d\n", mode->GreenFieldPosition); 196ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 197ed6184dfSmrg " BlueMaskSize: %d\n", mode->BlueMaskSize); 198ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 199ed6184dfSmrg " BlueFieldPosition: %d\n", mode->BlueFieldPosition); 200ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 201ed6184dfSmrg " RsvdMaskSize: %d\n", mode->RsvdMaskSize); 202ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 203ed6184dfSmrg " RsvdFieldPosition: %d\n", mode->RsvdFieldPosition); 204ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 205ed6184dfSmrg " DirectColorModeInfo: %d\n", mode->DirectColorModeInfo); 206ed6184dfSmrg if (major >= 2) { 207ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 208ed6184dfSmrg " PhysBasePtr: 0x%lx\n", 209ed6184dfSmrg (unsigned long) mode->PhysBasePtr); 210ed6184dfSmrg if (major >= 3) { 211ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, 212ed6184dfSmrg " LinBytesPerScanLine: %d\n", 213ed6184dfSmrg mode->LinBytesPerScanLine); 214ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " BnkNumberOfImagePages: %d\n", 215ed6184dfSmrg mode->BnkNumberOfImagePages); 216ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " LinNumberOfImagePages: %d\n", 217ed6184dfSmrg mode->LinNumberOfImagePages); 218ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " LinRedMaskSize: %d\n", 219ed6184dfSmrg mode->LinRedMaskSize); 220ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " LinRedFieldPosition: %d\n", 221ed6184dfSmrg mode->LinRedFieldPosition); 222ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " LinGreenMaskSize: %d\n", 223ed6184dfSmrg mode->LinGreenMaskSize); 224ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " LinGreenFieldPosition: %d\n", 225ed6184dfSmrg mode->LinGreenFieldPosition); 226ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " LinBlueMaskSize: %d\n", 227ed6184dfSmrg mode->LinBlueMaskSize); 228ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " LinBlueFieldPosition: %d\n", 229ed6184dfSmrg mode->LinBlueFieldPosition); 230ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " LinRsvdMaskSize: %d\n", 231ed6184dfSmrg mode->LinRsvdMaskSize); 232ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " LinRsvdFieldPosition: %d\n", 233ed6184dfSmrg mode->LinRsvdFieldPosition); 234ed6184dfSmrg xf86ErrorFVerb(DEBUG_VERB, " MaxPixelClock: %ld\n", 235ed6184dfSmrg (unsigned long) mode->MaxPixelClock); 236ed6184dfSmrg } 237ed6184dfSmrg } 238ed6184dfSmrg 239ed6184dfSmrg if (!modeOK) { 240ed6184dfSmrg VBEFreeModeInfo(mode); 241ed6184dfSmrg return NULL; 242ed6184dfSmrg } 243ed6184dfSmrg pMode = xnfcalloc(sizeof(DisplayModeRec), 1); 244ed6184dfSmrg 245ed6184dfSmrg pMode->status = MODE_OK; 246ed6184dfSmrg pMode->type = M_T_BUILTIN; 247ed6184dfSmrg 248ed6184dfSmrg /* for adjust frame */ 249ed6184dfSmrg pMode->HDisplay = mode->XResolution; 250ed6184dfSmrg pMode->VDisplay = mode->YResolution; 251ed6184dfSmrg 252ed6184dfSmrg data = xnfcalloc(sizeof(VbeModeInfoData), 1); 253ed6184dfSmrg data->mode = id; 254ed6184dfSmrg data->data = mode; 255ed6184dfSmrg pMode->PrivSize = sizeof(VbeModeInfoData); 256ed6184dfSmrg pMode->Private = (INT32 *) data; 257ed6184dfSmrg pMode->next = NULL; 258ed6184dfSmrg return pMode; 259ed6184dfSmrg} 260ed6184dfSmrg 261ed6184dfSmrg/* 262ed6184dfSmrg * Check the available BIOS modes, and extract those that match the 263ed6184dfSmrg * requirements into the modePool. Note: modePool is a NULL-terminated 264ed6184dfSmrg * list. 265ed6184dfSmrg */ 266ed6184dfSmrg 267ed6184dfSmrgDisplayModePtr 268ed6184dfSmrgVBEGetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock * vbe, 269ed6184dfSmrg int modeTypes) 270ed6184dfSmrg{ 271ed6184dfSmrg DisplayModePtr pMode, p = NULL, modePool = NULL; 272ed6184dfSmrg int i = 0; 273ed6184dfSmrg 274ed6184dfSmrg if (modeTypes & V_MODETYPE_VBE) { 275ed6184dfSmrg while (vbe->VideoModePtr[i] != 0xffff) { 276ed6184dfSmrg int id = vbe->VideoModePtr[i++]; 277ed6184dfSmrg 278ed6184dfSmrg if ((pMode = CheckMode(pScrn, pVbe, vbe, id, modeTypes)) != NULL) { 279ed6184dfSmrg ModeStatus status = MODE_OK; 280ed6184dfSmrg 281ed6184dfSmrg /* Check the mode against a specified virtual size (if any) */ 282ed6184dfSmrg if (pScrn->display->virtualX > 0 && 283ed6184dfSmrg pMode->HDisplay > pScrn->display->virtualX) { 284ed6184dfSmrg status = MODE_VIRTUAL_X; 285ed6184dfSmrg } 286ed6184dfSmrg if (pScrn->display->virtualY > 0 && 287ed6184dfSmrg pMode->VDisplay > pScrn->display->virtualY) { 288ed6184dfSmrg status = MODE_VIRTUAL_Y; 289ed6184dfSmrg } 290ed6184dfSmrg if (status != MODE_OK) { 291ed6184dfSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 292ed6184dfSmrg "Not using mode \"%dx%d\" (%s)\n", 293ed6184dfSmrg pMode->HDisplay, pMode->VDisplay, 294ed6184dfSmrg xf86ModeStatusToString(status)); 295ed6184dfSmrg } 296ed6184dfSmrg else { 297ed6184dfSmrg if (p == NULL) { 298ed6184dfSmrg modePool = pMode; 299ed6184dfSmrg } 300ed6184dfSmrg else { 301ed6184dfSmrg p->next = pMode; 302ed6184dfSmrg } 303ed6184dfSmrg pMode->prev = NULL; 304ed6184dfSmrg p = pMode; 305ed6184dfSmrg } 306ed6184dfSmrg } 307ed6184dfSmrg } 308ed6184dfSmrg } 309ed6184dfSmrg if (modeTypes & V_MODETYPE_VGA) { 310ed6184dfSmrg for (i = 0; i < 0x7F; i++) { 311ed6184dfSmrg if ((pMode = CheckMode(pScrn, pVbe, vbe, i, modeTypes)) != NULL) { 312ed6184dfSmrg ModeStatus status = MODE_OK; 313ed6184dfSmrg 314ed6184dfSmrg /* Check the mode against a specified virtual size (if any) */ 315ed6184dfSmrg if (pScrn->display->virtualX > 0 && 316ed6184dfSmrg pMode->HDisplay > pScrn->display->virtualX) { 317ed6184dfSmrg status = MODE_VIRTUAL_X; 318ed6184dfSmrg } 319ed6184dfSmrg if (pScrn->display->virtualY > 0 && 320ed6184dfSmrg pMode->VDisplay > pScrn->display->virtualY) { 321ed6184dfSmrg status = MODE_VIRTUAL_Y; 322ed6184dfSmrg } 323ed6184dfSmrg if (status != MODE_OK) { 324ed6184dfSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 325ed6184dfSmrg "Not using mode \"%dx%d\" (%s)\n", 326ed6184dfSmrg pMode->HDisplay, pMode->VDisplay, 327ed6184dfSmrg xf86ModeStatusToString(status)); 328ed6184dfSmrg } 329ed6184dfSmrg else { 330ed6184dfSmrg if (p == NULL) { 331ed6184dfSmrg modePool = pMode; 332ed6184dfSmrg } 333ed6184dfSmrg else { 334ed6184dfSmrg p->next = pMode; 335ed6184dfSmrg } 336ed6184dfSmrg pMode->prev = NULL; 337ed6184dfSmrg p = pMode; 338ed6184dfSmrg } 339ed6184dfSmrg } 340ed6184dfSmrg } 341ed6184dfSmrg } 342ed6184dfSmrg return modePool; 343ed6184dfSmrg} 344ed6184dfSmrg 345ed6184dfSmrgvoid 346ed6184dfSmrgVBESetModeNames(DisplayModePtr pMode) 347ed6184dfSmrg{ 348ed6184dfSmrg if (!pMode) 349ed6184dfSmrg return; 350ed6184dfSmrg 351ed6184dfSmrg do { 352ed6184dfSmrg if (!pMode->name) { 353ed6184dfSmrg /* Catch "bad" modes. */ 354ed6184dfSmrg if (pMode->HDisplay > 10000 || pMode->HDisplay < 0 || 355ed6184dfSmrg pMode->VDisplay > 10000 || pMode->VDisplay < 0) { 356ed6184dfSmrg pMode->name = strdup("BADMODE"); 357ed6184dfSmrg } 358ed6184dfSmrg else { 359ed6184dfSmrg char *tmp; 360ed6184dfSmrg XNFasprintf(&tmp, "%dx%d", 361ed6184dfSmrg pMode->HDisplay, pMode->VDisplay); 362ed6184dfSmrg pMode->name = tmp; 363ed6184dfSmrg } 364ed6184dfSmrg } 365ed6184dfSmrg pMode = pMode->next; 366ed6184dfSmrg } while (pMode); 367ed6184dfSmrg} 368ed6184dfSmrg 369ed6184dfSmrg/* 370ed6184dfSmrg * Go through the monitor modes and selecting the best set of 371ed6184dfSmrg * parameters for each BIOS mode. Note: This is only supported in 372ed6184dfSmrg * VBE version 3.0 or later. 373ed6184dfSmrg */ 374ed6184dfSmrgvoid 375ed6184dfSmrgVBESetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe) 376ed6184dfSmrg{ 377ed6184dfSmrg DisplayModePtr pMode; 378ed6184dfSmrg VbeModeInfoData *data; 379ed6184dfSmrg 380ed6184dfSmrg pMode = pScrn->modes; 381ed6184dfSmrg do { 382ed6184dfSmrg DisplayModePtr p, best = NULL; 383ed6184dfSmrg ModeStatus status; 384ed6184dfSmrg 385ed6184dfSmrg for (p = pScrn->monitor->Modes; p != NULL; p = p->next) { 386ed6184dfSmrg if ((p->HDisplay != pMode->HDisplay) || 387ed6184dfSmrg (p->VDisplay != pMode->VDisplay) || 388ed6184dfSmrg (p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2))) 389ed6184dfSmrg continue; 390ed6184dfSmrg /* XXX could support the various V_ flags */ 391ed6184dfSmrg status = xf86CheckModeForMonitor(p, pScrn->monitor); 392ed6184dfSmrg if (status != MODE_OK) 393ed6184dfSmrg continue; 394ed6184dfSmrg if (!best || (p->Clock > best->Clock)) 395ed6184dfSmrg best = p; 396ed6184dfSmrg } 397ed6184dfSmrg 398ed6184dfSmrg if (best) { 399ed6184dfSmrg int clock; 400ed6184dfSmrg 401ed6184dfSmrg data = (VbeModeInfoData *) pMode->Private; 402ed6184dfSmrg pMode->HSync = (float) best->Clock * 1000.0 / best->HTotal + 0.5; 403ed6184dfSmrg pMode->VRefresh = pMode->HSync / best->VTotal + 0.5; 404ed6184dfSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 405ed6184dfSmrg "Attempting to use %dHz refresh for mode \"%s\" (%x)\n", 406ed6184dfSmrg (int) pMode->VRefresh, pMode->name, data->mode); 407ed6184dfSmrg data->block = calloc(sizeof(VbeCRTCInfoBlock), 1); 408ed6184dfSmrg data->block->HorizontalTotal = best->HTotal; 409ed6184dfSmrg data->block->HorizontalSyncStart = best->HSyncStart; 410ed6184dfSmrg data->block->HorizontalSyncEnd = best->HSyncEnd; 411ed6184dfSmrg data->block->VerticalTotal = best->VTotal; 412ed6184dfSmrg data->block->VerticalSyncStart = best->VSyncStart; 413ed6184dfSmrg data->block->VerticalSyncEnd = best->VSyncEnd; 414ed6184dfSmrg data->block->Flags = ((best->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) | 415ed6184dfSmrg ((best->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0); 416ed6184dfSmrg data->block->PixelClock = best->Clock * 1000; 417ed6184dfSmrg /* XXX May not have this. */ 418ed6184dfSmrg clock = VBEGetPixelClock(pVbe, data->mode, data->block->PixelClock); 419ed6184dfSmrg DebugF("Setting clock %.2fMHz, closest is %.2fMHz\n", 420ed6184dfSmrg (double) data->block->PixelClock / 1000000.0, 421ed6184dfSmrg (double) clock / 1000000.0); 422ed6184dfSmrg if (clock) 423ed6184dfSmrg data->block->PixelClock = clock; 424ed6184dfSmrg data->mode |= (1 << 11); 425ed6184dfSmrg data->block->RefreshRate = ((double) (data->block->PixelClock) / 426ed6184dfSmrg (double) (best->HTotal * 427ed6184dfSmrg best->VTotal)) * 100; 428ed6184dfSmrg } 429ed6184dfSmrg pMode = pMode->next; 430ed6184dfSmrg } while (pMode != pScrn->modes); 431ed6184dfSmrg} 432ed6184dfSmrg 433ed6184dfSmrg/* 434ed6184dfSmrg * These wrappers are to allow (temporary) functionality divergences. 435ed6184dfSmrg */ 436ed6184dfSmrgint 437ed6184dfSmrgVBEValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes, 438ed6184dfSmrg const char **modeNames, ClockRangePtr clockRanges, 439ed6184dfSmrg int *linePitches, int minPitch, int maxPitch, int pitchInc, 440ed6184dfSmrg int minHeight, int maxHeight, int virtualX, int virtualY, 441ed6184dfSmrg int apertureSize, LookupModeFlags strategy) 442ed6184dfSmrg{ 443ed6184dfSmrg return xf86ValidateModes(scrp, availModes, modeNames, clockRanges, 444ed6184dfSmrg linePitches, minPitch, maxPitch, pitchInc, 445ed6184dfSmrg minHeight, maxHeight, virtualX, virtualY, 446ed6184dfSmrg apertureSize, strategy); 447ed6184dfSmrg} 448ed6184dfSmrg 449ed6184dfSmrgvoid 450ed6184dfSmrgVBEPrintModes(ScrnInfoPtr scrp) 451ed6184dfSmrg{ 452ed6184dfSmrg xf86PrintModes(scrp); 453ed6184dfSmrg} 454