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