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>
30
* $XFree86: xc/programs/Xserver/hw/xfree86/vbe/vbeModes.c,v 1.3tsi Exp $
33
#ifdef HAVE_XORG_CONFIG_H
34
#include <xorg-config.h>
38
#include "xf86_ansic.h"
43
GetDepthFlag(vbeInfoPtr pVbe, int id)
45
VbeModeInfoBlock *mode;
48
if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
51
if (VBE_MODE_USABLE(mode, 0)) {
54
if (VBE_MODE_COLOR(mode)) {
55
depth = mode->RedMaskSize + mode->GreenMaskSize +
60
bpp = mode->BitsPerPixel;
61
VBEFreeModeInfo(mode);
84
VBEFreeModeInfo(mode);
89
* Find supported mode depths.
92
VBEFindSupportedDepths(vbeInfoPtr pVbe, VbeInfoBlock *vbe, int *flags24,
98
if (modeTypes & V_MODETYPE_VBE) {
99
while (vbe->VideoModePtr[i] != 0xffff) {
100
depths |= GetDepthFlag(pVbe, vbe->VideoModePtr[i++]);
105
* XXX This possibly only works with VBE 3.0 and later.
107
if (modeTypes & V_MODETYPE_VGA) {
108
for (i = 0; i < 0x7F; i++) {
109
depths |= GetDepthFlag(pVbe, i);
114
if (depths & V_DEPTH_24_24)
115
*flags24 |= Support24bppFb;
116
if (depths & V_DEPTH_24_32)
117
*flags24 |= Support32bppFb;
123
static DisplayModePtr
124
CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
128
VbeModeInfoBlock *mode;
129
DisplayModePtr pMode, p;
130
VbeModeInfoData *data;
132
ModeStatus status = MODE_OK;
134
major = (unsigned)(vbe->VESAVersion >> 8);
136
if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
139
/* Does the mode match the depth/bpp? */
140
/* Some BIOS's set BitsPerPixel to 15 instead of 16 for 15/16 */
141
if (VBE_MODE_USABLE(mode, flags) &&
142
((pScrn->bitsPerPixel == 1 && !VBE_MODE_COLOR(mode)) ||
143
(mode->BitsPerPixel > 8 &&
144
(mode->RedMaskSize + mode->GreenMaskSize +
145
mode->BlueMaskSize) == pScrn->depth &&
146
mode->BitsPerPixel == pScrn->bitsPerPixel) ||
147
(mode->BitsPerPixel == 15 && pScrn->depth == 15) ||
148
(mode->BitsPerPixel <= 8 &&
149
mode->BitsPerPixel == pScrn->bitsPerPixel))) {
151
xf86ErrorFVerb(DEBUG_VERB, "*");
155
* Check if there's a valid monitor mode that this one can be matched
156
* up with. The actual matching is done later.
159
Bool sizeMatch = FALSE;
161
for (p = pScrn->monitor->Modes; p != NULL; p = p->next) {
162
if ((p->HDisplay != mode->XResolution) ||
163
(p->VDisplay != mode->YResolution) ||
164
(p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
167
/* XXX could support the various V_ flags */
168
status = xf86CheckModeForMonitor(p, pScrn->monitor);
169
if (status == MODE_OK) {
174
if (sizeMatch && !modeOK) {
175
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
176
"Not using built-in mode \"%dx%d\" (%s)\n",
177
mode->XResolution, mode->YResolution,
178
xf86ModeStatusToString(status));
182
xf86ErrorFVerb(DEBUG_VERB,
183
"Mode: %x (%dx%d)\n", id, mode->XResolution, mode->YResolution);
184
xf86ErrorFVerb(DEBUG_VERB,
185
" ModeAttributes: 0x%x\n", mode->ModeAttributes);
186
xf86ErrorFVerb(DEBUG_VERB,
187
" WinAAttributes: 0x%x\n", mode->WinAAttributes);
188
xf86ErrorFVerb(DEBUG_VERB,
189
" WinBAttributes: 0x%x\n", mode->WinBAttributes);
190
xf86ErrorFVerb(DEBUG_VERB,
191
" WinGranularity: %d\n", mode->WinGranularity);
192
xf86ErrorFVerb(DEBUG_VERB,
193
" WinSize: %d\n", mode->WinSize);
194
xf86ErrorFVerb(DEBUG_VERB,
195
" WinASegment: 0x%x\n", mode->WinASegment);
196
xf86ErrorFVerb(DEBUG_VERB,
197
" WinBSegment: 0x%x\n", mode->WinBSegment);
198
xf86ErrorFVerb(DEBUG_VERB,
199
" WinFuncPtr: 0x%lx\n", (unsigned long)mode->WinFuncPtr);
200
xf86ErrorFVerb(DEBUG_VERB,
201
" BytesPerScanline: %d\n", mode->BytesPerScanline);
202
xf86ErrorFVerb(DEBUG_VERB,
203
" XResolution: %d\n", mode->XResolution);
204
xf86ErrorFVerb(DEBUG_VERB,
205
" YResolution: %d\n", mode->YResolution);
206
xf86ErrorFVerb(DEBUG_VERB,
207
" XCharSize: %d\n", mode->XCharSize);
208
xf86ErrorFVerb(DEBUG_VERB,
209
" YCharSize: %d\n", mode->YCharSize);
210
xf86ErrorFVerb(DEBUG_VERB,
211
" NumberOfPlanes: %d\n", mode->NumberOfPlanes);
212
xf86ErrorFVerb(DEBUG_VERB,
213
" BitsPerPixel: %d\n", mode->BitsPerPixel);
214
xf86ErrorFVerb(DEBUG_VERB,
215
" NumberOfBanks: %d\n", mode->NumberOfBanks);
216
xf86ErrorFVerb(DEBUG_VERB,
217
" MemoryModel: %d\n", mode->MemoryModel);
218
xf86ErrorFVerb(DEBUG_VERB,
219
" BankSize: %d\n", mode->BankSize);
220
xf86ErrorFVerb(DEBUG_VERB,
221
" NumberOfImages: %d\n", mode->NumberOfImages);
222
xf86ErrorFVerb(DEBUG_VERB,
223
" RedMaskSize: %d\n", mode->RedMaskSize);
224
xf86ErrorFVerb(DEBUG_VERB,
225
" RedFieldPosition: %d\n", mode->RedFieldPosition);
226
xf86ErrorFVerb(DEBUG_VERB,
227
" GreenMaskSize: %d\n", mode->GreenMaskSize);
228
xf86ErrorFVerb(DEBUG_VERB,
229
" GreenFieldPosition: %d\n", mode->GreenFieldPosition);
230
xf86ErrorFVerb(DEBUG_VERB,
231
" BlueMaskSize: %d\n", mode->BlueMaskSize);
232
xf86ErrorFVerb(DEBUG_VERB,
233
" BlueFieldPosition: %d\n", mode->BlueFieldPosition);
234
xf86ErrorFVerb(DEBUG_VERB,
235
" RsvdMaskSize: %d\n", mode->RsvdMaskSize);
236
xf86ErrorFVerb(DEBUG_VERB,
237
" RsvdFieldPosition: %d\n", mode->RsvdFieldPosition);
238
xf86ErrorFVerb(DEBUG_VERB,
239
" DirectColorModeInfo: %d\n", mode->DirectColorModeInfo);
241
xf86ErrorFVerb(DEBUG_VERB,
242
" PhysBasePtr: 0x%lx\n",
243
(unsigned long)mode->PhysBasePtr);
245
xf86ErrorFVerb(DEBUG_VERB,
246
" LinBytesPerScanLine: %d\n", mode->LinBytesPerScanLine);
247
xf86ErrorFVerb(DEBUG_VERB,
248
" BnkNumberOfImagePages: %d\n", mode->BnkNumberOfImagePages);
249
xf86ErrorFVerb(DEBUG_VERB,
250
" LinNumberOfImagePages: %d\n", mode->LinNumberOfImagePages);
251
xf86ErrorFVerb(DEBUG_VERB,
252
" LinRedMaskSize: %d\n", mode->LinRedMaskSize);
253
xf86ErrorFVerb(DEBUG_VERB,
254
" LinRedFieldPosition: %d\n", mode->LinRedFieldPosition);
255
xf86ErrorFVerb(DEBUG_VERB,
256
" LinGreenMaskSize: %d\n", mode->LinGreenMaskSize);
257
xf86ErrorFVerb(DEBUG_VERB,
258
" LinGreenFieldPosition: %d\n", mode->LinGreenFieldPosition);
259
xf86ErrorFVerb(DEBUG_VERB,
260
" LinBlueMaskSize: %d\n", mode->LinBlueMaskSize);
261
xf86ErrorFVerb(DEBUG_VERB,
262
" LinBlueFieldPosition: %d\n", mode->LinBlueFieldPosition);
263
xf86ErrorFVerb(DEBUG_VERB,
264
" LinRsvdMaskSize: %d\n", mode->LinRsvdMaskSize);
265
xf86ErrorFVerb(DEBUG_VERB,
266
" LinRsvdFieldPosition: %d\n", mode->LinRsvdFieldPosition);
267
xf86ErrorFVerb(DEBUG_VERB,
268
" MaxPixelClock: %ld\n", (unsigned long)mode->MaxPixelClock);
273
VBEFreeModeInfo(mode);
276
pMode = xnfcalloc(sizeof(DisplayModeRec), 1);
278
pMode->status = MODE_OK;
279
pMode->type = M_T_BUILTIN;
281
/* for adjust frame */
282
pMode->HDisplay = mode->XResolution;
283
pMode->VDisplay = mode->YResolution;
285
data = xnfcalloc(sizeof(VbeModeInfoData), 1);
288
pMode->PrivSize = sizeof(VbeModeInfoData);
289
pMode->Private = (INT32*)data;
295
* Check the available BIOS modes, and extract those that match the
296
* requirements into the modePool. Note: modePool is a NULL-terminated
301
VBEGetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe,
304
DisplayModePtr pMode, p = NULL, modePool = NULL;
307
if (modeTypes & V_MODETYPE_VBE) {
308
while (vbe->VideoModePtr[i] != 0xffff) {
309
int id = vbe->VideoModePtr[i++];
311
if ((pMode = CheckMode(pScrn, pVbe, vbe, id, 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));
340
if (modeTypes & V_MODETYPE_VGA) {
341
for (i = 0; i < 0x7F; i++) {
342
if ((pMode = CheckMode(pScrn, pVbe, vbe, i, modeTypes)) != NULL) {
343
ModeStatus status = MODE_OK;
345
/* Check the mode against a specified virtual size (if any) */
346
if (pScrn->display->virtualX > 0 &&
347
pMode->HDisplay > pScrn->display->virtualX) {
348
status = MODE_VIRTUAL_X;
350
if (pScrn->display->virtualY > 0 &&
351
pMode->VDisplay > pScrn->display->virtualY) {
352
status = MODE_VIRTUAL_Y;
354
if (status != MODE_OK) {
355
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
356
"Not using mode \"%dx%d\" (%s)\n",
357
pMode->HDisplay, pMode->VDisplay,
358
xf86ModeStatusToString(status));
375
VBESetModeNames(DisplayModePtr pMode)
382
/* Catch "bad" modes. */
383
if (pMode->HDisplay > 10000 || pMode->HDisplay < 0 ||
384
pMode->VDisplay > 10000 || pMode->VDisplay < 0) {
385
pMode->name = strdup("BADMODE");
387
pMode->name = xnfalloc(4 + 1 + 4 + 1);
388
sprintf(pMode->name, "%dx%d", pMode->HDisplay, pMode->VDisplay);
396
* Go through the monitor modes and selecting the best set of
397
* parameters for each BIOS mode. Note: This is only supported in
398
* VBE version 3.0 or later.
401
VBESetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
403
DisplayModePtr pMode;
404
VbeModeInfoData *data;
406
pMode = pScrn->modes;
408
DisplayModePtr p, best = NULL;
411
for (p = pScrn->monitor->Modes; p != NULL; p = p->next) {
412
if ((p->HDisplay != pMode->HDisplay) ||
413
(p->VDisplay != pMode->VDisplay) ||
414
(p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
416
/* XXX could support the various V_ flags */
417
status = xf86CheckModeForMonitor(p, pScrn->monitor);
418
if (status != MODE_OK)
420
if (!best || (p->Clock > best->Clock))
427
data = (VbeModeInfoData*)pMode->Private;
428
pMode->HSync = (float)best->Clock * 1000.0 / best->HTotal + 0.5;
429
pMode->VRefresh = pMode->HSync / best->VTotal + 0.5;
430
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
431
"Attempting to use %dHz refresh for mode \"%s\" (%x)\n",
432
(int)pMode->VRefresh, pMode->name, data->mode);
433
data->block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
434
data->block->HorizontalTotal = best->HTotal;
435
data->block->HorizontalSyncStart = best->HSyncStart;
436
data->block->HorizontalSyncEnd = best->HSyncEnd;
437
data->block->VerticalTotal = best->VTotal;
438
data->block->VerticalSyncStart = best->VSyncStart;
439
data->block->VerticalSyncEnd = best->VSyncEnd;
440
data->block->Flags = ((best->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
441
((best->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
442
data->block->PixelClock = best->Clock * 1000;
443
/* XXX May not have this. */
444
clock = VBEGetPixelClock(pVbe, data->mode, data->block->PixelClock);
446
ErrorF("Setting clock %.2fMHz, closest is %.2fMHz\n",
447
(double)data->block->PixelClock / 1000000.0,
448
(double)clock / 1000000.0);
451
data->block->PixelClock = clock;
452
data->mode |= (1 << 11);
453
data->block->RefreshRate = ((double)(data->block->PixelClock) /
454
(double)(best->HTotal * best->VTotal)) * 100;
457
} while (pMode != pScrn->modes);
461
* These wrappers are to allow (temporary) funtionality divergences.
464
VBEValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
465
char **modeNames, ClockRangePtr clockRanges,
466
int *linePitches, int minPitch, int maxPitch, int pitchInc,
467
int minHeight, int maxHeight, int virtualX, int virtualY,
468
int apertureSize, LookupModeFlags strategy)
470
return xf86ValidateModes(scrp, availModes, modeNames, clockRanges,
471
linePitches, minPitch, maxPitch, pitchInc,
472
minHeight, maxHeight, virtualX, virtualY,
473
apertureSize, strategy);
477
VBEPrintModes(ScrnInfoPtr scrp)
479
xf86PrintModes(scrp);