3 * Copyright © 2002 David Dawes
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * Except as contained in this notice, the name of the author(s) shall
24 * not be used in advertising or otherwise to promote the sale, use or other
25 * dealings in this Software without prior written authorization from
28 * Authors: David Dawes <dawes@xfree86.org>
32 #ifdef HAVE_XORG_CONFIG_H
33 #include <xorg-config.h>
44 GetDepthFlag(vbeInfoPtr pVbe
, int id
)
46 VbeModeInfoBlock
*mode
;
49 if ((mode
= VBEGetModeInfo(pVbe
, id
)) == NULL
)
52 if (VBE_MODE_USABLE(mode
, 0)) {
55 if (VBE_MODE_COLOR(mode
)) {
56 depth
= mode
->RedMaskSize
+ mode
->GreenMaskSize
+
62 bpp
= mode
->BitsPerPixel
;
63 VBEFreeModeInfo(mode
);
86 VBEFreeModeInfo(mode
);
91 * Find supported mode depths.
94 VBEFindSupportedDepths(vbeInfoPtr pVbe
, VbeInfoBlock
* vbe
, int *flags24
,
100 if (modeTypes
& V_MODETYPE_VBE
) {
101 while (vbe
->VideoModePtr
[i
] != 0xffff) {
102 depths
|= GetDepthFlag(pVbe
, vbe
->VideoModePtr
[i
++]);
107 * XXX This possibly only works with VBE 3.0 and later.
109 if (modeTypes
& V_MODETYPE_VGA
) {
110 for (i
= 0; i
< 0x7F; i
++) {
111 depths
|= GetDepthFlag(pVbe
, i
);
116 if (depths
& V_DEPTH_24_24
)
117 *flags24
|= Support24bppFb
;
118 if (depths
& V_DEPTH_24_32
)
119 *flags24
|= Support32bppFb
;
125 static DisplayModePtr
126 CheckMode(ScrnInfoPtr pScrn
, vbeInfoPtr pVbe
, VbeInfoBlock
* vbe
, int id
,
130 VbeModeInfoBlock
*mode
;
131 DisplayModePtr pMode
;
132 VbeModeInfoData
*data
;
135 major
= (unsigned) (vbe
->VESAVersion
>> 8);
137 if ((mode
= VBEGetModeInfo(pVbe
, id
)) == NULL
)
140 /* Does the mode match the depth/bpp? */
141 /* Some BIOS's set BitsPerPixel to 15 instead of 16 for 15/16 */
142 if (VBE_MODE_USABLE(mode
, flags
) &&
143 ((pScrn
->bitsPerPixel
== 1 && !VBE_MODE_COLOR(mode
)) ||
144 (mode
->BitsPerPixel
> 8 &&
145 (mode
->RedMaskSize
+ mode
->GreenMaskSize
+
146 mode
->BlueMaskSize
) == pScrn
->depth
&&
147 mode
->BitsPerPixel
== pScrn
->bitsPerPixel
) ||
148 (mode
->BitsPerPixel
== 15 && pScrn
->depth
== 15) ||
149 (mode
->BitsPerPixel
<= 8 &&
150 mode
->BitsPerPixel
== pScrn
->bitsPerPixel
))) {
152 xf86ErrorFVerb(DEBUG_VERB
, "*");
155 xf86ErrorFVerb(DEBUG_VERB
,
156 "Mode: %x (%dx%d)\n", id
, mode
->XResolution
,
158 xf86ErrorFVerb(DEBUG_VERB
, " ModeAttributes: 0x%x\n",
159 mode
->ModeAttributes
);
160 xf86ErrorFVerb(DEBUG_VERB
, " WinAAttributes: 0x%x\n",
161 mode
->WinAAttributes
);
162 xf86ErrorFVerb(DEBUG_VERB
, " WinBAttributes: 0x%x\n",
163 mode
->WinBAttributes
);
164 xf86ErrorFVerb(DEBUG_VERB
, " WinGranularity: %d\n",
165 mode
->WinGranularity
);
166 xf86ErrorFVerb(DEBUG_VERB
, " WinSize: %d\n", mode
->WinSize
);
167 xf86ErrorFVerb(DEBUG_VERB
,
168 " WinASegment: 0x%x\n", mode
->WinASegment
);
169 xf86ErrorFVerb(DEBUG_VERB
,
170 " WinBSegment: 0x%x\n", mode
->WinBSegment
);
171 xf86ErrorFVerb(DEBUG_VERB
,
172 " WinFuncPtr: 0x%lx\n", (unsigned long) mode
->WinFuncPtr
);
173 xf86ErrorFVerb(DEBUG_VERB
,
174 " BytesPerScanline: %d\n", mode
->BytesPerScanline
);
175 xf86ErrorFVerb(DEBUG_VERB
, " XResolution: %d\n", mode
->XResolution
);
176 xf86ErrorFVerb(DEBUG_VERB
, " YResolution: %d\n", mode
->YResolution
);
177 xf86ErrorFVerb(DEBUG_VERB
, " XCharSize: %d\n", mode
->XCharSize
);
178 xf86ErrorFVerb(DEBUG_VERB
, " YCharSize: %d\n", mode
->YCharSize
);
179 xf86ErrorFVerb(DEBUG_VERB
,
180 " NumberOfPlanes: %d\n", mode
->NumberOfPlanes
);
181 xf86ErrorFVerb(DEBUG_VERB
,
182 " BitsPerPixel: %d\n", mode
->BitsPerPixel
);
183 xf86ErrorFVerb(DEBUG_VERB
,
184 " NumberOfBanks: %d\n", mode
->NumberOfBanks
);
185 xf86ErrorFVerb(DEBUG_VERB
, " MemoryModel: %d\n", mode
->MemoryModel
);
186 xf86ErrorFVerb(DEBUG_VERB
, " BankSize: %d\n", mode
->BankSize
);
187 xf86ErrorFVerb(DEBUG_VERB
,
188 " NumberOfImages: %d\n", mode
->NumberOfImages
);
189 xf86ErrorFVerb(DEBUG_VERB
, " RedMaskSize: %d\n", mode
->RedMaskSize
);
190 xf86ErrorFVerb(DEBUG_VERB
,
191 " RedFieldPosition: %d\n", mode
->RedFieldPosition
);
192 xf86ErrorFVerb(DEBUG_VERB
,
193 " GreenMaskSize: %d\n", mode
->GreenMaskSize
);
194 xf86ErrorFVerb(DEBUG_VERB
,
195 " GreenFieldPosition: %d\n", mode
->GreenFieldPosition
);
196 xf86ErrorFVerb(DEBUG_VERB
,
197 " BlueMaskSize: %d\n", mode
->BlueMaskSize
);
198 xf86ErrorFVerb(DEBUG_VERB
,
199 " BlueFieldPosition: %d\n", mode
->BlueFieldPosition
);
200 xf86ErrorFVerb(DEBUG_VERB
,
201 " RsvdMaskSize: %d\n", mode
->RsvdMaskSize
);
202 xf86ErrorFVerb(DEBUG_VERB
,
203 " RsvdFieldPosition: %d\n", mode
->RsvdFieldPosition
);
204 xf86ErrorFVerb(DEBUG_VERB
,
205 " DirectColorModeInfo: %d\n", mode
->DirectColorModeInfo
);
207 xf86ErrorFVerb(DEBUG_VERB
,
208 " PhysBasePtr: 0x%lx\n",
209 (unsigned long) mode
->PhysBasePtr
);
211 xf86ErrorFVerb(DEBUG_VERB
,
212 " LinBytesPerScanLine: %d\n",
213 mode
->LinBytesPerScanLine
);
214 xf86ErrorFVerb(DEBUG_VERB
, " BnkNumberOfImagePages: %d\n",
215 mode
->BnkNumberOfImagePages
);
216 xf86ErrorFVerb(DEBUG_VERB
, " LinNumberOfImagePages: %d\n",
217 mode
->LinNumberOfImagePages
);
218 xf86ErrorFVerb(DEBUG_VERB
, " LinRedMaskSize: %d\n",
219 mode
->LinRedMaskSize
);
220 xf86ErrorFVerb(DEBUG_VERB
, " LinRedFieldPosition: %d\n",
221 mode
->LinRedFieldPosition
);
222 xf86ErrorFVerb(DEBUG_VERB
, " LinGreenMaskSize: %d\n",
223 mode
->LinGreenMaskSize
);
224 xf86ErrorFVerb(DEBUG_VERB
, " LinGreenFieldPosition: %d\n",
225 mode
->LinGreenFieldPosition
);
226 xf86ErrorFVerb(DEBUG_VERB
, " LinBlueMaskSize: %d\n",
227 mode
->LinBlueMaskSize
);
228 xf86ErrorFVerb(DEBUG_VERB
, " LinBlueFieldPosition: %d\n",
229 mode
->LinBlueFieldPosition
);
230 xf86ErrorFVerb(DEBUG_VERB
, " LinRsvdMaskSize: %d\n",
231 mode
->LinRsvdMaskSize
);
232 xf86ErrorFVerb(DEBUG_VERB
, " LinRsvdFieldPosition: %d\n",
233 mode
->LinRsvdFieldPosition
);
234 xf86ErrorFVerb(DEBUG_VERB
, " MaxPixelClock: %ld\n",
235 (unsigned long) mode
->MaxPixelClock
);
240 VBEFreeModeInfo(mode
);
243 pMode
= xnfcalloc(sizeof(DisplayModeRec
), 1);
245 pMode
->status
= MODE_OK
;
246 pMode
->type
= M_T_BUILTIN
;
248 /* for adjust frame */
249 pMode
->HDisplay
= mode
->XResolution
;
250 pMode
->VDisplay
= mode
->YResolution
;
252 data
= xnfcalloc(sizeof(VbeModeInfoData
), 1);
255 pMode
->PrivSize
= sizeof(VbeModeInfoData
);
256 pMode
->Private
= (INT32
*) data
;
262 * Check the available BIOS modes, and extract those that match the
263 * requirements into the modePool. Note: modePool is a NULL-terminated
268 VBEGetModePool(ScrnInfoPtr pScrn
, vbeInfoPtr pVbe
, VbeInfoBlock
* vbe
,
271 DisplayModePtr pMode
, p
= NULL
, modePool
= NULL
;
274 if (modeTypes
& V_MODETYPE_VBE
) {
275 while (vbe
->VideoModePtr
[i
] != 0xffff) {
276 int id
= vbe
->VideoModePtr
[i
++];
278 if ((pMode
= CheckMode(pScrn
, pVbe
, vbe
, id
, modeTypes
)) != NULL
) {
279 ModeStatus status
= MODE_OK
;
281 /* Check the mode against a specified virtual size (if any) */
282 if (pScrn
->display
->virtualX
> 0 &&
283 pMode
->HDisplay
> pScrn
->display
->virtualX
) {
284 status
= MODE_VIRTUAL_X
;
286 if (pScrn
->display
->virtualY
> 0 &&
287 pMode
->VDisplay
> pScrn
->display
->virtualY
) {
288 status
= MODE_VIRTUAL_Y
;
290 if (status
!= MODE_OK
) {
291 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
292 "Not using mode \"%dx%d\" (%s)\n",
293 pMode
->HDisplay
, pMode
->VDisplay
,
294 xf86ModeStatusToString(status
));
309 if (modeTypes
& V_MODETYPE_VGA
) {
310 for (i
= 0; i
< 0x7F; i
++) {
311 if ((pMode
= CheckMode(pScrn
, pVbe
, vbe
, i
, modeTypes
)) != NULL
) {
312 ModeStatus status
= MODE_OK
;
314 /* Check the mode against a specified virtual size (if any) */
315 if (pScrn
->display
->virtualX
> 0 &&
316 pMode
->HDisplay
> pScrn
->display
->virtualX
) {
317 status
= MODE_VIRTUAL_X
;
319 if (pScrn
->display
->virtualY
> 0 &&
320 pMode
->VDisplay
> pScrn
->display
->virtualY
) {
321 status
= MODE_VIRTUAL_Y
;
323 if (status
!= MODE_OK
) {
324 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
325 "Not using mode \"%dx%d\" (%s)\n",
326 pMode
->HDisplay
, pMode
->VDisplay
,
327 xf86ModeStatusToString(status
));
346 VBESetModeNames(DisplayModePtr pMode
)
353 /* Catch "bad" modes. */
354 if (pMode
->HDisplay
> 10000 || pMode
->HDisplay
< 0 ||
355 pMode
->VDisplay
> 10000 || pMode
->VDisplay
< 0) {
356 pMode
->name
= strdup("BADMODE");
359 XNFasprintf(&pMode
->name
, "%dx%d",
360 pMode
->HDisplay
, pMode
->VDisplay
);
368 * Go through the monitor modes and selecting the best set of
369 * parameters for each BIOS mode. Note: This is only supported in
370 * VBE version 3.0 or later.
373 VBESetModeParameters(ScrnInfoPtr pScrn
, vbeInfoPtr pVbe
)
375 DisplayModePtr pMode
;
376 VbeModeInfoData
*data
;
378 pMode
= pScrn
->modes
;
380 DisplayModePtr p
, best
= NULL
;
383 for (p
= pScrn
->monitor
->Modes
; p
!= NULL
; p
= p
->next
) {
384 if ((p
->HDisplay
!= pMode
->HDisplay
) ||
385 (p
->VDisplay
!= pMode
->VDisplay
) ||
386 (p
->Flags
& (V_INTERLACE
| V_DBLSCAN
| V_CLKDIV2
)))
388 /* XXX could support the various V_ flags */
389 status
= xf86CheckModeForMonitor(p
, pScrn
->monitor
);
390 if (status
!= MODE_OK
)
392 if (!best
|| (p
->Clock
> best
->Clock
))
399 data
= (VbeModeInfoData
*) pMode
->Private
;
400 pMode
->HSync
= (float) best
->Clock
* 1000.0 / best
->HTotal
+ 0.5;
401 pMode
->VRefresh
= pMode
->HSync
/ best
->VTotal
+ 0.5;
402 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
403 "Attempting to use %dHz refresh for mode \"%s\" (%x)\n",
404 (int) pMode
->VRefresh
, pMode
->name
, data
->mode
);
405 data
->block
= calloc(sizeof(VbeCRTCInfoBlock
), 1);
406 data
->block
->HorizontalTotal
= best
->HTotal
;
407 data
->block
->HorizontalSyncStart
= best
->HSyncStart
;
408 data
->block
->HorizontalSyncEnd
= best
->HSyncEnd
;
409 data
->block
->VerticalTotal
= best
->VTotal
;
410 data
->block
->VerticalSyncStart
= best
->VSyncStart
;
411 data
->block
->VerticalSyncEnd
= best
->VSyncEnd
;
412 data
->block
->Flags
= ((best
->Flags
& V_NHSYNC
) ? CRTC_NHSYNC
: 0) |
413 ((best
->Flags
& V_NVSYNC
) ? CRTC_NVSYNC
: 0);
414 data
->block
->PixelClock
= best
->Clock
* 1000;
415 /* XXX May not have this. */
416 clock
= VBEGetPixelClock(pVbe
, data
->mode
, data
->block
->PixelClock
);
417 DebugF("Setting clock %.2fMHz, closest is %.2fMHz\n",
418 (double) data
->block
->PixelClock
/ 1000000.0,
419 (double) clock
/ 1000000.0);
421 data
->block
->PixelClock
= clock
;
422 data
->mode
|= (1 << 11);
423 data
->block
->RefreshRate
= ((double) (data
->block
->PixelClock
) /
424 (double) (best
->HTotal
*
425 best
->VTotal
)) * 100;
428 } while (pMode
!= pScrn
->modes
);
432 * These wrappers are to allow (temporary) funtionality divergences.
435 VBEValidateModes(ScrnInfoPtr scrp
, DisplayModePtr availModes
,
436 char **modeNames
, ClockRangePtr clockRanges
,
437 int *linePitches
, int minPitch
, int maxPitch
, int pitchInc
,
438 int minHeight
, int maxHeight
, int virtualX
, int virtualY
,
439 int apertureSize
, LookupModeFlags strategy
)
441 return xf86ValidateModes(scrp
, availModes
, modeNames
, clockRanges
,
442 linePitches
, minPitch
, maxPitch
, pitchInc
,
443 minHeight
, maxHeight
, virtualX
, virtualY
,
444 apertureSize
, strategy
);
448 VBEPrintModes(ScrnInfoPtr scrp
)
450 xf86PrintModes(scrp
);