Bugzilla #1064: https://bugs.freedesktop.org/show_bug.cgi?id=1064
Bugzilla #3055: https://bugs.freedesktop.org/show_bug.cgi?id=3055
Much better display switching support for mobile chipsets using
the Fn+F? combination keys.
Add DirectColor support.
Add gamma correction support.
This commit is contained in:
Alan Hourihane 2005-05-20 13:24:02 +00:00
parent b99ef9cd59
commit df0964ea8f
3 changed files with 1068 additions and 640 deletions

View File

@ -91,7 +91,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
typedef struct _VESARec {
/* SVGA state */
pointer state, pstate;
int statePage, stateSize, stateMode;
int statePage, stateSize, stateMode, stateRefresh;
CARD32 *savedPal;
int savedScanlinePitch;
xf86MonPtr monitor;
@ -165,13 +165,17 @@ typedef struct _I830Rec {
Bool newPipeSwitch;
Bool fakeSwitch;
int fixedPipe;
Bool Clone;
int CloneRefresh;
int CloneHDisplay;
int CloneVDisplay;
I830EntPtr entityPrivate;
int pipe;
int pipe, origPipe;
int init;
unsigned int bufferOffset; /* for I830SelectBuffer */
@ -234,6 +238,7 @@ typedef struct _I830Rec {
int MonType1;
int MonType2;
Bool specifiedMonitor;
DGAModePtr DGAModes;
int numDGAModes;
@ -320,10 +325,11 @@ typedef struct _I830Rec {
/* Use BIOS call 0x5f05 to set the refresh rate. */
Bool useExtendedRefresh;
Bool checkLid;
Bool checkDevices;
int monitorSwitch;
int operatingDevices;
int savedDevices;
int lastDevice1, lastDevice2;
/* These are indexed by the display types */
Bool displayAttached[NumDisplayTypes];
@ -343,6 +349,7 @@ typedef struct _I830Rec {
Bool starting;
Bool closing;
Bool suspended;
Bool leaving;
/* fbOffset converted to (x, y). */
int xoffset;
@ -353,7 +360,7 @@ typedef struct _I830Rec {
Bool displayInfo;
Bool devicePresence;
OsTimerPtr lidTimer;
OsTimerPtr devicesTimer;
} I830Rec;
#define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
@ -424,19 +431,21 @@ extern void I830ReadAllRegisters(I830Ptr pI830, I830RegPtr i830Reg);
extern void I830ChangeFrontbuffer(ScrnInfoPtr pScrn,int buffer);
extern DisplayModePtr i830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe,
VbeInfoBlock *vbe, int modeTypes);
extern void i830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe);
extern void i830PrintModes(ScrnInfoPtr pScrn);
extern DisplayModePtr I830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe,
VbeInfoBlock *vbe);
extern void I830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe);
extern void I830UnsetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe);
extern void I830PrintModes(ScrnInfoPtr pScrn);
extern int I830GetBestRefresh(ScrnInfoPtr pScrn, int refresh);
extern Bool I830CheckModeSupport(ScrnInfoPtr pScrn, int x, int y, int mode);
/*
* 12288 is set as the maximum, chosen because it is enough for
* 1920x1440@32bpp with a 2048 pixel line pitch with some to spare.
*/
#define I830_MAXIMUM_VBIOS_MEM 12288
#define I830_DEFAULT_VIDEOMEM_2D (MB(8) / 1024)
#define I830_DEFAULT_VIDEOMEM_3D (MB(32) / 1024)
#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024)
#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024)
/* Flags for memory allocation function */
#define FROM_ANYWHERE 0x00000000

File diff suppressed because it is too large Load Diff

View File

@ -356,7 +356,7 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
{
CARD16 major, minor;
VbeModeInfoBlock *mode;
DisplayModePtr pMode = NULL;
DisplayModePtr p = NULL, pMode = NULL;
VbeModeInfoData *data;
Bool modeOK = FALSE;
ModeStatus status = MODE_OK;
@ -382,14 +382,42 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
xf86ErrorFVerb(DEBUG_VERB, "*");
}
if (mode->XResolution && mode->YResolution &&
!I830CheckModeSupport(pScrn, mode->XResolution, mode->YResolution, id))
modeOK = FALSE;
/*
* Check if there's a valid monitor mode that this one can be matched
* up with from the specified modes list.
*/
if (modeOK) {
for (p = pScrn->monitor->Modes; p != NULL; p = p->next) {
if ((p->HDisplay != mode->XResolution) ||
(p->VDisplay != mode->YResolution) ||
(p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
continue;
status = xf86CheckModeForMonitor(p, pScrn->monitor);
if (p->type == M_T_BUILTIN) continue;
if (status == MODE_OK) {
modeOK = TRUE;
break;
}
}
if (p) {
pMode = xnfcalloc(sizeof(DisplayModeRec), 1);
memcpy((char*)pMode, (char*)p, sizeof(DisplayModeRec));
}
}
/*
* Check if there's a valid monitor mode that this one can be matched
* up with. The actual matching is done later.
*/
if (modeOK) {
if (modeOK && pMode == NULL) {
float vrefresh = 0.0f;
int i;
for (i=0;i<pScrn->monitor->nVrefresh;i++) {
for (vrefresh = pScrn->monitor->vrefresh[i].hi;
@ -447,7 +475,7 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
xf86ErrorFVerb(DEBUG_VERB,
" WinBSegment: 0x%x\n", mode->WinBSegment);
xf86ErrorFVerb(DEBUG_VERB,
" WinFuncPtr: 0x%x\n", mode->WinFuncPtr);
" WinFuncPtr: 0x%lx\n", mode->WinFuncPtr);
xf86ErrorFVerb(DEBUG_VERB,
" BytesPerScanline: %d\n", mode->BytesPerScanline);
xf86ErrorFVerb(DEBUG_VERB,
@ -490,7 +518,7 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
" DirectColorModeInfo: %d\n", mode->DirectColorModeInfo);
if (major >= 2) {
xf86ErrorFVerb(DEBUG_VERB,
" PhysBasePtr: 0x%x\n", mode->PhysBasePtr);
" PhysBasePtr: 0x%lx\n", mode->PhysBasePtr);
if (major >= 3) {
xf86ErrorFVerb(DEBUG_VERB,
" LinBytesPerScanLine: %d\n", mode->LinBytesPerScanLine);
@ -515,7 +543,7 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
xf86ErrorFVerb(DEBUG_VERB,
" LinRsvdFieldPosition: %d\n", mode->LinRsvdFieldPosition);
xf86ErrorFVerb(DEBUG_VERB,
" MaxPixelClock: %d\n", mode->MaxPixelClock);
" MaxPixelClock: %ld\n", mode->MaxPixelClock);
}
}
@ -549,18 +577,14 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
*/
DisplayModePtr
i830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe,
int modeTypes)
I830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe)
{
DisplayModePtr pMode, p = NULL, modePool = NULL;
int i = 0;
DisplayModePtr pMode, p = NULL, modePool = NULL;
int i = 0;
if (modeTypes & V_MODETYPE_VBE) {
while (vbe->VideoModePtr[i] != 0xffff) {
int id = vbe->VideoModePtr[i++];
if ((pMode = CheckMode(pScrn, pVbe, vbe, id, modeTypes)) != NULL) {
ModeStatus status = MODE_OK;
for (i = 0; i < 0x7F; i++) {
if ((pMode = CheckMode(pScrn, pVbe, vbe, i, V_MODETYPE_VGA)) != NULL) {
ModeStatus status = MODE_OK;
/* Check the mode against a specified virtual size (if any) */
if (pScrn->display->virtualX > 0 &&
@ -587,38 +611,6 @@ i830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe,
}
}
}
}
if (modeTypes & V_MODETYPE_VGA) {
for (i = 0; i < 0x7F; i++) {
if ((pMode = CheckMode(pScrn, pVbe, vbe, i, modeTypes)) != NULL) {
ModeStatus status = MODE_OK;
/* Check the mode against a specified virtual size (if any) */
if (pScrn->display->virtualX > 0 &&
pMode->HDisplay > pScrn->display->virtualX) {
status = MODE_VIRTUAL_X;
}
if (pScrn->display->virtualY > 0 &&
pMode->VDisplay > pScrn->display->virtualY) {
status = MODE_VIRTUAL_Y;
}
if (status != MODE_OK) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Not using mode \"%dx%d\" (%s)\n",
pMode->HDisplay, pMode->VDisplay,
xf86ModeStatusToString(status));
} else {
if (p == NULL) {
modePool = pMode;
} else {
p->next = pMode;
}
pMode->prev = NULL;
p = pMode;
}
}
}
}
return modePool;
}
@ -628,7 +620,7 @@ i830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe,
* VBE version 3.0 or later.
*/
void
i830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
I830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
{
DisplayModePtr pMode;
VbeModeInfoData *data;
@ -638,9 +630,6 @@ i830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
int clock;
data = (VbeModeInfoData*)pMode->Private;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Attempting to use %dHz refresh for mode \"%s\" (%x)\n",
(int)pMode->VRefresh, pMode->name, data->mode);
data->block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
data->block->HorizontalTotal = pMode->HTotal;
data->block->HorizontalSyncStart = pMode->HSyncStart;
@ -661,9 +650,11 @@ i830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
if (clock)
data->block->PixelClock = clock;
data->mode |= (1 << 11);
data->block->RefreshRate = ((double)(data->block->PixelClock) /
(double)(pMode->HTotal * pMode->VTotal)) * 100;
data->block->RefreshRate = i830refreshes[I830GetBestRefresh(pScrn, data->block->RefreshRate / 100)] * 100;
data->block->RefreshRate = (int)(((double)(data->block->PixelClock) /
(double)(pMode->HTotal * pMode->VTotal)) * 100);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Attempting to use %2.2fHz refresh for mode \"%s\" (%x)\n",
(float)(((double)(data->block->PixelClock) / (double)(pMode->HTotal * pMode->VTotal))), pMode->name, data->mode);
#ifdef DEBUG
ErrorF("Video Modeline: ID: 0x%x Name: %s %i %i %i %i - "
" %i %i %i %i %.2f MHz Refresh: %.2f Hz\n",
@ -678,7 +669,23 @@ i830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
}
void
i830PrintModes(ScrnInfoPtr scrp)
I830UnsetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
{
DisplayModePtr pMode;
VbeModeInfoData *data;
pMode = pScrn->modes;
do {
pMode = pMode->next;
data = (VbeModeInfoData*)pMode->Private;
xfree(data->block);
data->block = NULL;
} while (pMode != pScrn->modes);
}
void
I830PrintModes(ScrnInfoPtr scrp)
{
DisplayModePtr p;
float hsync, refresh = 0;