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