1 --- xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile.i945 2005-08-18 19:40:12.000000000 -0400
2 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/Imakefile 2005-08-18 19:40:24.000000000 -0400
6 I810SRCS = i810_cursor.c i810_accel.c i810_memory.c i810_wmark.c i810_dga.c \
7 - i810_video.c i810_io.c
8 + i810_video.c i810_io.c i830_modes.c
9 I810OBJS = i810_cursor.o i810_accel.o i810_memory.o i810_wmark.o i810_dga.o \
10 - i810_video.o i810_io.o
11 + i810_video.o i810_io.o i830_modes.o
13 I830SRCS = i830_driver.c i830_memory.c i830_cursor.c i830_accel.c i830_io.c \
14 - i830_dga.c $(I830SRCS1) $(I830SRCS2)
15 + i830_dga.c i830_shadow.c $(I830SRCS1) $(I830SRCS2)
16 I830OBJS = i830_driver.o i830_memory.o i830_cursor.o i830_accel.o i830_io.o \
17 - i830_dga.o $(I830OBJS1) $(I830OBJS2)
18 + i830_dga.o i830_shadow.o $(I830OBJS1) $(I830OBJS2)
20 SRCS = i810_driver.c \
21 $(I810SRCS) $(I830SRCS) $(DRISRCS)
23 InstallDriverSDKNonExecFile(i830_dri.h,$(DRIVERSDKDIR)/drivers/i810)
24 InstallDriverSDKNonExecFile(i830_driver.c,$(DRIVERSDKDIR)/drivers/i810)
25 InstallDriverSDKNonExecFile(i830_memory.c,$(DRIVERSDKDIR)/drivers/i810)
26 +InstallDriverSDKNonExecFile(i830_shadow.c,$(DRIVERSDKDIR)/drivers/i810)
27 InstallDriverSDKNonExecFile(i830_video.c,$(DRIVERSDKDIR)/drivers/i810)
29 InstallDriverSDKObjectModule(i810,$(DRIVERSDKMODULEDIR),drivers)
30 --- xc/programs/Xserver/hw/xfree86/drivers/i810/common.h.i945 2005-08-18 19:40:12.000000000 -0400
31 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/common.h 2005-08-18 19:40:24.000000000 -0400
33 /**************************************************************************
35 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
36 -Copyright © 2002 David Dawes
37 +Copyright © 2002 David Dawes
42 extern const char *I810ddcSymbols[];
43 extern const char *I810fbSymbols[];
44 extern const char *I810xaaSymbols[];
45 +extern const char *I810shadowFBSymbols[];
47 extern const char *I810driSymbols[];
48 extern const char *I810drmSymbols[];
50 #define PCI_CHIP_I915_G_BRIDGE 0x2580
53 +#ifndef PCI_CHIP_I915_GM
54 +#define PCI_CHIP_I915_GM 0x2592
55 +#define PCI_CHIP_I915_GM_BRIDGE 0x2590
58 +#ifndef PCI_CHIP_E7221_G
59 +#define PCI_CHIP_E7221_G 0x258A
60 +/* Same as I915_G_BRIDGE */
61 +#define PCI_CHIP_E7221_G_BRIDGE 0x2580
64 +#ifndef PCI_CHIP_I945_G
65 +#define PCI_CHIP_I945_G 0x2772
66 +#define PCI_CHIP_I945_G_BRIDGE 0x2770
69 #define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 || \
70 pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \
71 pI810->PciInfo->chipType == PCI_CHIP_I810_E)
73 #define IS_I830(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I830_M)
74 #define IS_845G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_845_G)
75 #define IS_I85X(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I855_GM)
76 +#define IS_I852(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME))
77 +#define IS_I855(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME))
78 #define IS_I865G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I865_G)
79 -#define IS_I915G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_G)
80 +#define IS_I915G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_G || pI810->PciInfo->chipType == PCI_CHIP_E7221_G)
81 +#define IS_I915GM(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_GM)
82 +#define IS_I945G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I945_G)
84 -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810))
85 +#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810))
87 #define GTT_PAGE_SIZE KB(4)
88 #define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y))
89 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i810.man.i945 2005-08-18 19:40:12.000000000 -0400
90 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i810.man 2005-08-18 19:40:24.000000000 -0400
92 .SH SUPPORTED HARDWARE
94 supports the i810, i810-DC100, i810e, i815, 830M, 845G, 852GM, 855GM,
95 -865G and 915G chipsets.
96 +865G, 915G and 915GM chipsets.
98 .SH CONFIGURATION DETAILS
99 Please refer to __xconfigfile__(__filemansuffix__) for general configuration
101 the machine has booted, but unfortunately it doesn't always work and
102 is extremely dependent upon the Video BIOS.
105 +.BI "Option \*qRotate\*q \*qCW\*q"
107 +.BI "Option \*qRotate\*q \*qCCW\*q"
108 +Rotate the desktop 90 degrees clockwise or counterclockwise. This option
109 +forces the ShadowFB option on, and disables acceleration.
110 +Default: no rotation.
112 +.BI "Option \*qShadowFB\*q \*q" boolean \*q
113 +Enable or disable use of the shadow framebuffer layer. This option
114 +disables acceleration. Default: off.
117 __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
119 Jeff Hartmann, Mark Vojkovich, Alan Hourihane, H. J. Lu. 830M and 845G
120 support reworked for XFree86 4.3 by David Dawes and Keith Whitwell.
121 852GM, 855GM, and 865G support added by David Dawes and Keith Whitwell.
122 -915G support added by Alan Hourihane and Keith Whitwell.
123 +915G and 915GM support added by Alan Hourihane and Keith Whitwell.
124 Dual Head, Clone and lid status support added by Alan Hourihane.
125 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c.i945 2005-08-18 19:40:12.000000000 -0400
126 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c 2005-08-18 19:40:24.000000000 -0400
129 /* VT switching tries to do this.
131 - if ((!pI810->LockHeld && pI810->directRenderingEnabled) || !pScrn->vtSema) {
132 + if (!pI810->LockHeld && pI810->directRenderingEnabled) {
136 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c.i945 2005-08-18 19:40:12.000000000 -0400
137 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c 2005-08-18 19:40:24.000000000 -0400
138 @@ -1498,10 +1498,10 @@
141 if (pI810->cursorARGBHandle != 0)
142 - if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorARGBHandle) != 0) {
143 - xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno));
146 + if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorARGBHandle) != 0) {
147 + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno));
150 if (pI810->agpAcquired == TRUE)
151 drmAgpRelease(pI810->drmSubFD);
152 pI810->agpAcquired = FALSE;
153 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h.i945 2005-08-18 19:40:12.000000000 -0400
154 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h 2005-08-18 19:40:24.000000000 -0400
159 -#include "xf86dri.h"
161 #include "i810_common.h"
163 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c.i945 2005-08-18 19:40:12.000000000 -0400
164 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c 2005-08-18 19:40:24.000000000 -0400
167 #include "miscstruct.h"
170 +#include <X11/extensions/Xv.h>
175 {PCI_CHIP_I855_GM, "852GM/855GM"},
176 {PCI_CHIP_I865_G, "865G"},
177 {PCI_CHIP_I915_G, "915G"},
178 + {PCI_CHIP_E7221_G, "E7221 (i915)"},
179 + {PCI_CHIP_I915_GM, "915GM"},
180 + {PCI_CHIP_I945_G, "945G"},
185 {PCI_CHIP_I855_GM, PCI_CHIP_I855_GM, RES_SHARED_VGA},
186 {PCI_CHIP_I865_G, PCI_CHIP_I865_G, RES_SHARED_VGA},
187 {PCI_CHIP_I915_G, PCI_CHIP_I915_G, RES_SHARED_VGA},
188 + {PCI_CHIP_E7221_G, PCI_CHIP_E7221_G, RES_SHARED_VGA},
189 + {PCI_CHIP_I915_GM, PCI_CHIP_I915_GM, RES_SHARED_VGA},
190 + {PCI_CHIP_I945_G, PCI_CHIP_I945_G, RES_SHARED_VGA},
191 {-1, -1, RES_UNDEFINED }
198 +const char *I810shadowFBSymbols[] = {
204 const char *I810drmSymbols[] = {
212 -static const char *driShadowFBSymbols[] = {
217 const char *I810shadowSymbols[] = {
226 -#endif /* I830_ONLY */
235 - driShadowFBSymbols,
236 + I810shadowFBSymbols,
238 I810vbeSymbols, vbeOptionalSymbols,
239 I810ddcSymbols, I810int10Symbols, NULL);
241 case PCI_CHIP_I830_M:
242 case PCI_CHIP_I855_GM:
243 case PCI_CHIP_I915_G:
244 + case PCI_CHIP_E7221_G:
245 + case PCI_CHIP_I915_GM:
246 + case PCI_CHIP_I945_G:
247 xf86SetEntitySharable(usedChips[i]);
249 /* Allocate an entity private if necessary */
250 @@ -1080,7 +1088,7 @@
251 "Couldn't load shadowfb module:\n");
254 - xf86LoaderReqSymLists(driShadowFBSymbols, NULL);
255 + xf86LoaderReqSymLists(I810shadowFBSymbols, NULL);
259 @@ -1729,6 +1737,21 @@
260 i810Reg->ExtHorizBlank = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x40) >> 6;
263 + * the KGA fix in vgaHW.c results in the first
264 + * scanline and the first character clock (8 pixels)
265 + * of each scanline thereafter on display with an i810
266 + * to be blank. Restoring CRTC 3, 5, & 22 to their
267 + * "theoretical" values corrects the problem. KAO.
269 + pVga->CRTC[3] = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
270 + pVga->CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2)
271 + | (((mode->CrtcHSyncEnd >> 3)) & 0x1F);
272 + pVga->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
274 + i810Reg->ExtHorizBlank = vgaHWHBlankKGA(mode, pVga, 7, 0);
275 + vgaHWVBlankKGA(mode, pVga, 8, 0);
278 * The following workarounds are needed to get video overlay working
279 * at 1024x768 and 1280x1024 display resolutions.
281 @@ -1787,7 +1810,6 @@
287 hwp = VGAHWPTR(pScrn);
288 pI810 = I810PTR(pScrn);
289 @@ -1796,18 +1818,6 @@
291 if (!vgaHWInit(pScrn, mode))
294 - * the KGA fix in vgaHW.c results in the first
295 - * scanline and the first character clock (8 pixels)
296 - * of each scanline thereafter on display with an i810
297 - * to be blank. Restoring CRTC 3, 5, & 22 to their
298 - * "theoretical" values corrects the problem. KAO.
300 - pVga = &VGAHWPTR(pScrn)->ModeReg;
301 - pVga->CRTC[3] = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
302 - pVga->CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2)
303 - | (((mode->CrtcHSyncEnd >> 3)) & 0x1F);
304 - pVga->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
306 pScrn->vtSema = TRUE;
308 @@ -2097,8 +2107,8 @@
312 - * Setup DRI after visuals have been established, but before cfbScreenInit
313 - * is called. cfbScreenInit will eventually call into the drivers
314 + * Setup DRI after visuals have been established, but before fbScreenInit
315 + * is called. fbScreenInit will eventually call into the drivers
316 * InitGLXVisuals call back.
319 @@ -2241,7 +2251,7 @@
322 if (pI810->directRenderingEnabled) {
323 - /* Now that mi, cfb, drm and others have done their thing,
324 + /* Now that mi, fb, drm and others have done their thing,
325 * complete the DRI setup.
327 pI810->directRenderingEnabled = I810DRIFinishScreenInit(pScreen);
328 @@ -2255,9 +2265,9 @@
331 if (pI810->directRenderingEnabled) {
332 - xf86DrvMsg(pScrn->scrnIndex, driFrom, "Direct rendering enabled\n");
333 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
335 - xf86DrvMsg(pScrn->scrnIndex, driFrom, "Direct rendering disabled\n");
336 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Direct rendering disabled\n");
339 pScreen->SaveScreen = I810SaveScreen;
340 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i810_hwmc.c.i945 2005-08-18 19:40:12.000000000 -0400
341 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i810_hwmc.c 2005-08-18 19:40:24.000000000 -0400
345 #include "xf86xvmc.h"
348 +#include <X11/extensions/Xv.h>
349 +#include <X11/extensions/XvMC.h>
351 #include "xaalocal.h"
352 #include "dixstruct.h"
353 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i830.h.i945 2005-08-18 19:40:12.000000000 -0400
354 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i830.h 2005-08-18 19:40:24.000000000 -0400
358 * The mode handling is based upon the VESA driver written by
359 - * Paulo César Pereira de Andrade <pcpa@conectiva.com.br>.
360 + * Paulo César Pereira de Andrade <pcpa@conectiva.com.br>.
363 #define PIPE_NONE 0<<0
365 typedef struct _VESARec {
367 pointer state, pstate;
368 - int statePage, stateSize, stateMode;
369 + int statePage, stateSize, stateMode, stateRefresh;
371 int savedScanlinePitch;
373 @@ -165,13 +165,17 @@
386 I830EntPtr entityPrivate;
388 + int pipe, origPipe;
391 unsigned int bufferOffset; /* for I830SelectBuffer */
396 + Bool specifiedMonitor;
401 drm_handle_t ring_map;
404 + /* Broken-out options. */
405 OptionInfoPtr Options;
409 + /* Support for shadowFB and rotation. */
410 + unsigned char *shadowPtr;
412 + void (*PointerMoved)(int, int, int);
414 /* Stolen memory support */
416 @@ -320,10 +333,11 @@
417 /* Use BIOS call 0x5f05 to set the refresh rate. */
418 Bool useExtendedRefresh;
423 int operatingDevices;
425 + int lastDevice1, lastDevice2;
427 /* These are indexed by the display types */
428 Bool displayAttached[NumDisplayTypes];
435 /* fbOffset converted to (x, y). */
441 - OsTimerPtr lidTimer;
442 + OsTimerPtr devicesTimer;
445 #define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
447 extern void I830SetupMemoryTiling(ScrnInfoPtr pScrn);
448 extern Bool I830DRIScreenInit(ScreenPtr pScreen);
449 extern Bool I830DRIDoMappings(ScreenPtr pScreen);
450 +extern Bool I830DRIResume(ScreenPtr pScreen);
451 extern void I830DRICloseScreen(ScreenPtr pScreen);
452 extern Bool I830DRIFinishScreenInit(ScreenPtr pScreen);
454 @@ -423,13 +439,27 @@
456 extern void I830ChangeFrontbuffer(ScrnInfoPtr pScrn,int buffer);
458 +extern DisplayModePtr I830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe,
459 + VbeInfoBlock *vbe);
460 +extern void I830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe);
461 +extern void I830UnsetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe);
462 +extern void I830PrintModes(ScrnInfoPtr pScrn);
463 +extern int I830GetBestRefresh(ScrnInfoPtr pScrn, int refresh);
464 +extern Bool I830CheckModeSupport(ScrnInfoPtr pScrn, int x, int y, int mode);
465 +extern void I830PointerMoved(int index, int x, int y);
466 +extern void I830RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
467 +extern void I830RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
468 +extern void I830RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
469 +extern void I830RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
470 +extern void I830RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
473 * 12288 is set as the maximum, chosen because it is enough for
474 * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare.
476 #define I830_MAXIMUM_VBIOS_MEM 12288
477 -#define I830_DEFAULT_VIDEOMEM_2D (MB(8) / 1024)
478 -#define I830_DEFAULT_VIDEOMEM_3D (MB(32) / 1024)
479 +#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024)
480 +#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024)
482 /* Flags for memory allocation function */
483 #define FROM_ANYWHERE 0x00000000
484 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h.i945 2005-08-18 19:40:12.000000000 -0400
485 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h 2005-08-18 19:40:24.000000000 -0400
489 I830_INIT_DMA = 0x01,
490 - I830_CLEANUP_DMA = 0x02
491 + I830_CLEANUP_DMA = 0x02,
492 + I830_RESUME_DMA = 0x03
494 unsigned int mmio_offset;
495 int sarea_priv_offset;
496 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i830_cursor.c.i945 2005-08-18 19:40:12.000000000 -0400
497 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i830_cursor.c 2005-08-18 19:40:24.000000000 -0400
499 /**************************************************************************
501 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
502 -Copyright © 2002 David Dawes
503 +Copyright © 2002 David Dawes
506 Permission is hereby granted, free of charge, to any person obtaining a
509 DPRINTF(PFX, "I830InitHWCursor\n");
510 /* Initialise the HW cursor registers, leaving the cursor hidden. */
511 - if (IS_MOBILE(pI830) || IS_I915G(pI830)) {
512 + if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830)) {
513 temp = INREG(CURSOR_A_CONTROL);
514 temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_MEM_TYPE_LOCAL |
515 MCURSOR_PIPE_SELECT);
519 /* have to upload the base for the new position */
520 - if (IS_I915G(pI830)) {
521 + if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
522 if (pI830->CursorIsARGB)
523 OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
526 pI830->CursorMemARGB->Physical, pI830->CursorMemARGB->Start);
528 pI830->cursorOn = TRUE;
529 - if (IS_MOBILE(pI830) || IS_I915G(pI830)) {
530 + if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830)) {
531 temp = INREG(CURSOR_A_CONTROL);
532 temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
533 if (pI830->CursorIsARGB)
535 DPRINTF(PFX, "I830HideCursor\n");
537 pI830->cursorOn = FALSE;
538 - if (IS_MOBILE(pI830) || IS_I915G(pI830)) {
539 + if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830)) {
540 temp = INREG(CURSOR_A_CONTROL);
541 temp &= ~CURSOR_MODE;
542 temp |= CURSOR_MODE_DISABLE;
543 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c.i945 2005-08-18 19:40:12.000000000 -0400
544 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.c 2005-08-18 19:40:24.000000000 -0400
546 /**************************************************************************
548 Copyright 2001 VA Linux Systems Inc., Fremont, California.
549 -Copyright © 2002 by David Dawes
550 +Copyright © 2002 by David Dawes
558 +I830ResumeDma(ScrnInfoPtr pScrn)
560 + I830Ptr pI830 = I830PTR(pScrn);
563 + memset(&info, 0, sizeof(drmI830Init));
564 + info.func = I830_RESUME_DMA;
566 + if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT,
567 + &info, sizeof(drmI830Init))) {
568 + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830 Dma Resume Failed\n");
576 I830SetParam(ScrnInfoPtr pScrn, int param, int value)
578 I830Ptr pI830 = I830PTR(pScrn);
583 - /* Check the i830 DRM versioning */
584 + /* Check the i915 DRM versioning */
586 drmVersionPtr version;
588 @@ -568,10 +586,18 @@
589 drmFreeVersion(version);
592 + if (strncmp(version->name, I830KernelDriverName, strlen(I830KernelDriverName))) {
593 + xf86DrvMsg(pScreen->myNum, X_WARNING,
594 + "i830 Kernel module detected, Use the i915 Kernel module instead, aborting DRI init.\n");
595 + I830DRICloseScreen(pScreen);
596 + drmFreeVersion(version);
599 pI830->drmMinor = version->version_minor;
600 drmFreeVersion(version);
608 xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] textures = 0x%08lx\n",
611 - I830InitDma(pScrn);
612 + if (!I830InitDma(pScrn)) {
613 + DRICloseScreen(pScreen);
617 if (pI830->PciInfo->chipType != PCI_CHIP_845_G &&
618 pI830->PciInfo->chipType != PCI_CHIP_I830_M) {
624 +I830DRIResume(ScreenPtr pScreen)
626 + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
627 + I830Ptr pI830 = I830PTR(pScrn);
628 + I830DRIPtr pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate;
630 + DPRINTF(PFX, "I830DRIResume\n");
632 + I830ResumeDma(pScrn);
635 + pI830DRI->irq = drmGetInterruptFromBusID(pI830->drmSubFD,
636 + ((pciConfigPtr) pI830->
637 + PciInfo->thisCard)->busnum,
638 + ((pciConfigPtr) pI830->
639 + PciInfo->thisCard)->devnum,
640 + ((pciConfigPtr) pI830->
641 + PciInfo->thisCard)->funcnum);
643 + if (drmCtlInstHandler(pI830->drmSubFD, pI830DRI->irq)) {
644 + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
645 + "[drm] failure adding irq handler\n");
650 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
651 + "[drm] dma control initialized, using IRQ %d\n",
659 I830DRICloseScreen(ScreenPtr pScreen)
661 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c.i945 2005-08-18 19:40:12.000000000 -0400
662 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c 2005-08-18 19:40:24.000000000 -0400
664 /**************************************************************************
666 Copyright 2001 VA Linux Systems Inc., Fremont, California.
667 -Copyright © 2002 by David Dawes
668 +Copyright © 2002 by David Dawes
675 * Mode handling is based on the VESA driver written by:
676 - * Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
677 + * Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
681 @@ -160,11 +160,12 @@
683 #include "mipointer.h"
685 +#include "shadowfb.h"
688 #include "miscstruct.h"
691 +#include <X11/extensions/Xv.h>
693 #include "vbeModes.h"
696 {PCI_CHIP_I855_GM, "852GM/855GM"},
697 {PCI_CHIP_I865_G, "865G"},
698 {PCI_CHIP_I915_G, "915G"},
699 + {PCI_CHIP_E7221_G, "E7221 (i915)"},
700 + {PCI_CHIP_I915_GM, "915GM"},
701 + {PCI_CHIP_I945_G, "945G"},
706 {PCI_CHIP_I855_GM, PCI_CHIP_I855_GM, RES_SHARED_VGA},
707 {PCI_CHIP_I865_G, PCI_CHIP_I865_G, RES_SHARED_VGA},
708 {PCI_CHIP_I915_G, PCI_CHIP_I915_G, RES_SHARED_VGA},
709 + {PCI_CHIP_E7221_G, PCI_CHIP_E7221_G, RES_SHARED_VGA},
710 + {PCI_CHIP_I915_GM, PCI_CHIP_I915_GM, RES_SHARED_VGA},
711 + {PCI_CHIP_I945_G, PCI_CHIP_I945_G, RES_SHARED_VGA},
712 {-1, -1, RES_UNDEFINED}
716 OPTION_MONITOR_LAYOUT,
718 OPTION_CLONE_REFRESH,
720 - OPTION_FLIP_PRIMARY
721 + OPTION_CHECKDEVICES,
727 static OptionInfoRec I830BIOSOptions[] = {
729 {OPTION_MONITOR_LAYOUT, "MonitorLayout", OPTV_ANYSTR,{0}, FALSE},
730 {OPTION_CLONE, "Clone", OPTV_BOOLEAN, {0}, FALSE},
731 {OPTION_CLONE_REFRESH,"CloneRefresh",OPTV_INTEGER, {0}, FALSE},
732 - {OPTION_CHECKLID, "CheckLid", OPTV_BOOLEAN, {0}, FALSE},
733 - {OPTION_FLIP_PRIMARY,"FlipPrimary", OPTV_BOOLEAN, {0}, FALSE},
734 + {OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN, {0}, FALSE},
735 + {OPTION_FIXEDPIPE, "FixedPipe", OPTV_ANYSTR, {0}, FALSE},
736 + {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE},
737 + {OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE},
738 {-1, NULL, OPTV_NONE, {0}, FALSE}
742 static Bool I830BIOSEnterVT(int scrnIndex, int flags);
743 static Bool I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode,
744 VbeCRTCInfoBlock *block);
745 -static CARD32 I830LidTimer(OsTimerPtr timer, CARD32 now, pointer arg);
746 +static CARD32 I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg);
747 static Bool SetPipeAccess(ScrnInfoPtr pScrn);
748 static Bool IsPrimary(ScrnInfoPtr pScrn);
750 @@ -363,11 +374,14 @@
751 ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
754 -/* Various extended video BIOS functions. */
755 -static const int refreshes[] = {
756 - 43, 56, 60, 70, 72, 75, 85, 100, 120
757 +/* Various extended video BIOS functions.
758 + * 100 and 120Hz aren't really supported, they work but only get close
759 + * to the requested refresh, and really not close enough.
760 + * I've seen 100Hz come out at 104Hz, and 120Hz come out at 128Hz */
761 +const int i830refreshes[] = {
762 + 43, 56, 60, 70, 72, 75, 85 /* 100, 120 */
764 -static const int nrefreshes = sizeof(refreshes) / sizeof(refreshes[0]);
765 +static const int nrefreshes = sizeof(i830refreshes) / sizeof(i830refreshes[0]);
768 Check5fStatus(ScrnInfoPtr pScrn, int func, int ax)
775 +GetToggleList(ScrnInfoPtr pScrn, int toggle)
777 + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
779 + DPRINTF(PFX, "GetToggleList\n");
781 + pVbe->pInt10->num = 0x10;
782 + pVbe->pInt10->ax = 0x5f64;
783 + pVbe->pInt10->bx = 0x500;
785 + pVbe->pInt10->bx |= toggle;
787 + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
788 + if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
789 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Toggle (%d) 0x%x\n", toggle, pVbe->pInt10->cx);
790 + return pVbe->pInt10->cx & 0xffff;
797 BitToRefresh(int bits)
799 @@ -398,12 +433,12 @@
801 for (i = 0; i < nrefreshes; i++)
803 - return refreshes[i];
804 + return i830refreshes[i];
809 -GetRefreshRate(ScrnInfoPtr pScrn, int mode, int refresh, int *availRefresh)
810 +GetRefreshRate(ScrnInfoPtr pScrn, int mode, int *availRefresh)
812 vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
818 - SetPipeAccess(pScrn);
820 pVbe->pInt10->num = 0x10;
821 pVbe->pInt10->ax = 0x5f05;
822 pVbe->pInt10->bx = (mode & 0xff) | 0x100;
823 @@ -427,48 +460,181 @@
830 -SetRefreshRate(ScrnInfoPtr pScrn, int mode, int refresh)
839 + int rsvdoffscrnmemsize;
840 + int rsvdoffscrnmemptr;
845 +I830InterpretPanelID(int scrnIndex, unsigned char *tmp)
848 - vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
849 + ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
850 + struct panelid *block = (struct panelid *)tmp;
852 - DPRINTF(PFX, "SetRefreshRate: mode 0x%x, refresh: %d\n", mode, refresh);
853 +#define PANEL_DEFAULT_HZ 60
855 - /* Only 8-bit mode numbers are supported. */
858 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
859 + "PanelID returned panel resolution : %dx%d\n",
860 + block->hsize, block->vsize);
862 - pVbe->pInt10->num = 0x10;
863 - pVbe->pInt10->ax = 0x5f05;
864 - pVbe->pInt10->bx = mode & 0xff;
865 + /* If we get bogus values from this, don't accept it */
866 + if (block->hsize == 0 || block->vsize == 0) {
867 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
868 + "Bad Panel resolution - ignoring panelID\n");
873 + /* If we have monitor timings then don't overwrite them */
874 + if (pScrn->monitor->nHsync > 0 &&
875 + pScrn->monitor->nVrefresh > 0)
878 + /* With panels, we're always assuming a refresh of 60Hz */
880 + pScrn->monitor->nHsync = 1;
881 + pScrn->monitor->nVrefresh = 1;
883 + /* Give a little tolerance for the selected panel */
884 + pScrn->monitor->hsync[0].lo = (float)((PANEL_DEFAULT_HZ/1.05)*block->vsize)/1000;
885 + pScrn->monitor->hsync[0].hi = (float)((PANEL_DEFAULT_HZ/0.95)*block->vsize)/1000;
886 + pScrn->monitor->vrefresh[0].lo = (float)PANEL_DEFAULT_HZ;
887 + pScrn->monitor->vrefresh[0].hi = (float)PANEL_DEFAULT_HZ;
890 +/* This should probably go into the VBE layer */
891 +static unsigned char *
892 +vbeReadPanelID(vbeInfoPtr pVbe)
894 + int RealOff = pVbe->real_mode_base;
895 + pointer page = pVbe->memory;
896 + unsigned char *tmp = NULL;
897 + int screen = pVbe->pInt10->scrnIndex;
899 + pVbe->pInt10->ax = 0x4F11;
900 + pVbe->pInt10->bx = 0x01;
901 + pVbe->pInt10->cx = 0;
902 + pVbe->pInt10->dx = 0;
903 + pVbe->pInt10->es = SEG_ADDR(RealOff);
904 + pVbe->pInt10->di = SEG_OFF(RealOff);
905 + pVbe->pInt10->num = 0x10;
907 + xf86ExecX86int10(pVbe->pInt10);
909 + if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
910 + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID invalid\n");
913 + switch (pVbe->pInt10->ax & 0xff00) {
915 + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read successfully\n");
916 + tmp = (unsigned char *)xnfalloc(32);
917 + memcpy(tmp,page,32);
920 + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read failed\n");
923 + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID unknown failure %i\n",
924 + pVbe->pInt10->ax & 0xff00);
933 +vbeDoPanelID(vbeInfoPtr pVbe)
935 + unsigned char *PanelID_data;
939 + PanelID_data = vbeReadPanelID(pVbe);
944 + I830InterpretPanelID(pVbe->pInt10->scrnIndex, PanelID_data);
948 +I830GetBestRefresh(ScrnInfoPtr pScrn, int refresh)
952 for (i = nrefreshes - 1; i >= 0; i--) {
954 * Look for the highest value that the requested (refresh + 2) is
955 * greater than or equal to.
957 - if (refreshes[i] <= (refresh + 2))
958 + if (i830refreshes[i] <= (refresh + 2))
961 /* i can be 0 if the requested refresh was higher than the max. */
963 - if (refresh >= refreshes[nrefreshes - 1])
964 + if (refresh >= i830refreshes[nrefreshes - 1])
972 +SetRefreshRate(ScrnInfoPtr pScrn, int mode, int refresh)
974 + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
975 + int i = I830GetBestRefresh(pScrn, refresh);
977 + DPRINTF(PFX, "SetRefreshRate: mode 0x%x, refresh: %d\n", mode, refresh);
979 DPRINTF(PFX, "Setting refresh rate to %dHz for mode 0x%02x\n",
980 - refreshes[i], mode & 0xff);
981 + i830refreshes[i], mode & 0xff);
983 + /* Only 8-bit mode numbers are supported. */
987 + pVbe->pInt10->num = 0x10;
988 + pVbe->pInt10->ax = 0x5f05;
989 + pVbe->pInt10->bx = mode & 0xff;
991 pVbe->pInt10->cx = 1 << i;
992 xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
993 if (Check5fStatus(pScrn, 0x5f05, pVbe->pInt10->ax))
994 - return refreshes[i];
995 + return i830refreshes[i];
1001 +SetPowerStatus(ScrnInfoPtr pScrn, int mode)
1003 + vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
1005 + pVbe->pInt10->num = 0x10;
1006 + pVbe->pInt10->ax = 0x5f64;
1007 + pVbe->pInt10->bx = 0x0800 | mode;
1008 + pVbe->pInt10->cx = 0x0000;
1010 + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
1011 + if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))
1018 GetModeSupport(ScrnInfoPtr pScrn, int modePipeA, int modePipeB,
1019 int devicesPipeA, int devicesPipeB, int *maxBandwidth,
1020 int *bandwidthPipeA, int *bandwidthPipeB)
1023 /* Only 8-bit mode numbers are supported. */
1024 if ((modePipeA & 0x100) || (modePipeB & 0x100))
1028 pVbe->pInt10->num = 0x10;
1029 pVbe->pInt10->ax = 0x5f28;
1030 @@ -575,55 +741,144 @@
1031 pVbe->pInt10->bx = 0x100;
1033 xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
1034 - if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))
1035 + if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
1036 return pVbe->pInt10->cx & 0xffff;
1040 + if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G) /* FIXED CONFIG */
1047 -/* This is needed for SetDisplayDevices to work correctly on I915G
1048 - * and possibly later Video BIOS builds around 3272 (but not sure here).
1049 - * So enable for all chipsets now as it has no bad side effects, apart
1050 - * from slightly longer startup time.
1052 -#define I915G_WORKAROUND
1054 +GetBIOSPipe(ScrnInfoPtr pScrn)
1056 + I830Ptr pI830 = I830PTR(pScrn);
1057 + vbeInfoPtr pVbe = pI830->pVbe;
1060 + DPRINTF(PFX, "GetBIOSPipe:\n");
1062 + /* single pipe machines should always return Pipe A */
1063 + if (pI830->availablePipes == 1) return 0;
1065 + pVbe->pInt10->num = 0x10;
1066 + pVbe->pInt10->ax = 0x5f1c;
1067 + pVbe->pInt10->bx = 0x100;
1069 + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
1070 + if (Check5fStatus(pScrn, 0x5f1c, pVbe->pInt10->ax)) {
1071 + if (pI830->newPipeSwitch) {
1072 + pipe = ((pVbe->pInt10->bx & 0x0001));
1074 + pipe = ((pVbe->pInt10->cx & 0x0100) >> 8);
1079 + /* failed, assume pipe A */
1084 -SetDisplayDevices(ScrnInfoPtr pScrn, int devices)
1085 +SetBIOSPipe(ScrnInfoPtr pScrn, int pipe)
1087 I830Ptr pI830 = I830PTR(pScrn);
1088 vbeInfoPtr pVbe = pI830->pVbe;
1091 -#ifdef I915G_WORKAROUND
1094 + DPRINTF(PFX, "SetBIOSPipe: pipe 0x%x\n", pipe);
1096 + /* single pipe machines should always return TRUE */
1097 + if (pI830->availablePipes == 1) return TRUE;
1099 + pVbe->pInt10->num = 0x10;
1100 + pVbe->pInt10->ax = 0x5f1c;
1101 + if (pI830->newPipeSwitch) {
1102 + pVbe->pInt10->bx = pipe;
1103 + pVbe->pInt10->cx = 0;
1105 + pVbe->pInt10->bx = 0x0;
1106 + pVbe->pInt10->cx = pipe << 8;
1109 + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
1110 + if (Check5fStatus(pScrn, 0x5f1c, pVbe->pInt10->ax)) {
1118 +SetPipeAccess(ScrnInfoPtr pScrn)
1120 + I830Ptr pI830 = I830PTR(pScrn);
1122 + /* Don't try messing with the pipe, unless we're dual head */
1123 + if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone || pI830->origPipe != pI830->pipe) {
1124 + if (!SetBIOSPipe(pScrn, pI830->pipe))
1132 +I830Set640x480(ScrnInfoPtr pScrn)
1134 + I830Ptr pI830 = I830PTR(pScrn);
1135 + int m = 0x30; /* 640x480 8bpp */
1137 switch (pScrn->depth) {
1160 - mode |= (1 << 15) | (1 << 14);
1161 + m |= (1 << 15) | (1 << 14);
1162 + return VBESetVBEMode(pI830->pVbe, m, NULL);
1165 +/* This is needed for SetDisplayDevices to work correctly on I915G.
1166 + * Enable for all chipsets now as it has no bad side effects, apart
1167 + * from slightly longer startup time.
1169 +#define I915G_WORKAROUND
1172 +SetDisplayDevices(ScrnInfoPtr pScrn, int devices)
1174 + I830Ptr pI830 = I830PTR(pScrn);
1175 + vbeInfoPtr pVbe = pI830->pVbe;
1177 + int singlepipe = 0;
1178 +#ifdef I915G_WORKAROUND
1180 + Bool setmode = FALSE;
1183 DPRINTF(PFX, "SetDisplayDevices: devices 0x%x\n", devices);
1185 + if (!pI830->specifiedMonitor)
1188 #ifdef I915G_WORKAROUND
1189 - if (pI830->bios_version >= 3272) {
1190 - VBEGetVBEMode(pVbe, &getmode);
1191 - I830VESASetVBEMode(pScrn, mode, NULL);
1192 + if (pI830->preinit)
1194 + if (pI830->leaving)
1196 + if (pI830->closing)
1200 + VBEGetVBEMode(pVbe, &getmode1);
1201 + I830Set640x480(pScrn);
1205 @@ -635,28 +890,146 @@
1206 xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
1207 if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
1208 #ifdef I915G_WORKAROUND
1209 - if (pI830->bios_version >= 3272)
1210 - I830VESASetVBEMode(pScrn, getmode, NULL);
1212 + VBESetVBEMode(pI830->pVbe, getmode1 | 1<<15, NULL);
1215 + pI830->pipeEnabled[0] = (devices & 0xff) ? TRUE : FALSE;
1216 + pI830->pipeEnabled[1] = (devices & 0xff00) ? TRUE : FALSE;
1221 #ifdef I915G_WORKAROUND
1222 - if (pI830->bios_version >= 3272)
1223 - I830VESASetVBEMode(pScrn, getmode, NULL);
1225 + VBESetVBEMode(pI830->pVbe, getmode1 | 1<<15, NULL);
1228 - xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1229 - "SetDisplayDevices call failed, writing config directly to SWF0.\n");
1230 + if (devices & 0xff) {
1231 + pVbe->pInt10->num = 0x10;
1232 + pVbe->pInt10->ax = 0x5f64;
1233 + pVbe->pInt10->bx = 0x1;
1234 + pVbe->pInt10->cx = devices & 0xff;
1236 + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
1237 + if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
1238 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1239 + "Successfully set display devices to 0x%x.\n",devices & 0xff);
1240 + singlepipe = devices & 0xff00; /* set alternate */
1242 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1243 + "Failed to set display devices to 0x%x.\n",devices & 0xff);
1244 + singlepipe = devices;
1247 + singlepipe = devices;
1249 + if (singlepipe == devices && devices & 0xff00) {
1250 + pVbe->pInt10->num = 0x10;
1251 + pVbe->pInt10->ax = 0x5f64;
1252 + pVbe->pInt10->bx = 0x1;
1253 + pVbe->pInt10->cx = devices & 0xff00;
1255 + xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
1256 + if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
1257 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1258 + "Successfully set display devices to 0x%x.\n",devices & 0xff00);
1259 + singlepipe = devices & 0xff; /* set alternate */
1261 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1262 + "Failed to set display devices to 0x%x.\n",devices & 0xff00);
1263 + singlepipe = devices;
1267 + /* LVDS doesn't exist on these */
1268 + if (IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830))
1269 + singlepipe &= ~(PIPE_LFP | (PIPE_LFP<<8));
1271 + if (pI830->availablePipes == 1)
1272 + singlepipe &= 0xFF;
1274 + /* Disable LVDS */
1275 + if (singlepipe & PIPE_LFP) {
1276 + /* LFP on PipeA is unlikely! */
1277 + OUTREG(0x61200, INREG(0x61200) & ~0x80000000);
1278 + OUTREG(0x61204, INREG(0x61204) & ~0x00000001);
1279 + while ((INREG(0x61200) & 0x80000000) || (INREG(0x61204) & 1));
1281 + OUTREG(LVDS, (INREG(LVDS) & ~1<<30) | 0x80000300);
1283 + OUTREG(0x61200, INREG(0x61200) | 0x80000000);
1284 + OUTREG(0x61204, INREG(0x61204) | 0x00000001);
1285 + while (!(INREG(0x61200) & 0x80000000) && !(INREG(0x61204) & 1));
1286 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1287 + "Enabling LVDS directly. Pipe A.\n");
1289 + if (singlepipe & (PIPE_LFP << 8)) {
1290 + OUTREG(0x61200, INREG(0x61200) & ~0x80000000);
1291 + OUTREG(0x61204, INREG(0x61204) & ~0x00000001);
1292 + while ((INREG(0x61200) & 0x80000000) || (INREG(0x61204) & 1));
1294 + OUTREG(LVDS, (INREG(LVDS) | 1<<30) | 0x80000300);
1296 + OUTREG(0x61200, INREG(0x61200) | 0x80000000);
1297 + OUTREG(0x61204, INREG(0x61204) | 0x00000001);
1298 + while (!(INREG(0x61200) & 0x80000000) && !(INREG(0x61204) & 1));
1299 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1300 + "Enabling LVDS directly. Pipe B.\n");
1302 + else if (!(IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830))) {
1303 + if (!(devices & (PIPE_LFP | PIPE_LFP<<8))) {
1304 + OUTREG(0x61200, INREG(0x61200) & ~0x80000000);
1305 + OUTREG(0x61204, INREG(0x61204) & ~0x00000001);
1306 + while ((INREG(0x61200) & 0x80000000) || (INREG(0x61204) & 1));
1308 + OUTREG(LVDS, (INREG(LVDS) | 1<<30) & ~0x80000300);
1309 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1310 + "Disabling LVDS directly.\n");
1314 + /* Now try to program the registers directly if the BIOS failed. */
1315 + temp = INREG(ADPA);
1316 + temp &= ~(ADPA_DAC_ENABLE | ADPA_PIPE_SELECT_MASK);
1317 + temp &= ~(ADPA_VSYNC_CNTL_DISABLE | ADPA_HSYNC_CNTL_DISABLE);
1318 + /* Turn on ADPA */
1319 + if (singlepipe & PIPE_CRT) {
1320 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1321 + "Enabling ADPA directly. Pipe A.\n");
1322 + temp |= ADPA_DAC_ENABLE | ADPA_PIPE_A_SELECT;
1323 + OUTREG(ADPA, temp);
1325 + if (singlepipe & (PIPE_CRT << 8)) {
1326 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1327 + "Enabling ADPA directly. Pipe B.\n");
1328 + temp |= ADPA_DAC_ENABLE | ADPA_PIPE_B_SELECT;
1329 + OUTREG(ADPA, temp);
1332 + if (!(devices & (PIPE_CRT | PIPE_CRT<<8))) {
1333 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1334 + "Disabling ADPA directly.\n");
1335 + temp |= ADPA_VSYNC_CNTL_DISABLE | ADPA_HSYNC_CNTL_DISABLE;
1336 + OUTREG(ADPA, temp);
1340 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,"Writing config directly to SWF0.\n");
1342 OUTREG(SWF0, (temp & ~(0xffff)) | (devices & 0xffff));
1344 - if (GetDisplayDevices(pScrn) != devices)
1345 + if (GetDisplayDevices(pScrn) != devices) {
1346 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1347 "SetDisplayDevices failed with devices 0x%x instead of 0x%x\n",
1348 GetDisplayDevices(pScrn), devices);
1353 + pI830->pipeEnabled[0] = (devices & 0xff) ? TRUE : FALSE;
1354 + pI830->pipeEnabled[1] = (devices & 0xff00) ? TRUE : FALSE;
1360 @@ -916,9 +1289,10 @@
1361 /* Check for active devices connected to each display pipe. */
1362 for (n = 0; n < pI830->availablePipes; n++) {
1363 pipe = ((pI830->operatingDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK);
1366 pI830->pipeEnabled[n] = TRUE;
1369 + pI830->pipeEnabled[n] = FALSE;
1372 GetPipeSizes(pScrn);
1373 @@ -942,7 +1316,7 @@
1374 * The GTT varying according the the FbMapSize and the popup is 4KB */
1375 range = (pI830->FbMapSize / (1024*1024)) + 4;
1377 - if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I915G(pI830)) {
1378 + if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
1379 switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
1380 case I855_GMCH_GMS_STOLEN_1M:
1381 memsize = MB(1) - KB(range);
1382 @@ -960,11 +1334,11 @@
1383 memsize = MB(32) - KB(range);
1385 case I915G_GMCH_GMS_STOLEN_48M:
1386 - if (IS_I915G(pI830))
1387 + if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))
1388 memsize = MB(48) - KB(range);
1390 case I915G_GMCH_GMS_STOLEN_64M:
1391 - if (IS_I915G(pI830))
1392 + if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))
1393 memsize = MB(64) - KB(range);
1396 @@ -1331,157 +1705,189 @@
1401 - * Use the native method instead of the vgahw method. So far this is
1402 - * only used for 8-bit mode.
1404 - * XXX Look into using the 10-bit gamma correction mode for 15/16/24 bit,
1405 - * and see if a DirectColor visual can be offered.
1408 I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
1409 LOCO * colors, VisualPtr pVisual)
1414 unsigned char r, g, b;
1417 + int dspreg, dspbase;
1419 DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
1420 pI830 = I830PTR(pScrn);
1422 if (pI830->pipe == 0) {
1423 - /* It seems that an initial read is needed. */
1424 - temp = INREG(PALETTE_A);
1425 + palreg = PALETTE_A;
1426 + dspreg = DSPACNTR;
1427 + dspbase = DSPABASE;
1429 + palreg = PALETTE_B;
1430 + dspreg = DSPBCNTR;
1431 + dspbase = DSPBBASE;
1434 + OUTREG(dspreg, INREG(dspreg) | DISPPLANE_GAMMA_ENABLE);
1435 + OUTREG(dspbase, INREG(dspbase));
1437 + /* It seems that an initial read is needed. */
1438 + temp = INREG(palreg);
1440 + switch(pScrn->depth) {
1442 for (i = 0; i < numColors; i++) {
1443 - index = indices[i];
1444 - r = colors[index].red;
1445 - g = colors[index].green;
1446 - b = colors[index].blue;
1447 - val = (r << 16) | (g << 8) | b;
1448 - OUTREG(PALETTE_A + index * 4, val);
1449 + index = indices[i];
1450 + r = colors[index].red;
1451 + g = colors[index].green;
1452 + b = colors[index].blue;
1453 + for (j = 0; j < 8; j++) {
1454 + val = (r << 16) | (g << 8) | b;
1455 + OUTREG(palreg + index * 32 + (j * 4), val);
1459 - if (pI830->pipe == 1) {
1460 - /* It seems that an initial read is needed. */
1461 - temp = INREG(PALETTE_B);
1464 for (i = 0; i < numColors; i++) {
1465 + index = indices[i / 2];
1466 + r = colors[index].red;
1467 + b = colors[index].blue;
1468 + index = indices[i];
1469 + g = colors[index].green;
1471 + val = (r << 16) | (g << 8) | b;
1472 + OUTREG(palreg + index * 16, val);
1473 + OUTREG(palreg + index * 16 + 4, val);
1474 + OUTREG(palreg + index * 16 + 8, val);
1475 + OUTREG(palreg + index * 16 + 12, val);
1478 + index = indices[i];
1479 + g = colors[index].green;
1481 + val = (r << 16) | (g << 8) | b;
1482 + OUTREG(palreg + index * 16, val);
1483 + OUTREG(palreg + index * 16 + 4, val);
1484 + OUTREG(palreg + index * 16 + 8, val);
1485 + OUTREG(palreg + index * 16 + 12, val);
1489 + for(i = 0; i < numColors; i++) {
1491 r = colors[index].red;
1492 g = colors[index].green;
1493 b = colors[index].blue;
1494 val = (r << 16) | (g << 8) | b;
1495 - OUTREG(PALETTE_B + index * 4, val);
1496 + OUTREG(palreg + index * 4, val);
1503 -PreInitCleanup(ScrnInfoPtr pScrn)
1505 - I830Ptr pI830 = I830PTR(pScrn);
1507 - if (IsPrimary(pScrn) && pI830->LpRing) {
1508 - xfree(pI830->LpRing);
1509 - pI830->LpRing = NULL;
1511 - if (IsPrimary(pScrn) && pI830->CursorMem) {
1512 - xfree(pI830->CursorMem);
1513 - pI830->CursorMem = NULL;
1515 - if (IsPrimary(pScrn) && pI830->CursorMemARGB) {
1516 - xfree(pI830->CursorMemARGB);
1517 - pI830->CursorMemARGB = NULL;
1519 - if (IsPrimary(pScrn) && pI830->OverlayMem) {
1520 - xfree(pI830->OverlayMem);
1521 - pI830->OverlayMem = NULL;
1523 - if (IsPrimary(pScrn) && pI830->overlayOn) {
1524 - xfree(pI830->overlayOn);
1525 - pI830->overlayOn = NULL;
1527 - if (!IsPrimary(pScrn) && pI830->entityPrivate)
1528 - pI830->entityPrivate->pScrn_2 = NULL;
1529 - RestoreBIOSMemSize(pScrn);
1530 - if (pI830->swfSaved) {
1531 - OUTREG(SWF0, pI830->saveSWF0);
1532 - OUTREG(SWF4, pI830->saveSWF4);
1534 - if (pI830->MMIOBase)
1535 - I830UnmapMMIO(pScrn);
1536 - I830BIOSFreeRec(pScrn);
1540 -GetBIOSPipe(ScrnInfoPtr pScrn)
1541 +I830UseDDC(ScrnInfoPtr pScrn)
1543 - I830Ptr pI830 = I830PTR(pScrn);
1544 - vbeInfoPtr pVbe = pI830->pVbe;
1547 - DPRINTF(PFX, "GetBIOSPipe:\n");
1549 - /* single pipe machines should always return Pipe A */
1550 - if (pI830->availablePipes == 1) return 0;
1552 - pVbe->pInt10->num = 0x10;
1553 - pVbe->pInt10->ax = 0x5f1c;
1554 - pVbe->pInt10->bx = 0x100;
1556 - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
1557 - if (Check5fStatus(pScrn, 0x5f1c, pVbe->pInt10->ax)) {
1558 - if (pI830->newPipeSwitch) {
1559 - pipe = ((pVbe->pInt10->bx & 0x0001));
1561 - pipe = ((pVbe->pInt10->cx & 0x0100) >> 8);
1570 -SetBIOSPipe(ScrnInfoPtr pScrn, int pipe)
1572 - I830Ptr pI830 = I830PTR(pScrn);
1573 - vbeInfoPtr pVbe = pI830->pVbe;
1574 + xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC);
1575 + struct detailed_monitor_section* detMon;
1576 + struct monitor_ranges *mon_range = NULL;
1579 - DPRINTF(PFX, "SetBIOSPipe: pipe 0x%x\n", pipe);
1580 + if (!DDC) return 0;
1582 - /* single pipe machines should always return TRUE */
1583 - if (pI830->availablePipes == 1) return TRUE;
1584 + /* Now change the hsync/vrefresh values of the current monitor to
1585 + * match those of DDC */
1586 + for (i = 0; i < 4; i++) {
1587 + detMon = &DDC->det_mon[i];
1588 + if(detMon->type == DS_RANGES)
1589 + mon_range = &detMon->section.ranges;
1592 + if (!mon_range || mon_range->min_h == 0 || mon_range->max_h == 0 ||
1593 + mon_range->min_v == 0 || mon_range->max_v == 0)
1594 + return 0; /* bad ddc */
1596 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using detected DDC timings\n");
1597 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tHorizSync %d-%d\n",
1598 + mon_range->min_h, mon_range->max_h);
1599 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tVertRefresh %d-%d\n",
1600 + mon_range->min_v, mon_range->max_v);
1601 +#define DDC_SYNC_TOLERANCE SYNC_TOLERANCE
1602 + if (pScrn->monitor->nHsync > 0) {
1603 + for (i = 0; i < pScrn->monitor->nHsync; i++) {
1604 + if ((1.0 - DDC_SYNC_TOLERANCE) * mon_range->min_h >
1605 + pScrn->monitor->hsync[i].lo ||
1606 + (1.0 + DDC_SYNC_TOLERANCE) * mon_range->max_h <
1607 + pScrn->monitor->hsync[i].hi) {
1608 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1609 + "config file hsync range %g-%gkHz not within DDC "
1610 + "hsync range %d-%dkHz\n",
1611 + pScrn->monitor->hsync[i].lo, pScrn->monitor->hsync[i].hi,
1612 + mon_range->min_h, mon_range->max_h);
1614 + pScrn->monitor->hsync[i].lo = mon_range->min_h;
1615 + pScrn->monitor->hsync[i].hi = mon_range->max_h;
1619 - pVbe->pInt10->num = 0x10;
1620 - pVbe->pInt10->ax = 0x5f1c;
1621 - if (pI830->newPipeSwitch) {
1622 - pVbe->pInt10->bx = pipe;
1623 - pVbe->pInt10->cx = 0;
1625 - pVbe->pInt10->bx = 0x0;
1626 - pVbe->pInt10->cx = pipe << 8;
1627 + if (pScrn->monitor->nVrefresh > 0) {
1628 + for (i=0; i<pScrn->monitor->nVrefresh; i++) {
1629 + if ((1.0 - DDC_SYNC_TOLERANCE) * mon_range->min_v >
1630 + pScrn->monitor->vrefresh[i].lo ||
1631 + (1.0 + DDC_SYNC_TOLERANCE) * mon_range->max_v <
1632 + pScrn->monitor->vrefresh[i].hi) {
1633 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1634 + "config file vrefresh range %g-%gHz not within DDC "
1635 + "vrefresh range %d-%dHz\n",
1636 + pScrn->monitor->vrefresh[i].lo, pScrn->monitor->vrefresh[i].hi,
1637 + mon_range->min_v, mon_range->max_v);
1639 + pScrn->monitor->vrefresh[i].lo = mon_range->min_v;
1640 + pScrn->monitor->vrefresh[i].hi = mon_range->max_v;
1644 - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
1645 - if (Check5fStatus(pScrn, 0x5f1c, pVbe->pInt10->ax))
1649 + return mon_range->max_clock;
1653 -SetPipeAccess(ScrnInfoPtr pScrn)
1655 +PreInitCleanup(ScrnInfoPtr pScrn)
1657 I830Ptr pI830 = I830PTR(pScrn);
1659 - /* Don't try messing with the pipe, unless we're dual head */
1660 - if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) {
1661 - if (!SetBIOSPipe(pScrn, pI830->pipe))
1663 + if (IsPrimary(pScrn))
1664 + pI830->entityPrivate->pScrn_1 = NULL;
1665 + if (IsPrimary(pScrn) && pI830->LpRing) {
1666 + xfree(pI830->LpRing);
1667 + pI830->LpRing = NULL;
1671 + if (IsPrimary(pScrn) && pI830->CursorMem) {
1672 + xfree(pI830->CursorMem);
1673 + pI830->CursorMem = NULL;
1675 + if (IsPrimary(pScrn) && pI830->CursorMemARGB) {
1676 + xfree(pI830->CursorMemARGB);
1677 + pI830->CursorMemARGB = NULL;
1679 + if (IsPrimary(pScrn) && pI830->OverlayMem) {
1680 + xfree(pI830->OverlayMem);
1681 + pI830->OverlayMem = NULL;
1683 + if (IsPrimary(pScrn) && pI830->overlayOn) {
1684 + xfree(pI830->overlayOn);
1685 + pI830->overlayOn = NULL;
1687 + if (!IsPrimary(pScrn) && pI830->entityPrivate)
1688 + pI830->entityPrivate->pScrn_2 = NULL;
1689 + RestoreBIOSMemSize(pScrn);
1690 + if (pI830->swfSaved) {
1691 + OUTREG(SWF0, pI830->saveSWF0);
1692 + OUTREG(SWF4, pI830->saveSWF4);
1694 + if (pI830->MMIOBase)
1695 + I830UnmapMMIO(pScrn);
1696 + I830BIOSFreeRec(pScrn);
1700 @@ -1508,9 +1914,12 @@
1701 I830EntPtr pI830Ent = NULL;
1708 - pointer pDDCModule, pVBEModule;
1709 + DisplayModePtr p, pMon;
1710 + pointer pDDCModule = NULL, pVBEModule = NULL;
1712 const char *chipname;
1714 @@ -1660,6 +2069,15 @@
1715 case PCI_CHIP_I915_G:
1718 + case PCI_CHIP_E7221_G:
1719 + chipname = "E7221 (i915)";
1721 + case PCI_CHIP_I915_GM:
1722 + chipname = "915GM";
1724 + case PCI_CHIP_I945_G:
1725 + chipname = "945G";
1728 chipname = "unknown chipset";
1730 @@ -1697,7 +2115,7 @@
1731 pI830->LinearAddr = pI830->pEnt->device->MemBase;
1734 - if (IS_I915G(pI830)) {
1735 + if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
1736 pI830->LinearAddr = pI830->PciInfo->memBase[2] & 0xF0000000;
1738 } else if (pI830->PciInfo->memBase[1] != 0) {
1739 @@ -1719,7 +2137,7 @@
1740 pI830->MMIOAddr = pI830->pEnt->device->IOBase;
1743 - if (IS_I915G(pI830)) {
1744 + if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
1745 pI830->MMIOAddr = pI830->PciInfo->memBase[0] & 0xFFF80000;
1747 } else if (pI830->PciInfo->memBase[1]) {
1748 @@ -1764,11 +2182,14 @@
1749 pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */
1752 - if (IS_I915G(pI830)) {
1753 + if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
1754 if (pI830->PciInfo->memBase[2] & 0x08000000)
1755 pI830->FbMapSize = 0x8000000; /* 128MB aperture */
1757 pI830->FbMapSize = 0x10000000; /* 256MB aperture */
1759 + if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G)
1760 + pI830->FbMapSize = 0x8000000; /* 128MB aperture */
1762 /* 128MB aperture for later chips */
1763 pI830->FbMapSize = 0x8000000;
1764 @@ -1791,7 +2212,10 @@
1768 - if (IS_MOBILE(pI830) || IS_I915G(pI830))
1769 + if (pI830->PciInfo->chipType == PCI_CHIP_E7221_G)
1770 + pI830->availablePipes = 1;
1772 + if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830))
1773 pI830->availablePipes = 2;
1775 pI830->availablePipes = 1;
1776 @@ -1866,8 +2290,19 @@
1780 + pI830->fixedPipe = -1;
1781 + if ((s = xf86GetOptValString(pI830->Options, OPTION_FIXEDPIPE)) &&
1782 + IsPrimary(pScrn)) {
1784 + if (strstr(s, "A") || strstr(s, "a") || strstr(s, "0"))
1785 + pI830->fixedPipe = 0;
1786 + else if (strstr(s, "B") || strstr(s, "b") || strstr(s, "1"))
1787 + pI830->fixedPipe = 1;
1790 pI830->MonType1 = PIPE_NONE;
1791 pI830->MonType2 = PIPE_NONE;
1792 + pI830->specifiedMonitor = FALSE;
1794 if ((s = xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT)) &&
1796 @@ -1947,6 +2382,8 @@
1797 "Monitor 1 and 2 cannot be type NONE\n");
1801 + pI830->specifiedMonitor = TRUE;
1804 if (xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) {
1805 @@ -1963,21 +2400,24 @@
1808 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling Clone Mode\n");
1809 - pI830->CloneRefresh = 60; /* default to 60Hz */
1810 - if (xf86GetOptValInteger(pI830->Options, OPTION_CLONE_REFRESH,
1811 + pI830->Clone = TRUE;
1814 + pI830->CloneRefresh = 60; /* default to 60Hz */
1815 + if (xf86GetOptValInteger(pI830->Options, OPTION_CLONE_REFRESH,
1816 &(pI830->CloneRefresh))) {
1817 - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Clone Monitor Refresh Rate %d\n",
1818 + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Clone Monitor Refresh Rate %d\n",
1819 pI830->CloneRefresh);
1821 - if (pI830->CloneRefresh < 60 || pI830->CloneRefresh > 120) {
1822 - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Bad Clone Refresh Rate\n");
1823 - PreInitCleanup(pScrn);
1826 - pI830->Clone = TRUE;
1829 - if ((pI830->entityPrivate && IsPrimary(pScrn)) || pI830->Clone) {
1830 + /* See above i830refreshes on why 120Hz is commented out */
1831 + if (pI830->CloneRefresh < 60 || pI830->CloneRefresh > 85 /* 120 */) {
1832 + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Bad Clone Refresh Rate\n");
1833 + PreInitCleanup(pScrn);
1837 + if ((pI830->entityPrivate && IsPrimary(pScrn)) || pI830->Clone) {
1838 if ((!xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT))) {
1839 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "You must have a MonitorLayout "
1840 "defined for use in a DualHead or Clone setup.\n");
1841 @@ -1993,26 +2433,57 @@
1845 + xf86GetOptValBool(pI830->Options, OPTION_SHADOW_FB, &pI830->shadowFB);
1846 + if (pI830->shadowFB) {
1847 + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: shadow FB enabled\n");
1850 + if ((s = xf86GetOptValString(pI830->Options, OPTION_ROTATE))) {
1851 + if(!xf86NameCmp(s, "CW")) {
1852 + /* accel is disabled below for shadowFB */
1853 + pI830->shadowFB = TRUE;
1854 + pI830->rotate = 1;
1855 + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
1856 + "Rotating screen clockwise - acceleration disabled\n");
1857 + } else if(!xf86NameCmp(s, "CCW")) {
1858 + pI830->shadowFB = TRUE;
1859 + pI830->rotate = -1;
1860 + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen"
1861 + "counter clockwise - acceleration disabled\n");
1863 + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
1864 + "value for Option \"Rotate\"\n", s);
1865 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1866 + "Valid options are \"CW\" or \"CCW\"\n");
1870 + if (pI830->shadowFB && !pI830->noAccel) {
1871 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1872 + "HW acceleration not supported with \"shadowFB\".\n");
1873 + pI830->noAccel = TRUE;
1877 * Let's setup the mobile systems to check the lid status
1879 if (IS_MOBILE(pI830)) {
1880 - pI830->checkLid = TRUE;
1881 + pI830->checkDevices = TRUE;
1883 - if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKLID, TRUE)) {
1884 - pI830->checkLid = FALSE;
1885 - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Checking Lid status disabled\n");
1886 + if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) {
1887 + pI830->checkDevices = FALSE;
1888 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n");
1890 if (pI830->entityPrivate && !IsPrimary(pScrn) &&
1891 - !I830PTR(pI830->entityPrivate->pScrn_1)->checkLid) {
1892 + !I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) {
1893 /* If checklid is off, on the primary head, then
1894 * turn it off on the secondary*/
1895 - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Checking Lid status disabled\n");
1896 - pI830->checkLid = FALSE;
1897 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n");
1898 + pI830->checkDevices = FALSE;
1900 - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Checking Lid status enabled\n");
1901 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays enabled\n");
1903 - pI830->checkLid = FALSE;
1904 + pI830->checkDevices = FALSE;
1907 * The "VideoRam" config file parameter specifies the total amount of
1908 @@ -2215,13 +2686,22 @@
1910 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS Build: %d\n",pI830->bios_version);
1912 - /* BIOS build 3062 changed the pipe switching functionality */
1913 - if (pI830->availablePipes == 2 && pI830->bios_version >= 3062) {
1915 + * Intel changed the BIOS version codes and started at 1200.
1916 + * We know that bios codes for 830M started around 2400.
1917 + * So we test those conditions to make this judgement. Ugh.
1919 + if (pI830->availablePipes == 2 && pI830->bios_version < 2000)
1920 pI830->newPipeSwitch = TRUE;
1921 - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using new Pipe switch code\n");
1923 + else if (pI830->availablePipes == 2 && pI830->bios_version >= 3062)
1924 + /* BIOS build 3062 changed the pipe switching functionality */
1925 + pI830->newPipeSwitch = TRUE;
1927 pI830->newPipeSwitch = FALSE;
1929 + if (pI830->newPipeSwitch)
1930 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using new Pipe switch code\n");
1932 pI830->devicePresence = FALSE;
1934 if (xf86ReturnOptValBool(pI830->Options, OPTION_DEVICE_PRESENCE, FALSE)) {
1935 @@ -2250,18 +2730,29 @@
1936 pI830->savedDevices = GetDisplayDevices(pScrn);
1938 if (IsPrimary(pScrn)) {
1939 - pI830->pipe = GetBIOSPipe(pScrn);
1941 - if (xf86ReturnOptValBool(pI830->Options, OPTION_FLIP_PRIMARY, FALSE)) {
1942 - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Primary flipping enabled\n");
1943 - pI830->pipe = !pI830->pipe;
1945 + pI830->pipe = pI830->origPipe = GetBIOSPipe(pScrn);
1948 + if (pI830->fixedPipe != -1) {
1949 + if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) {
1950 + pI830->pipe = pI830->fixedPipe;
1951 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1952 + "Fixed Pipe setting primary to pipe %s.\n",
1953 + pI830->fixedPipe ? "B" : "A");
1957 /* If the monitors aren't setup, read from the current config */
1958 - if (pI830->MonType1 == PIPE_NONE)
1959 + if (pI830->MonType1 == PIPE_NONE && pI830->MonType2 == PIPE_NONE) {
1960 pI830->MonType1 = pI830->savedDevices & 0xff;
1961 - if (pI830->MonType2 == PIPE_NONE)
1962 pI830->MonType2 = (pI830->savedDevices & 0xff00) >> 8;
1964 + /* Here, we've switched pipes from our primary */
1965 + if (pI830->MonType1 == PIPE_NONE && pI830->pipe == 0)
1967 + if (pI830->MonType2 == PIPE_NONE && pI830->pipe == 1)
1971 pI830->operatingDevices = (pI830->MonType2 << 8) | pI830->MonType1;
1973 @@ -2273,15 +2764,18 @@
1974 pI830->operatingDevices = pI830->MonType1;
1976 pI830->operatingDevices = pI830->MonType2 << 8;
1978 - if (pI830->operatingDevices & 0xFF00)
1979 - xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1980 - "Primary Pipe is %s, switching off second monitor (0x%x)\n",
1981 - pI830->pipe ? "B" : "A", pI830->operatingDevices);
1984 + if (pI830->pipe != pI830->origPipe)
1985 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1986 + "Primary Pipe has been switched from original pipe (%s to %s)\n",
1987 + pI830->origPipe ? "B" : "A", pI830->pipe ? "B" : "A");
1989 I830Ptr pI8301 = I830PTR(pI830Ent->pScrn_1);
1990 pI830->operatingDevices = pI8301->operatingDevices;
1991 + pI830->pipe = !pI8301->pipe;
1992 + pI830->MonType1 = pI8301->MonType1;
1993 + pI830->MonType2 = pI8301->MonType2;
1996 /* Buggy BIOS 3066 is known to cause this, so turn this off */
1997 @@ -2309,26 +2803,25 @@
2001 - if (!SetDisplayDevices(pScrn, pI830->operatingDevices)) {
2002 - xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2003 + if (IsPrimary(pScrn)) {
2004 + if (!SetDisplayDevices(pScrn, pI830->operatingDevices)) {
2005 + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2006 "Failed to switch to monitor configuration (0x%x)\n",
2007 pI830->operatingDevices);
2008 - xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2009 + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2010 "Please check the devices specified in your MonitorLayout\n");
2011 - xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2012 + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2013 "is configured correctly.\n");
2014 - PreInitCleanup(pScrn);
2016 + PreInitCleanup(pScrn);
2021 PrintDisplayDeviceInfo(pScrn);
2023 if (xf86IsEntityShared(pScrn->entityList[0])) {
2024 if (!IsPrimary(pScrn)) {
2025 - I830Ptr pI8301 = I830PTR(pI830Ent->pScrn_1);
2027 pI830Ent->pScrn_2 = pScrn;
2028 - pI830->pipe = !pI8301->pipe;
2030 /* This could be made to work with a little more fiddling */
2031 pI830->directRenderingDisabled = TRUE;
2032 @@ -2367,14 +2860,13 @@
2035 /* Check if the HW cursor needs physical address. */
2036 - if (IS_MOBILE(pI830) || IS_I915G(pI830))
2037 + if (IS_MOBILE(pI830) || IS_I915G(pI830) || IS_I945G(pI830))
2038 pI830->CursorNeedsPhysical = TRUE;
2040 pI830->CursorNeedsPhysical = FALSE;
2042 - /* Force ring buffer to be in low memory for the 845G and later. */
2043 - if (IS_845G(pI830) || IS_I85X(pI830) || IS_I865G(pI830) || IS_I915G(pI830))
2044 - pI830->NeedRingBufferLow = TRUE;
2045 + /* Force ring buffer to be in low memory for all chipsets */
2046 + pI830->NeedRingBufferLow = TRUE;
2049 * XXX If we knew the pre-initialised GTT format for certain, we could
2050 @@ -2413,14 +2905,17 @@
2051 "Maximum frambuffer space: %d kByte\n", pScrn->videoRam);
2053 SetPipeAccess(pScrn);
2054 - if ((pDDCModule = xf86LoadSubModule(pScrn, "ddc")) == NULL) {
2055 - PreInitCleanup(pScrn);
2059 - if ((pI830->vesa->monitor = vbeDoEDID(pI830->pVbe, pDDCModule)) != NULL) {
2060 - xf86PrintEDID(pI830->vesa->monitor);
2062 + /* Check we have an LFP connected, before trying to
2063 + * read PanelID information. */
2064 + if ( (pI830->pipe == 1 && pI830->operatingDevices & (PIPE_LFP << 8)) ||
2065 + (pI830->pipe == 0 && pI830->operatingDevices & PIPE_LFP) )
2066 + vbeDoPanelID(pI830->pVbe);
2068 + pDDCModule = xf86LoadSubModule(pScrn, "ddc");
2070 + pI830->vesa->monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
2072 if ((pScrn->monitor->DDC = pI830->vesa->monitor) != NULL)
2073 xf86SetDDCproperties(pScrn, pI830->vesa->monitor);
2074 xf86UnloadSubModule(pDDCModule);
2075 @@ -2485,7 +2980,7 @@
2079 - if (pI830->useExtendedRefresh) {
2080 + if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh) {
2081 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2082 "Will use BIOS call 0x5f05 to set refresh rates for CRTs.\n");
2084 @@ -2501,13 +2996,38 @@
2085 xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
2086 "Maximum space available for video modes: %d kByte\n", memsize);
2088 + /* By now, we should have had some monitor settings, but if not, we
2089 + * need to setup some defaults. These are used in common/xf86Modes.c
2090 + * so we'll use them here for GetModePool, and that's all.
2091 + * We unset them after the call, so we can report 'defaults' as being
2092 + * used through the common layer.
2094 +#define DEFAULT_HSYNC_LO 28
2095 +#define DEFAULT_HSYNC_HI 33
2096 +#define DEFAULT_VREFRESH_LO 43
2097 +#define DEFAULT_VREFRESH_HI 72
2099 + if (pScrn->monitor->nHsync == 0) {
2100 + pScrn->monitor->hsync[0].lo = DEFAULT_HSYNC_LO;
2101 + pScrn->monitor->hsync[0].hi = DEFAULT_HSYNC_HI;
2102 + pScrn->monitor->nHsync = 1;
2106 + if (pScrn->monitor->nVrefresh == 0) {
2107 + pScrn->monitor->vrefresh[0].lo = DEFAULT_VREFRESH_LO;
2108 + pScrn->monitor->vrefresh[0].hi = DEFAULT_VREFRESH_HI;
2109 + pScrn->monitor->nVrefresh = 1;
2113 + DDCclock = I830UseDDC(pScrn);
2116 * Note: VBE modes (> 0x7f) won't work with Intel's extended BIOS
2117 - * functions. For that reason it's important to set only
2118 - * V_MODETYPE_VGA in the flags for VBEGetModePool().
2121 - pScrn->modePool = VBEGetModePool(pScrn, pI830->pVbe, pI830->vbeInfo,
2123 + pScrn->modePool = I830GetModePool(pScrn, pI830->pVbe, pI830->vbeInfo);
2125 if (!pScrn->modePool) {
2126 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2127 @@ -2516,6 +3036,21 @@
2131 + /* This may look a little weird, but to notify that we're using the
2132 + * default hsync/vrefresh we need to unset what we just set .....
2135 + pScrn->monitor->hsync[0].lo = 0;
2136 + pScrn->monitor->hsync[0].hi = 0;
2137 + pScrn->monitor->nHsync = 0;
2141 + pScrn->monitor->vrefresh[0].lo = 0;
2142 + pScrn->monitor->vrefresh[0].hi = 0;
2143 + pScrn->monitor->nVrefresh = 0;
2146 SetPipeAccess(pScrn);
2147 VBESetModeNames(pScrn->modePool);
2149 @@ -2541,15 +3076,61 @@
2153 - xf86PruneDriverModes(pScrn);
2154 + /* Only use this if we've got DDC available */
2155 + if (DDCclock > 0) {
2160 + int Clock = 100000000; /* incredible value */
2162 - pScrn->currentMode = pScrn->modes;
2163 + for (pMon = pScrn->monitor->Modes; pMon != NULL; pMon = pMon->next) {
2164 + if ((pMon->HDisplay != p->HDisplay) ||
2165 + (pMon->VDisplay != p->VDisplay) ||
2166 + (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
2169 + /* Find lowest supported Clock for this resolution */
2170 + if (Clock > pMon->Clock)
2171 + Clock = pMon->Clock;
2174 + if (DDCclock < 2550 && Clock / 1000.0 > DDCclock) {
2175 + ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n",
2176 + p->name, pScrn->monitor->id,
2177 + Clock/1000.0, DDCclock);
2178 + p->status = MODE_BAD;
2181 + } while (p != NULL && p != pScrn->modes);
2184 + xf86PruneDriverModes(pScrn);
2186 if (pScrn->modes == NULL) {
2187 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
2188 PreInitCleanup(pScrn);
2192 + /* Now we check the VESA BIOS's displayWidth and reset if necessary */
2195 + VbeModeInfoData *data = (VbeModeInfoData *) p->Private;
2196 + VbeModeInfoBlock *modeInfo;
2198 + /* Get BytesPerScanline so we can reset displayWidth */
2199 + if ((modeInfo = VBEGetModeInfo(pI830->pVbe, data->mode))) {
2200 + if (pScrn->displayWidth < modeInfo->BytesPerScanline / pI830->cpp) {
2201 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Correcting stride (%d -> %d)\n", pScrn->displayWidth, modeInfo->BytesPerScanline);
2202 + pScrn->displayWidth = modeInfo->BytesPerScanline / pI830->cpp;
2206 + } while (p != NULL && p != pScrn->modes);
2208 + pScrn->currentMode = pScrn->modes;
2211 #define USE_PITCHES 1
2213 @@ -2671,7 +3252,7 @@
2216 SetPipeAccess(pScrn);
2217 - VBEPrintModes(pScrn);
2218 + I830PrintModes(pScrn);
2220 if (!pI830->vesa->useDefaultRefresh) {
2222 @@ -2682,7 +3263,7 @@
2223 * if there are no non-CRT devices attached.
2225 SetPipeAccess(pScrn);
2226 - VBESetModeParameters(pScrn, pI830->pVbe);
2227 + I830SetModeParameters(pScrn, pI830->pVbe);
2230 /* PreInit shouldn't leave any state changes, so restore this. */
2231 @@ -2721,11 +3302,6 @@
2232 xf86LoaderReqSymLists(I810ramdacSymbols, NULL);
2235 - if (!SetDisplayDevices(pScrn, pI830->savedDevices)) {
2236 - xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2237 - "Failed to switch to saved display devices, continuing.\n");
2240 I830UnmapMMIO(pScrn);
2242 /* We won't be using the VGA access after the probe. */
2243 @@ -2733,8 +3309,19 @@
2244 xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr);
2245 xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr);
2247 + if (pI830->shadowFB) {
2248 + if (!xf86LoadSubModule(pScrn, "shadowfb")) {
2249 + I830BIOSFreeRec(pScrn);
2250 + vbeFree(pI830->pVbe);
2253 + xf86LoaderReqSymLists(I810shadowFBSymbols, NULL);
2256 VBEFreeVBEInfo(pI830->vbeInfo);
2257 + pI830->vbeInfo = NULL;
2258 vbeFree(pI830->pVbe);
2259 + pI830->pVbe = NULL;
2261 /* Use the VBE mode restore workaround by default. */
2262 pI830->vbeRestoreWorkaround = TRUE;
2263 @@ -2953,12 +3540,16 @@
2265 DPRINTF(PFX, "SaveHWState\n");
2267 - SetPipeAccess(pScrn);
2268 + if (IsPrimary(pScrn) && pI830->pipe != pI830->origPipe)
2269 + SetBIOSPipe(pScrn, pI830->origPipe);
2271 + SetPipeAccess(pScrn);
2273 pVesa = pI830->vesa;
2275 /* Make sure we save at least this information in case of failure. */
2276 VBEGetVBEMode(pVbe, &pVesa->stateMode);
2277 + pVesa->stateRefresh = GetRefreshRate(pScrn, pVesa->stateMode, NULL);
2278 modeInfo = VBEGetModeInfo(pVbe, pVesa->stateMode);
2279 pVesa->savedScanlinePitch = 0;
2281 @@ -3024,6 +3615,11 @@
2283 DPRINTF(PFX, "RestoreHWState\n");
2285 + if (IsPrimary(pScrn) && pI830->pipe != pI830->origPipe)
2286 + SetBIOSPipe(pScrn, pI830->origPipe);
2288 + SetPipeAccess(pScrn);
2290 pVesa = pI830->vesa;
2293 @@ -3031,26 +3627,8 @@
2294 * Temporarily program a 640x480 mode before switching back to
2297 - if (pVesa->useDefaultRefresh) {
2300 - switch (pScrn->depth) {
2314 - mode |= (1 << 15) | (1 << 14);
2315 - I830VESASetVBEMode(pScrn, mode, NULL);
2317 + if (pVesa->useDefaultRefresh)
2318 + I830Set640x480(pScrn);
2320 if (pVesa->state && pVesa->stateSize) {
2321 CARD16 imr = INREG16(IMR);
2322 @@ -3083,6 +3661,9 @@
2323 "Setting the original video mode instead of restoring\n\t"
2324 "the saved state\n");
2325 I830VESASetVBEMode(pScrn, pVesa->stateMode, NULL);
2326 + if (!pVesa->useDefaultRefresh && pI830->useExtendedRefresh) {
2327 + SetRefreshRate(pScrn, pVesa->stateMode, pVesa->stateRefresh);
2330 if (pVesa->savedScanlinePitch)
2331 VBESetLogicalScanline(pVbe, pVesa->savedScanlinePitch);
2332 @@ -3094,13 +3675,10 @@
2334 vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
2344 static void I830SetCloneVBERefresh(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block, int refresh)
2346 I830Ptr pI830 = I830PTR(pScrn);
2347 @@ -3136,8 +3714,7 @@
2350 block->PixelClock = clock;
2351 - block->RefreshRate = ((double)(block->PixelClock) /
2352 - (double)(p->HTotal * p->VTotal)) * 100;
2353 + block->RefreshRate = RefreshRate;
2357 @@ -3147,62 +3724,138 @@
2358 I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block)
2360 I830Ptr pI830 = I830PTR(pScrn);
2364 DPRINTF(PFX, "Setting mode 0x%.8x\n", mode);
2366 - if (pI830->Clone && !pI830->preinit) {
2367 + if (pI830->Clone && pI830->CloneHDisplay && pI830->CloneVDisplay &&
2368 + !pI830->preinit && !pI830->closing) {
2369 VbeCRTCInfoBlock newblock;
2371 + int newmode = mode;
2374 - Mon = pI830->MonType2;
2376 + if (pI830->pipe == 1)
2377 Mon = pI830->MonType1;
2379 + Mon = pI830->MonType2;
2381 SetBIOSPipe(pScrn, !pI830->pipe);
2383 - /* The reason for this code is if we've not got a CRT on this pipe, then
2384 - * make sure we're using a 60Hz refresh */
2385 - if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh &&
2386 - (mode & (1 << 11)) && block) {
2387 - /* we'll call 5F05 to set the refresh later.... */
2388 - if (Mon != PIPE_CRT)
2389 - VBESetVBEMode(pI830->pVbe, mode, NULL);
2391 - VBESetVBEMode(pI830->pVbe, mode, block);
2393 - if (Mon != PIPE_CRT)
2394 - /* Set clone head to 60Hz because we ain't got a CRT on it */
2395 - I830SetCloneVBERefresh(pScrn, mode, &newblock, 6000);
2397 - /* Set clone head to specified clone refresh rate */
2398 - I830SetCloneVBERefresh(pScrn, mode, &newblock, pI830->CloneRefresh * 100);
2399 - if (newblock.RefreshRate == 0)
2400 + /* Now recheck refresh operations we can use */
2401 + pI830->useExtendedRefresh = FALSE;
2402 + pI830->vesa->useDefaultRefresh = FALSE;
2404 + if (Mon != PIPE_CRT) {
2405 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2406 + "A non-CRT device is attached to Clone pipe %c.\n"
2407 + "\tNo refresh rate overrides will be attempted (0x%x).\n",
2408 + PIPE_NAME(!pI830->pipe), newmode);
2409 + pI830->vesa->useDefaultRefresh = TRUE;
2412 + * Some desktop platforms might not have 0x5f05, so useExtendedRefresh
2413 + * would need to be set to FALSE for those cases.
2415 + if (!pI830->vesa->useDefaultRefresh)
2416 + pI830->useExtendedRefresh = TRUE;
2418 + newmode |= 1 << 11;
2419 + if (pI830->vesa->useDefaultRefresh)
2420 + newmode &= ~(1 << 11);
2422 + if (!SetRefreshRate(pScrn, newmode, 60)) {
2423 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2424 + "BIOS call 0x5f05 not supported on Clone Head, "
2425 + "setting refresh with VBE 3 method.\n");
2426 + pI830->useExtendedRefresh = FALSE;
2429 + if (!pI830->vesa->useDefaultRefresh) {
2430 + I830SetCloneVBERefresh(pScrn, newmode, &newblock, pI830->CloneRefresh * 100);
2432 + if (!VBESetVBEMode(pI830->pVbe, newmode, &newblock)) {
2433 + if (!VBESetVBEMode(pI830->pVbe, (newmode & ~(1 << 11)), NULL))
2434 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2435 + "Failed to set mode for Clone head.\n");
2437 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2438 + "Setting refresh on clone head with VBE 3 method.\n");
2439 + pI830->useExtendedRefresh = FALSE;
2442 + if (!VBESetVBEMode(pI830->pVbe, (newmode & ~(1 << 11)), NULL))
2443 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2444 + "Failed to set mode for Clone head.\n");
2447 + if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh) {
2448 + if (!SetRefreshRate(pScrn, newmode, pI830->CloneRefresh))
2449 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2450 - "Failed to setup clone head mode resolution and refresh.\n");
2451 + "Failed to set refresh rate to %dHz on Clone head.\n",
2452 + pI830->CloneRefresh);
2454 - VBESetVBEMode(pI830->pVbe, mode, &newblock);
2455 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2456 + "Set refresh rate to %dHz on Clone head.\n",
2457 + pI830->CloneRefresh);
2459 + SetPipeAccess(pScrn);
2462 - SetPipeAccess(pScrn);
2463 + if (pI830->pipe == 0)
2464 + Mon = pI830->MonType1;
2466 + Mon = pI830->MonType2;
2469 - return VBESetVBEMode(pI830->pVbe, mode, block);
2472 - vbeInfoPtr pVbe = pI830->pVbe;
2473 - pVbe->pInt10->num = 0x10;
2474 - pVbe->pInt10->ax = 0x80 | (mode & 0x7f);
2475 - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
2476 - pVbe->pInt10->ax = 0x0f00;
2477 - xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
2478 - if ((pVbe->pInt10->ax & 0x7f) == (mode & 0x7f))
2482 + /* Now recheck refresh operations we can use */
2483 + pI830->useExtendedRefresh = FALSE;
2484 + pI830->vesa->useDefaultRefresh = FALSE;
2486 + if (Mon != PIPE_CRT)
2487 + pI830->vesa->useDefaultRefresh = TRUE;
2490 + if (pI830->vesa->useDefaultRefresh)
2491 + mode &= ~(1 << 11);
2493 + * Some desktop platforms might not have 0x5f05, so useExtendedRefresh
2494 + * would need to be set to FALSE for those cases.
2496 + if (!pI830->vesa->useDefaultRefresh)
2497 + pI830->useExtendedRefresh = TRUE;
2499 + if (!SetRefreshRate(pScrn, mode, 60)) {
2500 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2501 + "BIOS call 0x5f05 not supported, "
2502 + "setting refresh with VBE 3 method.\n");
2503 + pI830->useExtendedRefresh = FALSE;
2507 + if (!pI830->vesa->useDefaultRefresh && block) {
2508 + ret = VBESetVBEMode(pI830->pVbe, mode, block);
2510 + ret = VBESetVBEMode(pI830->pVbe, (mode & ~(1 << 11)), NULL);
2512 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2513 + "Setting refresh with VBE 3 method.\n");
2514 + pI830->useExtendedRefresh = FALSE;
2517 + ret = VBESetVBEMode(pI830->pVbe, (mode & ~(1 << 11)), NULL);
2520 + /* Might as well bail now if we've failed */
2521 + if (!ret) return FALSE;
2523 + if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh && block) {
2524 + if (!SetRefreshRate(pScrn, mode, block->RefreshRate / 100)) {
2525 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2526 + "Failed to set refresh rate to %dHz.\n",
2527 + block->RefreshRate / 100);
2528 + pI830->useExtendedRefresh = FALSE;
2536 @@ -3231,21 +3884,6 @@
2541 - * Do this early to find out if we can support it or not....
2542 - * Test if the extendedRefresh BIOS function is supported.
2544 - if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh &&
2545 - (mode & (1 << 11)) && data && data->data && data->block) {
2546 - SetPipeAccess(pScrn);
2547 - if (!SetRefreshRate(pScrn, mode, 60)) {
2548 - xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2549 - "BIOS call 0x5f05 not supported, "
2550 - "setting refresh with VBE 3 method.\n");
2551 - pI830->useExtendedRefresh = FALSE;
2556 pI830->CloneHDisplay = pMode->HDisplay;
2557 pI830->CloneVDisplay = pMode->VDisplay;
2558 @@ -3258,25 +3896,11 @@
2559 ResetState(pScrn, TRUE);
2562 - /* XXX Add macros for the various mode parameter bits. */
2564 - if (pI830->vesa->useDefaultRefresh)
2565 - mode &= ~(1 << 11);
2566 + SetPipeAccess(pScrn);
2568 if (I830VESASetVBEMode(pScrn, mode, data->block) == FALSE) {
2569 - if ((data->block && (mode & (1 << 11))) &&
2570 - I830VESASetVBEMode(pScrn, (mode & ~(1 << 11)), NULL) == TRUE) {
2571 - xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2572 - "Set VBE Mode rejected this modeline.\n\t"
2573 - "Trying standard mode instead!\n");
2574 - DPRINTF(PFX, "OOPS!\n");
2575 - xfree(data->block);
2576 - data->block = NULL;
2577 - data->mode &= ~(1 << 11);
2579 - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
2582 + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n");
2587 @@ -3302,49 +3926,6 @@
2588 VBESetGetDACPaletteFormat(pVbe, 8);
2592 - * When it's OK to set better than default refresh rates, set them here.
2594 - if (pI830->Clone) {
2597 - Mon = pI830->MonType2;
2599 - Mon = pI830->MonType1;
2600 - SetBIOSPipe(pScrn, !pI830->pipe);
2601 - if (pI830->CloneRefresh && (Mon == PIPE_CRT)) {
2602 - if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh &&
2603 - (mode & (1 << 11)) && data && data->data && data->block) {
2604 - refresh = SetRefreshRate(pScrn, mode, pI830->CloneRefresh);
2606 - xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2607 - "Failed to set refresh rate to %dHz on Clone head.\n",
2608 - pI830->CloneRefresh);
2610 - xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2611 - "Set refresh rate to %dHz on Clone head.\n",
2612 - pI830->CloneRefresh);
2614 - xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2615 - "Will use VBE3 method to set refresh on Clone head.\n");
2617 - xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2618 - "Not attempting to override default refresh on non-CRT clone head\n");
2622 - if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh &&
2623 - (mode & (1 << 11)) && data && data->data && data->block) {
2624 - SetPipeAccess(pScrn);
2625 - refresh = SetRefreshRate(pScrn, mode, data->block->RefreshRate / 100);
2628 - xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2629 - "Failed to set refresh rate to %dHz.\n",
2630 - data->block->RefreshRate / 100);
2634 /* XXX Fix plane A with pipe A, and plane B with pipe B. */
2635 planeA = INREG(DSPACNTR);
2636 planeB = INREG(DSPBCNTR);
2637 @@ -3360,36 +3941,18 @@
2638 pI830->planeEnabled[1] ? "enabled" : "disabled",
2639 planeB & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A");
2641 - if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) {
2642 + if (pI830->operatingDevices & 0xff) {
2643 pI830->planeEnabled[0] = 1;
2644 - pI830->pipeEnabled[0] = 1;
2645 - pI830->planeEnabled[1] = 1;
2646 - pI830->pipeEnabled[1] = 1;
2648 + pI830->planeEnabled[0] = 0;
2652 - * Sometimes it seems that no display planes are enabled at this point.
2653 - * For mobile platforms pick the plane(s) connected to enabled pipes.
2654 - * For others choose plane A.
2656 - if (!pI830->planeEnabled[0] && !pI830->planeEnabled[1]) {
2657 - if (pI830->availablePipes == 2) {
2658 - if ((pI830->pipeEnabled[0] &&
2659 - ((planeA & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE_A)) ||
2660 - (pI830->pipeEnabled[1] &&
2661 - ((planeA & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE_B))) {
2662 - pI830->planeEnabled[0] = TRUE;
2664 - if ((pI830->pipeEnabled[0] &&
2665 - ((planeB & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE_A)) ||
2666 - (pI830->pipeEnabled[1] &&
2667 - ((planeB & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE_B))) {
2668 - pI830->planeEnabled[1] = TRUE;
2671 - pI830->planeEnabled[0] = TRUE;
2673 + if (pI830->operatingDevices & 0xff00) {
2674 + pI830->planeEnabled[1] = 1;
2676 + pI830->planeEnabled[1] = 0;
2679 if (pI830->planeEnabled[0]) {
2680 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane A.\n");
2681 planeA |= DISPLAY_PLANE_ENABLE;
2682 @@ -3433,6 +3996,8 @@
2683 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08lx\n", temp);
2688 if (xf86IsEntityShared(pScrn->entityList[0])) {
2689 /* Clean this up !! */
2690 if (IsPrimary(pScrn)) {
2691 @@ -3611,6 +4176,7 @@
2699 @@ -3620,6 +4186,7 @@
2700 "LFP compensation mode: 0x%x\n", ret);
2705 #if MODESWITCH_RESET_STATE
2706 ResetState(pScrn, TRUE);
2707 @@ -3876,6 +4443,8 @@
2709 I830EntPtr pI830Ent = NULL;
2710 I830Ptr pI8301 = NULL;
2711 + int width, height, displayWidth;
2712 + unsigned char *fbbase;
2716 @@ -3938,26 +4507,22 @@
2717 * If we're changing the BIOS's view of the video memory size, do that
2718 * first, then re-initialise the VBE information.
2721 + vbeFree(pI830->pVbe);
2722 pI830->pVbe = VBEInit(NULL, pI830->pEnt->index);
2723 if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize,FALSE))
2724 SetBIOSMemSize(pScrn, pI830->newBIOSMemSize);
2727 + if (pI830->vbeInfo)
2728 + VBEFreeVBEInfo(pI830->vbeInfo);
2729 pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
2731 miClearVisualTypes();
2732 - if (!xf86SetDefaultVisual(pScrn, -1))
2734 - if (pScrn->bitsPerPixel > 8) {
2735 - if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
2736 - pScrn->rgbBits, TrueColor))
2739 - if (!miSetVisualTypes(pScrn->depth,
2740 + if (!miSetVisualTypes(pScrn->depth,
2741 miGetDefaultVisualMask(pScrn->depth),
2742 pScrn->rgbBits, pScrn->defaultVisual))
2745 if (!miSetPixmapDepths())
2748 @@ -4036,7 +4601,7 @@
2751 if (pI830->directRenderingEnabled) {
2752 - if (pI830->noAccel || pI830->SWCursor || pI830->StolenOnly) {
2753 + if (pI830->noAccel || pI830->SWCursor || (pI830->StolenOnly && IsPrimary(pScrn))) {
2754 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DRI is disabled because it "
2755 "needs HW cursor, 2D accel and AGPGART.\n");
2756 pI830->directRenderingEnabled = FALSE;
2757 @@ -4114,10 +4679,26 @@
2760 DPRINTF(PFX, "assert( if(!fbScreenInit(pScreen, ...) )\n");
2761 - if (!fbScreenInit(pScreen, pI830->FbBase + pScrn->fbOffset,
2762 - pScrn->virtualX, pScrn->virtualY,
2763 + if (pI830->rotate) {
2764 + height = pScrn->virtualX;
2765 + width = pScrn->virtualY;
2767 + width = pScrn->virtualX;
2768 + height = pScrn->virtualY;
2770 + if (pI830->shadowFB) {
2771 + pI830->shadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
2772 + pI830->shadowPtr = xalloc(pI830->shadowPitch * height);
2773 + displayWidth = pI830->shadowPitch / (pScrn->bitsPerPixel >> 3);
2774 + fbbase = pI830->shadowPtr;
2776 + pI830->shadowPtr = NULL;
2777 + fbbase = pI830->FbBase;
2778 + displayWidth = pScrn->displayWidth;
2780 + if (!fbScreenInit(pScreen, fbbase + pScrn->fbOffset, width, height,
2781 pScrn->xDpi, pScrn->yDpi,
2782 - pScrn->displayWidth, pScrn->bitsPerPixel))
2783 + displayWidth, pScrn->bitsPerPixel))
2786 if (pScrn->bitsPerPixel > 8) {
2787 @@ -4139,7 +4720,8 @@
2789 xf86SetBlackWhitePixels(pScreen);
2791 - I830DGAInit(pScreen);
2792 + if (!pI830->shadowFB)
2793 + I830DGAInit(pScreen);
2796 "assert( if(!xf86InitFBManager(pScreen, &(pI830->FbMemBox))) )\n");
2797 @@ -4177,13 +4759,39 @@
2799 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing SW Cursor!\n");
2801 + if (pI830->shadowFB) {
2802 + RefreshAreaFuncPtr refreshArea = I830RefreshArea;
2803 + if (pI830->rotate) {
2804 + if (!pI830->PointerMoved) {
2805 + pI830->PointerMoved = pScrn->PointerMoved;
2806 + pScrn->PointerMoved = I830PointerMoved;
2808 + switch (pScrn->bitsPerPixel) {
2810 + refreshArea = I830RefreshArea8;
2813 + refreshArea = I830RefreshArea16;
2816 + refreshArea = I830RefreshArea24;
2819 + refreshArea = I830RefreshArea32;
2823 + ShadowFBInit(pScreen, refreshArea);
2826 DPRINTF(PFX, "assert( if(!miCreateDefColormap(pScreen)) )\n");
2827 if (!miCreateDefColormap(pScreen))
2830 DPRINTF(PFX, "assert( if(!xf86HandleColormaps(pScreen, ...)) )\n");
2831 if (!xf86HandleColormaps(pScreen, 256, 8, I830LoadPalette, 0,
2832 - CMAP_RELOAD_ON_MODE_SWITCH)) {
2833 + CMAP_RELOAD_ON_MODE_SWITCH |
2834 + CMAP_PALETTED_TRUECOLOR)) {
2838 @@ -4221,9 +4829,6 @@
2839 pI830->CloseScreen = pScreen->CloseScreen;
2840 pScreen->CloseScreen = I830BIOSCloseScreen;
2842 - if (pI830->checkLid)
2843 - pI830->lidTimer = TimerSet(NULL, 0, 1000, I830LidTimer, pScrn);
2845 if (serverGeneration == 1)
2846 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
2848 @@ -4335,18 +4940,32 @@
2850 DPRINTF(PFX, "Leave VT\n");
2852 + pI830->leaving = TRUE;
2854 + if (pI830->devicesTimer)
2855 + TimerCancel(pI830->devicesTimer);
2856 + pI830->devicesTimer = NULL;
2858 + if (pI830->Clone) {
2859 + /* Ensure we don't try and setup modes on a clone head */
2860 + pI830->CloneHDisplay = 0;
2861 + pI830->CloneVDisplay = 0;
2864 if (!IsPrimary(pScrn)) {
2865 I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
2866 if (!pI8301->GttBound) {
2873 if (pI830->directRenderingOpen) {
2874 DPRINTF(PFX, "calling dri lock\n");
2875 DRILock(screenInfo.screens[scrnIndex], 0);
2876 pI830->LockHeld = 1;
2878 + drmCtlUninstHandler(pI830->drmSubFD);
2882 @@ -4355,8 +4974,10 @@
2883 SaveHWOperatingState(pScrn);
2886 + if (pI830->CursorInfoRec && pI830->CursorInfoRec->HideCursor)
2887 + pI830->CursorInfoRec->HideCursor(pScrn);
2889 ResetState(pScrn, TRUE);
2890 - RestoreHWState(pScrn);
2892 if (IsPrimary(pScrn)) {
2893 if (!SetDisplayDevices(pScrn, pI830->savedDevices)) {
2894 @@ -4369,13 +4990,195 @@
2898 + RestoreHWState(pScrn);
2899 RestoreBIOSMemSize(pScrn);
2900 if (IsPrimary(pScrn))
2901 I830UnbindGARTMemory(pScrn);
2902 if (pI830->AccelInfoRec)
2903 pI830->AccelInfoRec->NeedToSync = FALSE;
2905 + /* DO IT AGAIN! AS IT SEEMS THAT SOME LFPs FLICKER OTHERWISE */
2906 + if (IsPrimary(pScrn)) {
2907 + if (!SetDisplayDevices(pScrn, pI830->savedDevices)) {
2908 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2909 + "Failed to switch back to original display devices (0x%x) (2)\n",
2910 + pI830->savedDevices);
2912 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
2913 + "Successfully set original devices (2)\n");
2919 +I830DetectMonitorChange(ScrnInfoPtr pScrn)
2921 + I830Ptr pI830 = I830PTR(pScrn);
2922 + pointer pDDCModule = NULL;
2923 + DisplayModePtr p, pMon;
2926 + int displayWidth = pScrn->displayWidth;
2927 + int curHDisplay = pScrn->currentMode->HDisplay;
2928 + int curVDisplay = pScrn->currentMode->VDisplay;
2930 + DPRINTF(PFX, "Detect Monitor Change\n");
2932 + SetPipeAccess(pScrn);
2934 + /* Re-read EDID */
2935 + pDDCModule = xf86LoadSubModule(pScrn, "ddc");
2936 + if (pI830->vesa->monitor)
2937 + xfree(pI830->vesa->monitor);
2938 + pI830->vesa->monitor = vbeDoEDID(pI830->pVbe, pDDCModule);
2939 + xf86UnloadSubModule(pDDCModule);
2940 + if ((pScrn->monitor->DDC = pI830->vesa->monitor) != NULL)
2941 + xf86SetDDCproperties(pScrn, pI830->vesa->monitor);
2943 + /* No DDC, so get out of here, and continue to use the current settings */
2946 + if (!(DDCclock = I830UseDDC(pScrn)))
2949 + /* Revalidate the modes */
2952 + * Note: VBE modes (> 0x7f) won't work with Intel's extended BIOS
2955 + pScrn->modePool = I830GetModePool(pScrn, pI830->pVbe, pI830->vbeInfo);
2957 + if (!pScrn->modePool) {
2958 + /* This is bad, which would cause the Xserver to exit, maybe
2959 + * we should default to a 640x480 @ 60Hz mode here ??? */
2960 + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
2961 + "No Video BIOS modes for chosen depth.\n");
2965 + SetPipeAccess(pScrn);
2966 + VBESetModeNames(pScrn->modePool);
2968 + if (pScrn->videoRam > (pI830->vbeInfo->TotalMemory * 64))
2969 + memsize = pI830->vbeInfo->TotalMemory * 64;
2971 + memsize = pScrn->videoRam;
2973 + VBEValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, NULL,
2974 + NULL, 0, MAX_DISPLAY_PITCH, 1,
2975 + 0, MAX_DISPLAY_HEIGHT,
2976 + pScrn->display->virtualX,
2977 + pScrn->display->virtualY,
2978 + memsize, LOOKUP_BEST_REFRESH);
2980 +if (DDCclock > 0) {
2985 + int Clock = 100000000; /* incredible value */
2987 + for (pMon = pScrn->monitor->Modes; pMon != NULL; pMon = pMon->next) {
2988 + if ((pMon->HDisplay != p->HDisplay) ||
2989 + (pMon->VDisplay != p->VDisplay) ||
2990 + (pMon->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
2993 + /* Find lowest supported Clock for this resolution */
2994 + if (Clock > pMon->Clock)
2995 + Clock = pMon->Clock;
2998 + if (DDCclock < 2550 && Clock / 1000.0 > DDCclock) {
2999 + ErrorF("(%s,%s) mode clock %gMHz exceeds DDC maximum %dMHz\n",
3000 + p->name, pScrn->monitor->id,
3001 + Clock/1000.0, DDCclock);
3002 + p->status = MODE_BAD;
3005 + } while (p != NULL && p != pScrn->modes);
3008 + pScrn->displayWidth = displayWidth; /* restore old displayWidth */
3010 + xf86PruneDriverModes(pScrn);
3011 + I830PrintModes(pScrn);
3013 + if (!pI830->vesa->useDefaultRefresh)
3014 + I830SetModeParameters(pScrn, pI830->pVbe);
3016 + /* Now check if the previously used mode is o.k. for the current monitor.
3017 + * This allows VT switching to continue happily when not disconnecting
3018 + * and reconnecting monitors */
3020 + pScrn->currentMode = pScrn->modes;
3025 + if ((p->HDisplay == curHDisplay) &&
3026 + (p->VDisplay == curVDisplay) &&
3027 + (!(p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))) {
3028 + pScrn->currentMode = p; /* previous mode is o.k. */
3031 + } while (p != NULL && p != pScrn->modes);
3033 + /* Now readjust for panning if necessary */
3035 + pScrn->frameX0 = (pScrn->frameX0 + pScrn->frameX1 + 1 - pScrn->currentMode->HDisplay) / 2;
3037 + if (pScrn->frameX0 < 0)
3038 + pScrn->frameX0 = 0;
3040 + pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1;
3041 + if (pScrn->frameX1 >= pScrn->virtualX) {
3042 + pScrn->frameX0 = pScrn->virtualX - pScrn->currentMode->HDisplay;
3043 + pScrn->frameX1 = pScrn->virtualX - 1;
3046 + pScrn->frameY0 = (pScrn->frameY0 + pScrn->frameY1 + 1 - pScrn->currentMode->VDisplay) / 2;
3048 + if (pScrn->frameY0 < 0)
3049 + pScrn->frameY0 = 0;
3051 + pScrn->frameY1 = pScrn->frameY0 + pScrn->currentMode->VDisplay - 1;
3052 + if (pScrn->frameY1 >= pScrn->virtualY) {
3053 + pScrn->frameY0 = pScrn->virtualY - pScrn->currentMode->VDisplay;
3054 + pScrn->frameY1 = pScrn->virtualY - 1;
3062 +I830CheckModeSupport(ScrnInfoPtr pScrn, int x, int y, int mode)
3064 + I830Ptr pI830 = I830PTR(pScrn);
3067 + if (pI830->Clone) {
3068 + if (pI830->pipeDisplaySize[0].x2 != 0) {
3069 + if (x > pI830->pipeDisplaySize[0].x2 ||
3070 + y > pI830->pipeDisplaySize[0].y2) {
3071 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bad Clone Mode removing\n");
3075 + if (pI830->pipeDisplaySize[1].x2 != 0) {
3076 + if (x > pI830->pipeDisplaySize[1].x2 ||
3077 + y > pI830->pipeDisplaySize[1].y2) {
3078 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bad Clone Mode removing\n");
3088 * This gets called when gaining control of the VT, and from ScreenInit().
3090 @@ -4387,15 +5190,56 @@
3092 DPRINTF(PFX, "Enter VT\n");
3095 + * Only save state once per server generation since that's what most
3096 + * drivers do. Could change this to save state at each VT enter.
3098 + if (pI830->SaveGeneration != serverGeneration) {
3099 + pI830->SaveGeneration = serverGeneration;
3100 + SaveHWState(pScrn);
3103 + pI830->leaving = FALSE;
3105 if (IsPrimary(pScrn)) {
3107 + * This is needed for restoring from ACPI modes (especially S3)
3108 + * so that we warmboot the Video BIOS. Some platforms have problems,
3109 + * warm booting when we don't need to, so check that we can call
3110 + * the Video BIOS with our saved devices, and only when that fails,
3111 + * we'll warm boot it.
3113 + /* Check Pipe conf registers or possibly HTOTAL/VTOTAL for 0x00000000)*/
3114 + CARD32 temp = pI830->pipe ? INREG(PIPEBCONF) : INREG(PIPEACONF);
3115 + if (!I830Set640x480(pScrn) || !(temp & 0x80000000)) {
3116 + xf86Int10InfoPtr pInt;
3118 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3119 + "Detected resume, re-POSTing.\n");
3121 + pInt = xf86InitInt10(pI830->pEnt->index);
3123 + /* Now perform our warm boot */
3126 + xf86ExecX86int10 (pInt);
3127 + xf86FreeInt10 (pInt);
3128 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Re-POSTing via int10.\n");
3130 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3131 + "Re-POSTing via int10 failed, trying to continue.\n");
3135 + /* Finally, re-setup the display devices */
3136 if (!SetDisplayDevices(pScrn, pI830->operatingDevices)) {
3137 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3138 "Failed to switch to configured display devices\n");
3144 - /* Setup for checking lid status */
3145 + /* Setup for device monitoring status */
3146 pI830->monitorSwitch = INREG(SWF0) & 0x0000FFFF;
3148 if (IsPrimary(pScrn))
3149 @@ -4406,14 +5250,6 @@
3150 if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize,FALSE))
3151 SetBIOSMemSize(pScrn, pI830->newBIOSMemSize);
3154 - * Only save state once per server generation since that's what most
3155 - * drivers do. Could change this to save state at each VT enter.
3157 - if (pI830->SaveGeneration != serverGeneration) {
3158 - pI830->SaveGeneration = serverGeneration;
3159 - SaveHWState(pScrn);
3161 ResetState(pScrn, FALSE);
3162 SetHWOperatingState(pScrn);
3164 @@ -4423,8 +5259,13 @@
3165 pScrn->virtualY * pScrn->displayWidth * pI830->cpp);
3168 + /* Detect monitor change and switch to suitable mode */
3169 + if (!pI830->starting)
3170 + I830DetectMonitorChange(pScrn);
3172 if (!I830VESASetMode(pScrn, pScrn->currentMode))
3176 I830VideoSwitchModeAfter(pScrn, pScrn->currentMode);
3178 @@ -4441,6 +5282,8 @@
3180 if (pI830->directRenderingEnabled) {
3181 if (!pI830->starting) {
3182 + I830DRIResume(screenInfo.screens[scrnIndex]);
3184 I830EmitInvarientState(pScrn);
3185 I830RefreshRing(pScrn);
3187 @@ -4453,6 +5296,9 @@
3191 + if (pI830->checkDevices)
3192 + pI830->devicesTimer = TimerSet(NULL, 0, 1000, I830CheckDevicesTimer, pScrn);
3197 @@ -4460,8 +5306,6 @@
3198 I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
3203 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
3204 I830Ptr pI830 = I830PTR(pScrn);
3206 @@ -4469,13 +5313,8 @@
3207 DPRINTF(PFX, "I830BIOSSwitchMode: mode == %p\n", mode);
3209 /* Stops head pointer freezes for 845G */
3210 - if (!pI830->noAccel && (1 || IS_845G(pI830))) {
3212 - _head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK;
3213 - _tail = INREG(LP_RING + RING_TAIL) & I830_TAIL_MASK;
3215 - } while (_head != _tail);
3217 + if (!pI830->noAccel)
3218 + (*pI830->AccelInfoRec->Sync)(pScrn);
3221 #define BINDUNBIND 0
3222 @@ -4509,30 +5348,27 @@
3223 I830Ptr pI830 = I830PTR(pScrn);
3224 Bool on = xf86IsUnblank(mode);
3225 CARD32 temp, ctrl, base;
3228 DPRINTF(PFX, "I830BIOSSaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on));
3230 if (pScrn->vtSema) {
3231 - for (i = 0; i < pI830->availablePipes; i++) {
3239 - if (pI830->planeEnabled[i]) {
3240 - temp = INREG(ctrl);
3242 - temp |= DISPLAY_PLANE_ENABLE;
3244 - temp &= ~DISPLAY_PLANE_ENABLE;
3245 - OUTREG(ctrl, temp);
3246 - /* Flush changes */
3247 - temp = INREG(base);
3248 - OUTREG(base, temp);
3250 + if (pI830->pipe == 0) {
3257 + if (pI830->planeEnabled[pI830->pipe]) {
3258 + temp = INREG(ctrl);
3260 + temp |= DISPLAY_PLANE_ENABLE;
3262 + temp &= ~DISPLAY_PLANE_ENABLE;
3263 + OUTREG(ctrl, temp);
3264 + /* Flush changes */
3265 + temp = INREG(base);
3266 + OUTREG(base, temp);
3269 if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
3270 @@ -4625,6 +5461,10 @@
3271 I830BIOSLeaveVT(scrnIndex, 0);
3274 + if (pI830->devicesTimer)
3275 + TimerCancel(pI830->devicesTimer);
3276 + pI830->devicesTimer = NULL;
3278 DPRINTF(PFX, "\nUnmapping memory\n");
3279 I830UnmapMem(pScrn);
3280 vgaHWUnmapMem(pScrn);
3281 @@ -4661,9 +5501,6 @@
3282 pI830->overlayOn = NULL;
3285 - if (pI830->lidTimer)
3286 - TimerCancel(pI830->lidTimer);
3288 pScrn->vtSema = FALSE;
3289 pI830->closing = FALSE;
3290 pScreen->CloseScreen = pI830->CloseScreen;
3291 @@ -4743,58 +5580,232 @@
3295 +static int CountBits(int a)
3300 + for (i=0;i<8;i++) {
3309 -I830LidTimer(OsTimerPtr timer, CARD32 now, pointer arg)
3310 +I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
3312 ScrnInfoPtr pScrn = (ScrnInfoPtr) arg;
3313 I830Ptr pI830 = I830PTR(pScrn);
3316 if (pScrn->vtSema) {
3317 /* Check for monitor lid being closed/opened and act accordingly */
3318 - int temp = INREG(SWF0) & 0x0000FFFF;
3320 + CARD32 temp = INREG(SWF0) & 0x0000FFFF;
3323 + /* this avoids a BIOS call if possible */
3324 if (pI830->monitorSwitch != temp) {
3325 - int conf = pI830->operatingDevices;
3326 - xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3327 - "Detected possible lid operation, fixing up.\n");
3328 - if ((temp & 0x0808) == 0x0000) {
3329 - /* LFP (PIPE A or B) GOING OFF - PROBABLE LID CLOSURE */
3330 - conf = pI830->operatingDevices & 0xF7F7;
3332 - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Lid is being closed.\n");
3336 - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Lid is being opened.\n");
3339 + I830Ptr pI8302 = NULL;
3340 + unsigned int toggle = GetToggleList(pScrn, 1);
3342 + GetToggleList(pScrn, 2);
3343 + GetToggleList(pScrn, 3);
3344 + GetToggleList(pScrn, 4);
3346 + if (IsPrimary(pScrn))
3349 + pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
3351 + if (xf86IsEntityShared(pScrn->entityList[0]))
3352 + pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
3354 + pI8301->lastDevice1 = pI8301->lastDevice2;
3355 + pI8301->lastDevice2 = pI8301->monitorSwitch;
3357 + if (CountBits(temp & 0xff) > 1) {
3358 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3359 + "Detected cloned pipe mode (A).\n");
3360 + if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone)
3361 + temp = pI8301->MonType2 << 8 | pI8301->MonType1;
3363 + if (CountBits((temp & 0xff00) >> 8) > 1) {
3364 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3365 + "Detected cloned pipe mode (B).\n");
3366 + if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone)
3367 + temp = pI8301->MonType2 << 8 | pI8301->MonType1;
3369 + if (pI8301->lastDevice1 && pI8301->lastDevice2) {
3370 + if ( ((pI8301->lastDevice1 & 0xFF00) == 0) &&
3371 + ((pI8301->lastDevice2 & 0x00FF) == 0) ) {
3372 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3373 + "Detected last devices (1).\n");
3375 + } else if ( ((pI8301->lastDevice2 & 0xFF00) == 0) &&
3376 + ((pI8301->lastDevice1 & 0x00FF) == 0) ) {
3377 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3378 + "Detected last devices (2).\n");
3385 + ((CountBits(pI830->lastDevice1 & 0xff) > 1) ||
3386 + ((CountBits((pI830->lastDevice1 & 0xff00) >> 8) > 1))) ) {
3387 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3388 + "Detected duplicate (1).\n");
3392 + ((CountBits(pI830->lastDevice2 & 0xff) > 1) ||
3393 + ((CountBits((pI830->lastDevice2 & 0xff00) >> 8) > 1))) ) {
3394 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3395 + "Detected duplicate (2).\n");
3399 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3400 + "Requested display devices 0x%lx.\n", temp);
3403 + /* If the BIOS doesn't flip between CRT, LFP and CRT+LFP we fake
3404 + * it here as it seems some just flip between CRT and LFP. Ugh!
3406 + * So this pushes them onto Pipe B and clones the displays, which
3407 + * is what most BIOS' should be doing.
3409 + * Cloned pipe mode should only be done when running single head.
3411 + if (xf86IsEntityShared(pScrn->entityList[0]))
3416 + temp = pI8301->MonType2 << 8 | pI8301->MonType1;
3417 + else if (pI8301->lastDevice1 & 0xFF)
3418 + temp = pI8301->lastDevice1 << 8 | pI8301->lastDevice2;
3420 + temp = pI8301->lastDevice2 << 8 | pI8301->lastDevice1;
3423 + /* Jump to our next mode if we detect we've been here before */
3424 + if (temp == pI830->lastDevice1 || temp == pI830->lastDevice2) {
3426 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3427 + "Detected duplicate devices. Toggling (0x%lx)\n", temp);
3430 - /* If we've defined our own monitors, then get them and set them
3431 - * up when switching in single head mode, no effect in dual heads
3432 - * NOTE: This assumes that the LCD is always on Pipe B..... */
3433 - conf |= pI830->MonType1;
3434 - if (IsPrimary(pScrn)) {
3435 - if (!SetDisplayDevices(pScrn, conf))
3436 - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to switch "
3437 - "to configured display devices during lid operation.\n");
3438 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3439 + "Detected display change operation (0x%x, 0x%x, 0x%lx).\n",
3440 + pI8301->lastDevice1, pI8301->lastDevice2, temp);
3442 + /* So that if we close on the wrong config, we restore correctly */
3443 + pI830->specifiedMonitor = TRUE;
3445 + /* double check the display devices are what's configured and try
3446 + * not to do it twice because of dual heads with the code above */
3447 + if (!SetDisplayDevices(pScrn, temp)) {
3449 + ((CountBits(temp & 0xff) > 1) ||
3450 + (CountBits((temp & 0xff00) >> 8) > 1)) ) {
3451 + temp = pI8301->lastDevice2 | pI8301->lastDevice1;
3452 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Cloning failed, "
3453 + "trying dual pipe clone mode (0x%lx)\n", temp);
3454 + if (!SetDisplayDevices(pScrn, temp))
3455 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to switch "
3456 + "to configured display devices (0x%lx).\n", temp);
3458 + pI830->Clone = TRUE;
3461 - pI830->monitorSwitch = conf;
3463 + pI8301->monitorSwitch = temp;
3464 + pI8301->operatingDevices = temp;
3465 + if (xf86IsEntityShared(pScrn->entityList[0])) {
3466 + pI8302->operatingDevices = temp;
3467 + pI8302->monitorSwitch = temp;
3472 + int offset = pScrn->fbOffset + ((pScrn->frameY0 * pScrn->displayWidth + pScrn->frameX0) * pI830->cpp);
3474 + if (pI830->pipe == 0)
3475 + adjust = INREG(DSPABASE);
3477 + adjust = INREG(DSPBBASE);
3479 + if (adjust != offset) {
3480 + xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
3481 + "Fixing display offsets.\n");
3483 + I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
3488 + ScreenPtr pCursorScreen;
3491 + pCursorScreen = miPointerCurrentScreen();
3492 + if (pScrn->pScreen == pCursorScreen)
3493 + miPointerPosition(&x, &y);
3495 /* Now, when we're single head, make sure we switch pipes */
3496 - if (!(xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone)) {
3497 - if ((temp & 0xFF00) == 0x0000)
3499 - if ((temp & 0x00FF) == 0x0000)
3500 + if (!(xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) || cloned) {
3501 + if (temp & 0xFF00)
3506 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
3507 + "Primary pipe is now %s.\n", pI830->pipe ? "B" : "A");
3510 I830BIOSSwitchMode(pScrn->pScreen->myNum, pScrn->currentMode, 0);
3511 I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
3513 - /* Everything should be o.k. now, so make sure the HW cursor is
3514 - * on the correct pipe */
3515 - if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
3516 - pI830->CursorInfoRec->ShowCursor(pScrn);
3517 - pI830->cursorOn = TRUE;
3518 + if (xf86IsEntityShared(pScrn->entityList[0])) {
3519 + ScrnInfoPtr pScrn2;
3522 + if (IsPrimary(pScrn)) {
3523 + pScrn2 = pI830->entityPrivate->pScrn_2;
3524 + pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
3526 + pScrn2 = pI830->entityPrivate->pScrn_1;
3527 + pI8302 = I830PTR(pI830->entityPrivate->pScrn_1);
3530 + I830BIOSSwitchMode(pScrn2->pScreen->myNum, pScrn2->currentMode, 0);
3531 + I830BIOSAdjustFrame(pScrn2->pScreen->myNum, pScrn2->frameX0, pScrn2->frameY0, 0);
3532 + if (pScrn2->pScreen == pCursorScreen) {
3533 + int sigstate = xf86BlockSIGIO ();
3534 + miPointerWarpCursor(pScrn2->pScreen,x,y);
3536 + /* xf86Info.currentScreen = pScrn->pScreen; */
3537 + xf86UnblockSIGIO (sigstate);
3538 + if (pI8302->CursorInfoRec && !pI8302->SWCursor && pI8302->cursorOn) {
3539 + pI8302->CursorInfoRec->HideCursor(pScrn);
3540 + pI8302->CursorInfoRec->ShowCursor(pScrn);
3541 + pI8302->cursorOn = TRUE;
3546 + if (pScrn->pScreen == pCursorScreen) {
3547 + int sigstate = xf86BlockSIGIO ();
3548 + miPointerWarpCursor(pScrn->pScreen,x,y);
3550 + /* xf86Info.currentScreen = pScrn->pScreen; */
3551 + xf86UnblockSIGIO (sigstate);
3552 + if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
3553 + pI830->CursorInfoRec->HideCursor(pScrn);
3554 + pI830->CursorInfoRec->ShowCursor(pScrn);
3555 + pI830->cursorOn = TRUE;
3560 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i830_memory.c.i945 2005-08-18 19:40:12.000000000 -0400
3561 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i830_memory.c 2005-08-18 19:40:24.000000000 -0400
3563 /**************************************************************************
3565 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
3566 -Copyright © 2002 by David Dawes.
3567 +Copyright © 2002 by David Dawes.
3569 All Rights Reserved.
3572 end = pool->Free.End;
3574 start = ROUND_DOWN_TO(end - size, alignment);
3575 - needed = pool->Free.End - start;
3576 + needed = end - start;
3579 if (needed > pool->Free.Size) {
3580 @@ -123,10 +123,9 @@
3581 pool->Free.Start += needed;
3582 result->End = pool->Free.Start;
3584 - result->Start = ROUND_DOWN_TO(pool->Free.End - size, alignment) -
3586 - result->End = pool->Free.End - pool->Total.End;
3587 + result->Start = ROUND_DOWN_TO(pool->Free.End - size, alignment);
3588 pool->Free.End -= needed;
3589 + result->End = result->Start + needed;
3591 pool->Free.Size = pool->Free.End - pool->Free.Start;
3592 result->Size = result->End - result->Start;
3593 @@ -1236,7 +1235,7 @@
3595 i830Reg->Fence[nr] = 0;
3597 - if (IS_I915G(pI830))
3598 + if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))
3599 fence_mask = ~I915G_FENCE_START_MASK;
3601 fence_mask = ~I830_FENCE_START_MASK;
3602 @@ -1244,7 +1243,7 @@
3603 if (start & fence_mask) {
3604 xf86DrvMsg(X_WARNING, pScrn->scrnIndex,
3605 "SetFence: %d: start (0x%08x) is not %s aligned\n",
3606 - nr, start, (IS_I915G(pI830)) ? "1MB" : "512k");
3607 + nr, start, (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) ? "1MB" : "512k");
3611 @@ -1264,7 +1263,7 @@
3613 val = (start | FENCE_X_MAJOR | FENCE_VALID);
3615 - if (IS_I915G(pI830)) {
3616 + if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
3619 val |= I915G_FENCE_SIZE_1M;
3620 @@ -1325,7 +1324,7 @@
3624 - if (IS_I915G(pI830))
3625 + if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))
3626 fence_pitch = pitch / 512;
3628 fence_pitch = pitch / 128;
3629 --- xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c.i945 2005-08-18 19:40:12.000000000 -0400
3630 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c 2005-08-18 19:40:24.000000000 -0400
3633 * i830_video.c: i830/i845 Xv driver.
3635 - * Copyright © 2002 by Alan Hourihane and David Dawes
3636 + * Copyright © 2002 by Alan Hourihane and David Dawes
3639 * Alan Hourihane <alanh@tungstengraphics.com>
3645 +#include <X11/extensions/Xv.h>
3647 #include "xaalocal.h"
3648 #include "dixstruct.h"
3651 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
3653 -static Atom xvBrightness, xvContrast, xvColorKey;
3654 +static Atom xvBrightness, xvContrast, xvColorKey, xvPipe;
3655 static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;
3657 #define IMAGE_MAX_WIDTH 1440
3658 @@ -251,12 +251,20 @@
3659 {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
3662 -#define NUM_ATTRIBUTES 9
3663 +#define CLONE_ATTRIBUTES 1
3664 +static XF86AttributeRec CloneAttributes[CLONE_ATTRIBUTES] = {
3665 + {XvSettable | XvGettable, 0, 1, "XV_PIPE"}
3668 +#define NUM_ATTRIBUTES 3
3669 static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = {
3670 {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
3671 {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
3672 - {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
3673 + {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
3676 +#define GAMMA_ATTRIBUTES 6
3677 +static XF86AttributeRec GammaAttributes[GAMMA_ATTRIBUTES] = {
3678 {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA0"},
3679 {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA1"},
3680 {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA2"},
3690 * Select which pipe the overlay is enabled on.
3692 overlay->OCONFIG &= ~OVERLAY_PIPE_MASK;
3693 - if (pI830->pipe == 0)
3694 + if (pPriv->pipe == 0)
3695 overlay->OCONFIG |= OVERLAY_PIPE_A;
3697 overlay->OCONFIG |= OVERLAY_PIPE_B;
3699 I830Ptr pI830 = I830PTR(pScrn);
3700 XF86VideoAdaptorPtr adapt;
3701 I830PortPrivPtr pPriv;
3702 + XF86AttributePtr att;
3704 DPRINTF(PFX, "I830SetupImageVideo\n");
3708 adapt->type = XvWindowMask | XvInputMask | XvImageMask;
3709 adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
3710 - adapt->name = "Intel(R) 830M/845G/852GM/855GM/865G/915G Video Overlay";
3711 + adapt->name = "Intel(R) Video Overlay";
3712 adapt->nEncodings = 1;
3713 adapt->pEncodings = DummyEncoding;
3714 adapt->nFormats = NUM_FORMATS;
3715 @@ -600,12 +610,25 @@
3716 pPriv = (I830PortPrivPtr) (&adapt->pPortPrivates[1]);
3718 adapt->pPortPrivates[0].ptr = (pointer) (pPriv);
3719 - adapt->pAttributes = Attributes;
3720 + adapt->nAttributes = NUM_ATTRIBUTES;
3722 + adapt->nAttributes += CLONE_ATTRIBUTES;
3723 + if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))
3724 + adapt->nAttributes += GAMMA_ATTRIBUTES; /* has gamma */
3725 + adapt->pAttributes = xnfalloc(sizeof(XF86AttributeRec) * adapt->nAttributes);
3726 + /* Now copy the attributes */
3727 + att = adapt->pAttributes;
3728 + memcpy((char *)att, (char*)Attributes, sizeof(XF86AttributeRec)* NUM_ATTRIBUTES);
3729 + att+=NUM_ATTRIBUTES;
3730 + if (pI830->Clone) {
3731 + memcpy((char*)att, (char*)CloneAttributes, sizeof(XF86AttributeRec) * CLONE_ATTRIBUTES);
3732 + att+=CLONE_ATTRIBUTES;
3734 + if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
3735 + memcpy((char*)att, (char*)GammaAttributes, sizeof(XF86AttributeRec) * GAMMA_ATTRIBUTES);
3736 + att+=GAMMA_ATTRIBUTES;
3738 adapt->nImages = NUM_IMAGES;
3739 - if (IS_I915G(pI830))
3740 - adapt->nAttributes = 9; /* has gamma */
3742 - adapt->nAttributes = 3;
3743 adapt->pImages = Images;
3744 adapt->PutVideo = NULL;
3745 adapt->PutStill = NULL;
3747 pPriv->videoStatus = 0;
3748 pPriv->brightness = 0;
3749 pPriv->contrast = 64;
3750 + pPriv->pipe = pI830->pipe; /* default to current pipe */
3751 pPriv->linear = NULL;
3752 pPriv->currentBuf = 0;
3753 pPriv->gamma5 = 0xc0c0c0;
3754 @@ -655,7 +679,12 @@
3755 xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
3756 xvContrast = MAKE_ATOM("XV_CONTRAST");
3757 xvColorKey = MAKE_ATOM("XV_COLORKEY");
3758 - if (IS_I915G(pI830)) {
3760 + /* Allow the pipe to be switched from pipe A to B when in clone mode */
3762 + xvPipe = MAKE_ATOM("XV_PIPE");
3764 + if (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830)) {
3765 xvGamma0 = MAKE_ATOM("XV_GAMMA0");
3766 xvGamma1 = MAKE_ATOM("XV_GAMMA1");
3767 xvGamma2 = MAKE_ATOM("XV_GAMMA2");
3768 @@ -759,7 +788,21 @@
3769 overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
3770 if (pPriv->overlayOK)
3772 - } else if (attribute == xvGamma0 && (IS_I915G(pI830))) {
3773 + } else if (pI830->Clone && attribute == xvPipe) {
3774 + if ((value < 0) || (value > 1))
3776 + pPriv->pipe = value;
3778 + * Select which pipe the overlay is enabled on.
3780 + overlay->OCONFIG &= ~OVERLAY_PIPE_MASK;
3781 + if (pPriv->pipe == 0)
3782 + overlay->OCONFIG |= OVERLAY_PIPE_A;
3784 + overlay->OCONFIG |= OVERLAY_PIPE_B;
3785 + if (pPriv->overlayOK)
3787 + } else if (attribute == xvGamma0 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3788 /* Avoid video anomalies, so set gamma registers when overlay is off */
3789 /* We also clamp the values if they are outside the ranges */
3790 if (!*pI830->overlayOn) {
3791 @@ -768,35 +811,35 @@
3792 pPriv->gamma1 = pPriv->gamma0 + 0x7d;
3795 - } else if (attribute == xvGamma1 && (IS_I915G(pI830))) {
3796 + } else if (attribute == xvGamma1 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3797 if (!*pI830->overlayOn) {
3798 pPriv->gamma1 = value;
3799 if (pPriv->gamma1 - pPriv->gamma0 > 0x7d)
3800 pPriv->gamma0 = pPriv->gamma1 - 0x7d;
3803 - } else if (attribute == xvGamma2 && (IS_I915G(pI830))) {
3804 + } else if (attribute == xvGamma2 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3805 if (!*pI830->overlayOn) {
3806 pPriv->gamma2 = value;
3807 if (pPriv->gamma3 - pPriv->gamma2 > 0x7d)
3808 pPriv->gamma3 = pPriv->gamma2 + 0x7d;
3811 - } else if (attribute == xvGamma3 && (IS_I915G(pI830))) {
3812 + } else if (attribute == xvGamma3 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3813 if (!*pI830->overlayOn) {
3814 pPriv->gamma3 = value;
3815 if (pPriv->gamma3 - pPriv->gamma2 > 0x7d)
3816 pPriv->gamma2 = pPriv->gamma3 - 0x7d;
3819 - } else if (attribute == xvGamma4 && (IS_I915G(pI830))) {
3820 + } else if (attribute == xvGamma4 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3821 if (!*pI830->overlayOn) {
3822 pPriv->gamma4 = value;
3823 if (pPriv->gamma5 - pPriv->gamma4 > 0x7d)
3824 pPriv->gamma5 = pPriv->gamma4 + 0x7d;
3827 - } else if (attribute == xvGamma5 && (IS_I915G(pI830))) {
3828 + } else if (attribute == xvGamma5 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3829 if (!*pI830->overlayOn) {
3830 pPriv->gamma5 = value;
3831 if (pPriv->gamma5 - pPriv->gamma4 > 0x7d)
3833 attribute == xvGamma2 ||
3834 attribute == xvGamma3 ||
3835 attribute == xvGamma4 ||
3836 - attribute == xvGamma5) && (IS_I915G(pI830))) {
3837 + attribute == xvGamma5) && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3838 I830UpdateGamma(pScrn);
3841 @@ -846,17 +889,19 @@
3842 *value = pPriv->brightness;
3843 } else if (attribute == xvContrast) {
3844 *value = pPriv->contrast;
3845 - } else if (attribute == xvGamma0 && (IS_I915G(pI830))) {
3846 + } else if (pI830->Clone && attribute == xvPipe) {
3847 + *value = pPriv->pipe;
3848 + } else if (attribute == xvGamma0 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3849 *value = pPriv->gamma0;
3850 - } else if (attribute == xvGamma1 && (IS_I915G(pI830))) {
3851 + } else if (attribute == xvGamma1 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3852 *value = pPriv->gamma1;
3853 - } else if (attribute == xvGamma2 && (IS_I915G(pI830))) {
3854 + } else if (attribute == xvGamma2 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3855 *value = pPriv->gamma2;
3856 - } else if (attribute == xvGamma3 && (IS_I915G(pI830))) {
3857 + } else if (attribute == xvGamma3 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3858 *value = pPriv->gamma3;
3859 - } else if (attribute == xvGamma4 && (IS_I915G(pI830))) {
3860 + } else if (attribute == xvGamma4 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3861 *value = pPriv->gamma4;
3862 - } else if (attribute == xvGamma5 && (IS_I915G(pI830))) {
3863 + } else if (attribute == xvGamma5 && (IS_I915G(pI830) || IS_I915GM(pI830) || IS_I945G(pI830))) {
3864 *value = pPriv->gamma5;
3865 } else if (attribute == xvColorKey) {
3866 *value = pPriv->colorKey;
3870 I830CopyPlanarData(ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch,
3871 - int dstPitch, int srcH, int top, int left,
3872 + int srcPitch2, int dstPitch, int srcH, int top, int left,
3873 int h, int w, int id)
3875 I830Ptr pI830 = I830PTR(pScrn);
3878 unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3;
3880 - DPRINTF(PFX, "I830CopyPlanarData: srcPitch %d, dstPitch %d\n"
3881 - "nlines %d, npixels %d, top %d, left %d\n", srcPitch, dstPitch,
3882 + ErrorF("I830CopyPlanarData: srcPitch %d, srcPitch %d, dstPitch %d\n"
3883 + "nlines %d, npixels %d, top %d, left %d\n", srcPitch, srcPitch2, dstPitch,
3887 @@ -957,12 +1002,12 @@
3889 for (i = 0; i < h / 2; i++) {
3890 memcpy(dst2, src2, w / 2);
3891 - src2 += srcPitch >> 1;
3892 + src2 += srcPitch2;
3896 /* Copy U data for YV12, or V data for I420 */
3897 - src3 = buf + (srcH * srcPitch) + ((srcH * srcPitch) >> 2) +
3898 + src3 = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) +
3899 ((top * srcPitch) >> 2) + (left >> 1);
3900 ErrorF("src3 is %p, offset is %d\n", src3,
3901 (unsigned long)src3 - (unsigned long)buf);
3902 @@ -980,7 +1025,7 @@
3904 for (i = 0; i < h / 2; i++) {
3905 memcpy(dst3, src3, w / 2);
3906 - src3 += srcPitch >> 1;
3907 + src3 += srcPitch2;
3911 @@ -1125,70 +1170,126 @@
3912 I830OverlayRegPtr overlay =
3913 (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
3914 unsigned int swidth;
3915 + unsigned int mask, shift, offsety, offsetu;
3917 - DPRINTF(PFX, "I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
3918 + ErrorF("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
3921 if (!pPriv->overlayOK)
3924 + if (IS_I915G(pI830) || IS_I915GM(pI830)) {
3932 + if (pPriv->currentBuf == 0) {
3933 + offsety = pPriv->YBuf0offset;
3934 + offsetu = pPriv->UBuf0offset;
3936 + offsety = pPriv->YBuf1offset;
3937 + offsetu = pPriv->UBuf1offset;
3941 CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
3944 /* When in dual head with different bpp setups we need to refresh the
3945 * color key, so let's reset the video parameters and refresh here */
3946 - I830ResetVideo(pScrn);
3948 + if (pI830->entityPrivate)
3950 + I830ResetVideo(pScrn);
3955 - swidth = (width + 1) & ~1 & 0xfff;
3958 overlay->SWIDTH = swidth;
3960 overlay->SWIDTH |= (swidth & 0x7ff) << 16;
3962 - swidth = ((pPriv->YBuf0offset + width + 0x1f) >> 5) -
3963 - (pPriv->YBuf0offset >> 5) - 1;
3964 + swidth = ((offsety + width + mask) >> shift) -
3965 + (offsety >> shift);
3967 + if (IS_I915G(pI830) || IS_I915GM(pI830))
3970 - ErrorF("Y width is %d, swidthsw is %d\n", width, swidth);
3973 + ErrorF("Y width is %d, swidth is %d\n", width, swidth);
3975 overlay->SWIDTHSW = swidth << 2;
3977 - swidth = ((pPriv->UBuf0offset + (width / 2) + 0x1f) >> 5) -
3978 - (pPriv->UBuf0offset >> 5) - 1;
3979 + swidth = ((offsetu + (width / 2) + mask) >> shift) -
3980 + (offsetu >> shift);
3982 + if (IS_I915G(pI830) || IS_I915GM(pI830))
3987 ErrorF("UV width is %d, swidthsw is %d\n", width / 2, swidth);
3989 overlay->SWIDTHSW |= swidth << 18;
3991 + ErrorF("HEIGHT is %d\n",height);
3993 + overlay->SHEIGHT = height | ((height / 2) << 16);
3998 - /* XXX Check for i845 */
4000 - swidth = ((width + 31) & ~31) << 1;
4002 overlay->SWIDTH = swidth;
4003 - overlay->SWIDTHSW = swidth >> 3;
4005 + ErrorF("Y width is %d\n", swidth);
4007 + swidth = ((offsety + (width << 1) + mask) >> shift) -
4008 + (offsety >> shift);
4010 + if (IS_I915G(pI830) || IS_I915GM(pI830))
4015 + ErrorF("swidthsw is %d\n", swidth);
4017 + overlay->SWIDTHSW = swidth << 2;
4019 + ErrorF("HEIGHT is %d\n",height);
4021 + overlay->SHEIGHT = height;
4025 - overlay->SHEIGHT = height | ((height / 2) << 16);
4027 if (pPriv->oneLineMode) {
4028 /* change the coordinates with panel fitting active */
4029 dstBox->y1 = (((dstBox->y1 - 1) * pPriv->scaleRatio) >> 16) + 1;
4030 dstBox->y2 = ((dstBox->y2 * pPriv->scaleRatio) >> 16) + 1;
4033 /* Now, alter the height, so we scale to the correct size */
4034 - drw_h = dstBox->y2 - dstBox->y1;
4035 - if (drw_h < height) drw_h = height;
4036 + drw_h = ((drw_h * pPriv->scaleRatio) >> 16) + 1;
4038 + /* Keep the engine happy */
4039 + if (dstBox->y1 < 0) dstBox->y1 = 0;
4040 + if (dstBox->y2 < 0) dstBox->y2 = 0;
4044 overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1;
4046 overlay->DWINSZ = ((dstBox->y2 - dstBox->y1) << 16) |
4047 (dstBox->x2 - dstBox->x1);
4049 + ErrorF("dstBox: x1: %d, y1: %d, x2: %d, y2: %d\n", dstBox->x1, dstBox->y1,
4050 + dstBox->x2, dstBox->y2);
4052 /* buffer locations */
4053 overlay->OBUF_0Y = pPriv->YBuf0offset;
4054 overlay->OBUF_0U = pPriv->UBuf0offset;
4055 @@ -1252,8 +1353,8 @@
4057 * Y down-scale factor as a multiple of 4096.
4059 - xscaleFract = (src_w << 12) / drw_w;
4060 - yscaleFract = (src_h << 12) / drw_h;
4061 + xscaleFract = ((src_w - 1) << 12) / drw_w;
4062 + yscaleFract = ((src_h - 1) << 12) / drw_h;
4064 /* Calculate the UV scaling factor. */
4065 xscaleFractUV = xscaleFract / uvratio;
4066 @@ -1273,9 +1374,9 @@
4067 xscaleIntUV = xscaleFractUV >> 12;
4068 yscaleIntUV = yscaleFractUV >> 12;
4070 - ErrorF("xscale: 0x%x.%03x, yscale: 0x%x.%03x\n", xscaleInt,
4071 + ErrorF("xscale: %x.%03x, yscale: %x.%03x\n", xscaleInt,
4072 xscaleFract & 0xFFF, yscaleInt, yscaleFract & 0xFFF);
4073 - ErrorF("UV xscale: 0x%x.%03x, UV yscale: 0x%x.%03x\n", xscaleIntUV,
4074 + ErrorF("UV xscale: %x.%03x, UV yscale: %x.%03x\n", xscaleIntUV,
4075 xscaleFractUV & 0xFFF, yscaleIntUV, yscaleFractUV & 0xFFF);
4077 newval = (xscaleInt << 16) |
4078 @@ -1385,13 +1486,9 @@
4081 FBLinearPtr new_linear;
4082 - int bytespp = pScrn->bitsPerPixel >> 3;
4084 DPRINTF(PFX, "I830AllocateMemory\n");
4086 - /* convert size in bytes into number of pixels */
4087 - size = (size + bytespp - 1) / bytespp;
4090 if (linear->size >= size)
4092 @@ -1438,7 +1535,7 @@
4093 I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
4094 ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
4095 INT32 x1, x2, y1, y2;
4096 - int srcPitch, dstPitch;
4097 + int srcPitch, srcPitch2 = 0, dstPitch;
4098 int top, left, npixels, nlines, size, loops;
4101 @@ -1448,7 +1545,7 @@
4103 if (pI830->entityPrivate) {
4104 if (pI830->entityPrivate->XvInUse != -1 &&
4105 - pI830->entityPrivate->XvInUse != pI830->pipe) {
4106 + pI830->entityPrivate->XvInUse != pPriv->pipe) {
4108 if (!noPanoramiXExtension) {
4109 return Success; /* faked for trying to share it */
4110 @@ -1459,9 +1556,16 @@
4114 - pI830->entityPrivate->XvInUse = pI830->pipe;
4115 + pI830->entityPrivate->XvInUse = pPriv->pipe;
4118 + /* overlay limits */
4119 + if(src_w > (drw_w * 7))
4120 + drw_w = src_w * 7;
4122 + if(src_h > (drw_h * 7))
4123 + drw_h = src_h * 7;
4128 @@ -1486,21 +1590,22 @@
4131 srcPitch = (width + 3) & ~3;
4132 - dstPitch = ((width / 2) + 255) & ~255; /* of chroma */
4133 + srcPitch2 = ((width >> 1) + 3) & ~3;
4134 + dstPitch = ((width / 2) + 63) & ~63; /* of chroma */
4135 size = dstPitch * height * 3;
4140 - srcPitch = (width << 1);
4141 - dstPitch = (srcPitch + 255) & ~255;
4142 + srcPitch = width << 1;
4143 + dstPitch = (srcPitch + 63) & ~63; /* of chroma */
4144 size = dstPitch * height;
4147 ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size);
4149 - if (!(pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear,
4150 - size * 2 / pI830->cpp)))
4151 + /* size is multiplied by 2 because we have two buffers that are flipping */
4152 + if (!(pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear, size * 2 / pI830->cpp)))
4155 /* fixup pointers */
4156 @@ -1549,7 +1654,7 @@
4159 nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
4160 - I830CopyPlanarData(pScrn, buf, srcPitch, dstPitch, height, top, left,
4161 + I830CopyPlanarData(pScrn, buf, srcPitch, srcPitch2, dstPitch, height, top, left,
4162 nlines, npixels, id);
4165 @@ -1605,21 +1710,13 @@
4170 size = (*w + 3) & ~3;
4172 - size = (*w + 255) & ~255;
4180 tmp = ((*w >> 1) + 3) & ~3;
4182 - tmp = ((*w >> 1) + 255) & ~255;
4185 pitches[1] = pitches[2] = tmp;
4187 @@ -1836,7 +1933,7 @@
4189 if (pI830->entityPrivate) {
4190 if (pI830->entityPrivate->XvInUse != -1 &&
4191 - pI830->entityPrivate->XvInUse != pI830->pipe) {
4192 + pI830->entityPrivate->XvInUse != pI830Priv->pipe) {
4194 if (!noPanoramiXExtension) {
4195 return Success; /* faked for trying to share it */
4196 @@ -1847,7 +1944,7 @@
4200 - pI830->entityPrivate->XvInUse = pI830->pipe;
4201 + pI830->entityPrivate->XvInUse = pI830Priv->pipe;
4205 @@ -1978,7 +2075,7 @@
4209 - if (pI830->pipe == 0) {
4210 + if (pPriv->pipe == 0) {
4211 if (INREG(PIPEACONF) & PIPEACONF_DOUBLE_WIDE) {
4212 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
4213 "Disabling XVideo output because Pipe A is in double-wide mode.\n");
4214 @@ -1990,7 +2087,7 @@
4218 - if (pI830->pipe == 1) {
4219 + if (pPriv->pipe == 1) {
4220 if (INREG(PIPEBCONF) & PIPEBCONF_DOUBLE_WIDE) {
4221 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
4222 "Disabling XVideo output because Pipe B is in double-wide mode.\n");
4223 @@ -2002,12 +2099,13 @@
4227 - /* Check we are on pipe B and have an LFP connected */
4228 - if ((pI830->pipe == 1) && (pI830->operatingDevices & (PIPE_LFP << 8))) {
4229 - size = INREG(PIPEBSRC);
4230 + /* Check we have an LFP connected */
4231 + if ((pPriv->pipe == 1 && pI830->operatingDevices & (PIPE_LFP << 8)) ||
4232 + (pPriv->pipe == 0 && pI830->operatingDevices & PIPE_LFP) ) {
4233 + size = pI830->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
4234 hsize = (size >> 16) & 0x7FF;
4235 vsize = size & 0x7FF;
4236 - active = INREG(VTOTAL_B) & 0x7FF;
4237 + active = pI830->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
4239 if (vsize < active && hsize > 1024)
4240 I830SetOneLineModeRatio(pScrn);
4241 --- /dev/null 2004-06-24 14:04:38.000000000 -0400
4242 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i830_modes.c 2005-08-18 19:40:24.000000000 -0400
4244 +#define DEBUG_VERB 2
4246 + * Copyright © 2002 David Dawes
4248 + * Permission is hereby granted, free of charge, to any person obtaining a
4249 + * copy of this software and associated documentation files (the "Software"),
4250 + * to deal in the Software without restriction, including without limitation
4251 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4252 + * and/or sell copies of the Software, and to permit persons to whom the
4253 + * Software is furnished to do so, subject to the following conditions:
4255 + * The above copyright notice and this permission notice shall be included in
4256 + * all copies or substantial portions of the Software.
4258 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4259 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4260 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4261 + * THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
4262 + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
4263 + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
4266 + * Except as contained in this notice, the name of the author(s) shall
4267 + * not be used in advertising or otherwise to promote the sale, use or other
4268 + * dealings in this Software without prior written authorization from
4271 + * Authors: David Dawes <dawes@xfree86.org>
4273 + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/vbe/vbeModes.c,v 1.6 2002/11/02 01:38:25 dawes Exp $
4276 + * Modified by Alan Hourihane <alanh@tungstengraphics.com>
4277 + * to support extended BIOS modes for the Intel chipsets
4281 +#include "xf86_ansic.h"
4283 +#include "vbeModes.h"
4288 +#define rint(x) floor(x)
4290 +#define MARGIN_PERCENT 1.8 /* % of active vertical image */
4291 +#define CELL_GRAN 8.0 /* assumed character cell granularity */
4292 +#define MIN_PORCH 1 /* minimum front porch */
4293 +#define V_SYNC_RQD 3 /* width of vsync in lines */
4294 +#define H_SYNC_PERCENT 8.0 /* width of hsync as % of total line */
4295 +#define MIN_VSYNC_PLUS_BP 550.0 /* min time of vsync + back porch (microsec) */
4296 +#define M 600.0 /* blanking formula gradient */
4297 +#define C 40.0 /* blanking formula offset */
4298 +#define K 128.0 /* blanking formula scaling factor */
4299 +#define J 20.0 /* blanking formula scaling factor */
4301 +/* C' and M' are part of the Blanking Duty Cycle computation */
4303 +#define C_PRIME (((C - J) * K/256.0) + J)
4304 +#define M_PRIME (K/256.0 * M)
4306 +extern const int i830refreshes[];
4308 +static DisplayModePtr
4309 +I830GetGTF (int h_pixels, int v_lines, float freq,
4310 + int interlaced, int margins)
4312 + float h_pixels_rnd;
4313 + float v_lines_rnd;
4314 + float v_field_rate_rqd;
4316 + float bottom_margin;
4318 + float h_period_est;
4319 + float vsync_plus_bp;
4320 + float v_back_porch;
4321 + float total_v_lines;
4322 + float v_field_rate_est;
4324 + float v_field_rate;
4325 + float v_frame_rate;
4326 + float left_margin;
4327 + float right_margin;
4328 + float total_active_pixels;
4329 + float ideal_duty_cycle;
4331 + float total_pixels;
4336 + float h_front_porch;
4337 + float v_odd_front_porch_lines;
4338 + char modename[20];
4341 + m = xnfcalloc(sizeof(DisplayModeRec), 1);
4344 + /* 1. In order to give correct results, the number of horizontal
4345 + * pixels requested is first processed to ensure that it is divisible
4346 + * by the character size, by rounding it to the nearest character
4349 + * [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND])
4352 + h_pixels_rnd = rint((float) h_pixels / CELL_GRAN) * CELL_GRAN;
4355 + /* 2. If interlace is requested, the number of vertical lines assumed
4356 + * by the calculation must be halved, as the computation calculates
4357 + * the number of vertical lines per field. In either case, the
4358 + * number of lines is rounded to the nearest integer.
4360 + * [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0),
4361 + * ROUND([V LINES],0))
4364 + v_lines_rnd = interlaced ?
4365 + rint((float) v_lines) / 2.0 :
4366 + rint((float) v_lines);
4368 + /* 3. Find the frame rate required:
4370 + * [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2,
4374 + v_field_rate_rqd = interlaced ? (freq * 2.0) : (freq);
4376 + /* 4. Find number of lines in Top margin:
4378 + * [TOP MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
4379 + * ROUND(([MARGIN%]/100*[V LINES RND]),0),
4383 + top_margin = margins ? rint(MARGIN_PERCENT / 100.0 * v_lines_rnd) : (0.0);
4385 + /* 5. Find number of lines in Bottom margin:
4387 + * [BOT MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
4388 + * ROUND(([MARGIN%]/100*[V LINES RND]),0),
4392 + bottom_margin = margins ? rint(MARGIN_PERCENT/100.0 * v_lines_rnd) : (0.0);
4394 + /* 6. If interlace is required, then set variable [INTERLACE]=0.5:
4396 + * [INTERLACE]=(IF([INT RQD?]="y",0.5,0))
4399 + interlace = interlaced ? 0.5 : 0.0;
4401 + /* 7. Estimate the Horizontal period
4403 + * [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000) /
4404 + * ([V LINES RND] + (2*[TOP MARGIN (LINES)]) +
4405 + * [MIN PORCH RND]+[INTERLACE]) * 1000000
4408 + h_period_est = (((1.0/v_field_rate_rqd) - (MIN_VSYNC_PLUS_BP/1000000.0))
4409 + / (v_lines_rnd + (2*top_margin) + MIN_PORCH + interlace)
4412 + /* 8. Find the number of lines in V sync + back porch:
4414 + * [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0)
4417 + vsync_plus_bp = rint(MIN_VSYNC_PLUS_BP/h_period_est);
4419 + /* 9. Find the number of lines in V back porch alone:
4421 + * [V BACK PORCH] = [V SYNC+BP] - [V SYNC RND]
4423 + * XXX is "[V SYNC RND]" a typo? should be [V SYNC RQD]?
4426 + v_back_porch = vsync_plus_bp - V_SYNC_RQD;
4428 + /* 10. Find the total number of lines in Vertical field period:
4430 + * [TOTAL V LINES] = [V LINES RND] + [TOP MARGIN (LINES)] +
4431 + * [BOT MARGIN (LINES)] + [V SYNC+BP] + [INTERLACE] +
4435 + total_v_lines = v_lines_rnd + top_margin + bottom_margin + vsync_plus_bp +
4436 + interlace + MIN_PORCH;
4438 + /* 11. Estimate the Vertical field frequency:
4440 + * [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000
4443 + v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0;
4445 + /* 12. Find the actual horizontal period:
4447 + * [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST])
4450 + h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est);
4452 + /* 13. Find the actual Vertical field frequency:
4454 + * [V FIELD RATE] = 1 / [H PERIOD] / [TOTAL V LINES] * 1000000
4457 + v_field_rate = 1.0 / h_period / total_v_lines * 1000000.0;
4459 + /* 14. Find the Vertical frame frequency:
4461 + * [V FRAME RATE] = (IF([INT RQD?]="y", [V FIELD RATE]/2, [V FIELD RATE]))
4464 + v_frame_rate = interlaced ? v_field_rate / 2.0 : v_field_rate;
4466 + /* 15. Find number of pixels in left margin:
4468 + * [LEFT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
4469 + * (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
4470 + * [CELL GRAN RND]),0)) * [CELL GRAN RND],
4474 + left_margin = margins ?
4475 + rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN :
4478 + /* 16. Find number of pixels in right margin:
4480 + * [RIGHT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
4481 + * (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
4482 + * [CELL GRAN RND]),0)) * [CELL GRAN RND],
4486 + right_margin = margins ?
4487 + rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN :
4490 + /* 17. Find total number of active pixels in image and left and right
4493 + * [TOTAL ACTIVE PIXELS] = [H PIXELS RND] + [LEFT MARGIN (PIXELS)] +
4494 + * [RIGHT MARGIN (PIXELS)]
4497 + total_active_pixels = h_pixels_rnd + left_margin + right_margin;
4499 + /* 18. Find the ideal blanking duty cycle from the blanking duty cycle
4502 + * [IDEAL DUTY CYCLE] = [C'] - ([M']*[H PERIOD]/1000)
4505 + ideal_duty_cycle = C_PRIME - (M_PRIME * h_period / 1000.0);
4507 + /* 19. Find the number of pixels in the blanking time to the nearest
4508 + * double character cell:
4510 + * [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS] *
4511 + * [IDEAL DUTY CYCLE] /
4512 + * (100-[IDEAL DUTY CYCLE]) /
4513 + * (2*[CELL GRAN RND])), 0))
4514 + * * (2*[CELL GRAN RND])
4517 + h_blank = rint(total_active_pixels *
4518 + ideal_duty_cycle /
4519 + (100.0 - ideal_duty_cycle) /
4520 + (2.0 * CELL_GRAN)) * (2.0 * CELL_GRAN);
4522 + /* 20. Find total number of pixels:
4524 + * [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)]
4527 + total_pixels = total_active_pixels + h_blank;
4529 + /* 21. Find pixel clock frequency:
4531 + * [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD]
4534 + pixel_freq = total_pixels / h_period;
4536 + /* 22. Find horizontal frequency:
4538 + * [H FREQ] = 1000 / [H PERIOD]
4541 + h_freq = 1000.0 / h_period;
4544 + /* Stage 1 computations are now complete; I should really pass
4545 + the results to another function and do the Stage 2
4546 + computations, but I only need a few more values so I'll just
4547 + append the computations here for now */
4551 + /* 17. Find the number of pixels in the horizontal sync period:
4553 + * [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS] /
4554 + * [CELL GRAN RND]),0))*[CELL GRAN RND]
4557 + h_sync = rint(H_SYNC_PERCENT/100.0 * total_pixels / CELL_GRAN) * CELL_GRAN;
4559 + /* 18. Find the number of pixels in the horizontal front porch period:
4561 + * [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)]
4564 + h_front_porch = (h_blank / 2.0) - h_sync;
4566 + /* 36. Find the number of lines in the odd front porch period:
4568 + * [V ODD FRONT PORCH(LINES)]=([MIN PORCH RND]+[INTERLACE])
4571 + v_odd_front_porch_lines = MIN_PORCH + interlace;
4573 + /* finally, pack the results in the DisplayMode struct */
4575 + m->HDisplay = (int) (h_pixels_rnd);
4576 + m->HSyncStart = (int) (h_pixels_rnd + h_front_porch);
4577 + m->HSyncEnd = (int) (h_pixels_rnd + h_front_porch + h_sync);
4578 + m->HTotal = (int) (total_pixels);
4580 + m->VDisplay = (int) (v_lines_rnd);
4581 + m->VSyncStart = (int) (v_lines_rnd + v_odd_front_porch_lines);
4582 + m->VSyncEnd = (int) (int) (v_lines_rnd + v_odd_front_porch_lines + V_SYNC_RQD);
4583 + m->VTotal = (int) (total_v_lines);
4585 + m->Clock = (int)(pixel_freq * 1000);
4586 + m->SynthClock = m->Clock;
4587 + m->HSync = h_freq;
4588 + m->VRefresh = freq;
4590 + snprintf(modename, sizeof(modename), "%dx%d", m->HDisplay,m->VDisplay);
4591 + m->name = xnfstrdup(modename);
4596 +static DisplayModePtr
4597 +CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
4600 + CARD16 major, minor;
4601 + VbeModeInfoBlock *mode;
4602 + DisplayModePtr p = NULL, pMode = NULL;
4603 + VbeModeInfoData *data;
4604 + Bool modeOK = FALSE;
4605 + ModeStatus status = MODE_OK;
4607 + major = (unsigned)(vbe->VESAVersion >> 8);
4608 + minor = vbe->VESAVersion & 0xff;
4610 + if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
4613 + /* Does the mode match the depth/bpp? */
4614 + /* Some BIOS's set BitsPerPixel to 15 instead of 16 for 15/16 */
4615 + if (VBE_MODE_USABLE(mode, flags) &&
4616 + ((pScrn->bitsPerPixel == 1 && !VBE_MODE_COLOR(mode)) ||
4617 + (mode->BitsPerPixel > 8 &&
4618 + (mode->RedMaskSize + mode->GreenMaskSize +
4619 + mode->BlueMaskSize) == pScrn->depth &&
4620 + mode->BitsPerPixel == pScrn->bitsPerPixel) ||
4621 + (mode->BitsPerPixel == 15 && pScrn->depth == 15) ||
4622 + (mode->BitsPerPixel <= 8 &&
4623 + mode->BitsPerPixel == pScrn->bitsPerPixel))) {
4625 + xf86ErrorFVerb(DEBUG_VERB, "*");
4628 + if (mode->XResolution && mode->YResolution &&
4629 + !I830CheckModeSupport(pScrn, mode->XResolution, mode->YResolution, id))
4634 + * Check if there's a valid monitor mode that this one can be matched
4635 + * up with from the 'specified' modes list.
4638 + for (p = pScrn->monitor->Modes; p != NULL; p = p->next) {
4639 + if ((p->type != 0) ||
4640 + (p->HDisplay != mode->XResolution) ||
4641 + (p->VDisplay != mode->YResolution) ||
4642 + (p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
4644 + status = xf86CheckModeForMonitor(p, pScrn->monitor);
4645 + if (status == MODE_OK) {
4651 + pMode = xnfcalloc(sizeof(DisplayModeRec), 1);
4652 + memcpy((char*)pMode,(char*)p,sizeof(DisplayModeRec));
4653 + pMode->name = xnfstrdup(p->name);
4658 + * Now, check if there's a valid monitor mode that this one can be matched
4659 + * up with from the default modes list. i.e. VESA modes in xf86DefModes.c
4661 + if (modeOK && !pMode) {
4662 + int refresh = 0, calcrefresh = 0;
4663 + DisplayModePtr newMode = NULL;
4665 + for (p = pScrn->monitor->Modes; p != NULL; p = p->next) {
4666 + calcrefresh = (int)(((double)(p->Clock * 1000) /
4667 + (double)(p->HTotal * p->VTotal)) * 100);
4668 + if ((p->type != M_T_DEFAULT) ||
4669 + (p->HDisplay != mode->XResolution) ||
4670 + (p->VDisplay != mode->YResolution) ||
4671 + (p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
4673 + status = xf86CheckModeForMonitor(p, pScrn->monitor);
4674 + if (status == MODE_OK) {
4675 + if (calcrefresh > refresh) {
4676 + refresh = calcrefresh;
4683 + pMode = xnfcalloc(sizeof(DisplayModeRec), 1);
4684 + memcpy((char*)pMode,(char*)newMode,sizeof(DisplayModeRec));
4685 + pMode->name = xnfstrdup(newMode->name);
4690 + * Check if there's a valid monitor mode that this one can be matched
4691 + * up with. The actual matching is done later.
4693 + if (modeOK && !pMode) {
4694 + float vrefresh = 0.0f;
4697 + for (i=0;i<pScrn->monitor->nVrefresh;i++) {
4699 + for (vrefresh = pScrn->monitor->vrefresh[i].hi;
4700 + vrefresh >= pScrn->monitor->vrefresh[i].lo; vrefresh -= 1.0f) {
4702 + if (vrefresh != (float)0.0f) {
4703 + float best_vrefresh;
4706 + /* Find the best refresh for the Intel chipsets */
4707 + int_vrefresh = I830GetBestRefresh(pScrn, (int)vrefresh);
4708 + best_vrefresh = (float)i830refreshes[int_vrefresh];
4710 + /* Now, grab the best mode from the available refresh */
4711 + pMode = I830GetGTF(mode->XResolution, mode->YResolution,
4712 + best_vrefresh, 0, 0);
4714 + pMode->type = M_T_BUILTIN;
4716 + status = xf86CheckModeForMonitor(pMode, pScrn->monitor);
4717 + if (status == MODE_OK) {
4719 + if (pMode->Clock * 1000 <= mode->MaxPixelClock)
4727 + pMode->status = status;
4731 + if (modeOK) break;
4733 + if (modeOK) break;
4737 + xf86ErrorFVerb(DEBUG_VERB,
4738 + "Mode: %x (%dx%d)\n", id, mode->XResolution, mode->YResolution);
4739 + xf86ErrorFVerb(DEBUG_VERB,
4740 + " ModeAttributes: 0x%x\n", mode->ModeAttributes);
4741 + xf86ErrorFVerb(DEBUG_VERB,
4742 + " WinAAttributes: 0x%x\n", mode->WinAAttributes);
4743 + xf86ErrorFVerb(DEBUG_VERB,
4744 + " WinBAttributes: 0x%x\n", mode->WinBAttributes);
4745 + xf86ErrorFVerb(DEBUG_VERB,
4746 + " WinGranularity: %d\n", mode->WinGranularity);
4747 + xf86ErrorFVerb(DEBUG_VERB,
4748 + " WinSize: %d\n", mode->WinSize);
4749 + xf86ErrorFVerb(DEBUG_VERB,
4750 + " WinASegment: 0x%x\n", mode->WinASegment);
4751 + xf86ErrorFVerb(DEBUG_VERB,
4752 + " WinBSegment: 0x%x\n", mode->WinBSegment);
4753 + xf86ErrorFVerb(DEBUG_VERB,
4754 + " WinFuncPtr: 0x%lx\n", mode->WinFuncPtr);
4755 + xf86ErrorFVerb(DEBUG_VERB,
4756 + " BytesPerScanline: %d\n", mode->BytesPerScanline);
4757 + xf86ErrorFVerb(DEBUG_VERB,
4758 + " XResolution: %d\n", mode->XResolution);
4759 + xf86ErrorFVerb(DEBUG_VERB,
4760 + " YResolution: %d\n", mode->YResolution);
4761 + xf86ErrorFVerb(DEBUG_VERB,
4762 + " XCharSize: %d\n", mode->XCharSize);
4763 + xf86ErrorFVerb(DEBUG_VERB,
4764 + " YCharSize: %d\n", mode->YCharSize);
4765 + xf86ErrorFVerb(DEBUG_VERB,
4766 + " NumberOfPlanes: %d\n", mode->NumberOfPlanes);
4767 + xf86ErrorFVerb(DEBUG_VERB,
4768 + " BitsPerPixel: %d\n", mode->BitsPerPixel);
4769 + xf86ErrorFVerb(DEBUG_VERB,
4770 + " NumberOfBanks: %d\n", mode->NumberOfBanks);
4771 + xf86ErrorFVerb(DEBUG_VERB,
4772 + " MemoryModel: %d\n", mode->MemoryModel);
4773 + xf86ErrorFVerb(DEBUG_VERB,
4774 + " BankSize: %d\n", mode->BankSize);
4775 + xf86ErrorFVerb(DEBUG_VERB,
4776 + " NumberOfImages: %d\n", mode->NumberOfImages);
4777 + xf86ErrorFVerb(DEBUG_VERB,
4778 + " RedMaskSize: %d\n", mode->RedMaskSize);
4779 + xf86ErrorFVerb(DEBUG_VERB,
4780 + " RedFieldPosition: %d\n", mode->RedFieldPosition);
4781 + xf86ErrorFVerb(DEBUG_VERB,
4782 + " GreenMaskSize: %d\n", mode->GreenMaskSize);
4783 + xf86ErrorFVerb(DEBUG_VERB,
4784 + " GreenFieldPosition: %d\n", mode->GreenFieldPosition);
4785 + xf86ErrorFVerb(DEBUG_VERB,
4786 + " BlueMaskSize: %d\n", mode->BlueMaskSize);
4787 + xf86ErrorFVerb(DEBUG_VERB,
4788 + " BlueFieldPosition: %d\n", mode->BlueFieldPosition);
4789 + xf86ErrorFVerb(DEBUG_VERB,
4790 + " RsvdMaskSize: %d\n", mode->RsvdMaskSize);
4791 + xf86ErrorFVerb(DEBUG_VERB,
4792 + " RsvdFieldPosition: %d\n", mode->RsvdFieldPosition);
4793 + xf86ErrorFVerb(DEBUG_VERB,
4794 + " DirectColorModeInfo: %d\n", mode->DirectColorModeInfo);
4796 + xf86ErrorFVerb(DEBUG_VERB,
4797 + " PhysBasePtr: 0x%lx\n", mode->PhysBasePtr);
4799 + xf86ErrorFVerb(DEBUG_VERB,
4800 + " LinBytesPerScanLine: %d\n", mode->LinBytesPerScanLine);
4801 + xf86ErrorFVerb(DEBUG_VERB,
4802 + " BnkNumberOfImagePages: %d\n", mode->BnkNumberOfImagePages);
4803 + xf86ErrorFVerb(DEBUG_VERB,
4804 + " LinNumberOfImagePages: %d\n", mode->LinNumberOfImagePages);
4805 + xf86ErrorFVerb(DEBUG_VERB,
4806 + " LinRedMaskSize: %d\n", mode->LinRedMaskSize);
4807 + xf86ErrorFVerb(DEBUG_VERB,
4808 + " LinRedFieldPosition: %d\n", mode->LinRedFieldPosition);
4809 + xf86ErrorFVerb(DEBUG_VERB,
4810 + " LinGreenMaskSize: %d\n", mode->LinGreenMaskSize);
4811 + xf86ErrorFVerb(DEBUG_VERB,
4812 + " LinGreenFieldPosition: %d\n", mode->LinGreenFieldPosition);
4813 + xf86ErrorFVerb(DEBUG_VERB,
4814 + " LinBlueMaskSize: %d\n", mode->LinBlueMaskSize);
4815 + xf86ErrorFVerb(DEBUG_VERB,
4816 + " LinBlueFieldPosition: %d\n", mode->LinBlueFieldPosition);
4817 + xf86ErrorFVerb(DEBUG_VERB,
4818 + " LinRsvdMaskSize: %d\n", mode->LinRsvdMaskSize);
4819 + xf86ErrorFVerb(DEBUG_VERB,
4820 + " LinRsvdFieldPosition: %d\n", mode->LinRsvdFieldPosition);
4821 + xf86ErrorFVerb(DEBUG_VERB,
4822 + " MaxPixelClock: %ld\n", mode->MaxPixelClock);
4827 + VBEFreeModeInfo(mode);
4833 + pMode->status = MODE_OK;
4834 + pMode->type = M_T_BUILTIN;
4836 + /* for adjust frame */
4837 + pMode->HDisplay = mode->XResolution;
4838 + pMode->VDisplay = mode->YResolution;
4840 + data = xnfcalloc(sizeof(VbeModeInfoData), 1);
4842 + data->data = mode;
4843 + pMode->PrivSize = sizeof(VbeModeInfoData);
4844 + pMode->Private = (INT32*)data;
4845 + pMode->next = NULL;
4850 + * Check the available BIOS modes, and extract those that match the
4851 + * requirements into the modePool. Note: modePool is a NULL-terminated
4856 +I830GetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe)
4858 + DisplayModePtr pMode, p = NULL, modePool = NULL;
4861 + for (i = 0; i < 0x7F; i++) {
4862 + if ((pMode = CheckMode(pScrn, pVbe, vbe, i, V_MODETYPE_VGA)) != NULL) {
4863 + ModeStatus status = MODE_OK;
4865 + /* Check the mode against a specified virtual size (if any) */
4866 + if (pScrn->display->virtualX > 0 &&
4867 + pMode->HDisplay > pScrn->display->virtualX) {
4868 + status = MODE_VIRTUAL_X;
4870 + if (pScrn->display->virtualY > 0 &&
4871 + pMode->VDisplay > pScrn->display->virtualY) {
4872 + status = MODE_VIRTUAL_Y;
4874 + if (status != MODE_OK) {
4875 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4876 + "Not using mode \"%dx%d\" (%s)\n",
4877 + pMode->HDisplay, pMode->VDisplay,
4878 + xf86ModeStatusToString(status));
4885 + pMode->prev = NULL;
4894 + * Go through the monitor modes and selecting the best set of
4895 + * parameters for each BIOS mode. Note: This is only supported in
4896 + * VBE version 3.0 or later.
4899 +I830SetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
4901 + DisplayModePtr pMode;
4902 + VbeModeInfoData *data;
4904 + pMode = pScrn->modes;
4908 + data = (VbeModeInfoData*)pMode->Private;
4909 + data->block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
4910 + data->block->HorizontalTotal = pMode->HTotal;
4911 + data->block->HorizontalSyncStart = pMode->HSyncStart;
4912 + data->block->HorizontalSyncEnd = pMode->HSyncEnd;
4913 + data->block->VerticalTotal = pMode->VTotal;
4914 + data->block->VerticalSyncStart = pMode->VSyncStart;
4915 + data->block->VerticalSyncEnd = pMode->VSyncEnd;
4916 + data->block->Flags = ((pMode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
4917 + ((pMode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
4918 + data->block->PixelClock = pMode->Clock * 1000;
4919 + /* XXX May not have this. */
4920 + clock = VBEGetPixelClock(pVbe, data->mode, data->block->PixelClock);
4922 + data->block->PixelClock = clock;
4924 + ErrorF("Setting clock %.2fMHz, closest is %.2fMHz\n",
4925 + (double)data->block->PixelClock / 1000000.0,
4926 + (double)clock / 1000000.0);
4928 + data->mode |= (1 << 11);
4929 + if (pMode->VRefresh != 0) {
4930 + data->block->RefreshRate = pMode->VRefresh * 100;
4932 + data->block->RefreshRate = (int)(((double)(data->block->PixelClock)/
4933 + (double)(pMode->HTotal * pMode->VTotal)) * 100);
4935 + xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4936 + "Attempting to use %2.2fHz refresh for mode \"%s\" (%x)\n",
4937 + (float)(((double)(data->block->PixelClock) / (double)(pMode->HTotal * pMode->VTotal))), pMode->name, data->mode);
4939 + ErrorF("Video Modeline: ID: 0x%x Name: %s %i %i %i %i - "
4940 + " %i %i %i %i %.2f MHz Refresh: %.2f Hz\n",
4941 + data->mode, pMode->name, pMode->HDisplay, pMode->HSyncStart,
4942 + pMode->HSyncEnd, pMode->HTotal, pMode->VDisplay,
4943 + pMode->VSyncStart,pMode->VSyncEnd,pMode->VTotal,
4944 + (double)data->block->PixelClock/1000000.0,
4945 + (double)data->block->RefreshRate/100);
4947 + pMode = pMode->next;
4948 + } while (pMode != pScrn->modes);
4952 +I830PrintModes(ScrnInfoPtr scrp)
4955 + float hsync, refresh = 0;
4956 + char *desc, *desc2, *prefix, *uprefix;
4961 + xf86DrvMsg(scrp->scrnIndex, scrp->virtualFrom, "Virtual size is %dx%d "
4962 + "(pitch %d)\n", scrp->virtualX, scrp->virtualY,
4963 + scrp->displayWidth);
4970 + desc = desc2 = "";
4971 + if (p->HSync > 0.0)
4973 + else if (p->HTotal > 0)
4974 + hsync = (float)p->Clock / (float)p->HTotal;
4977 + if (p->VTotal > 0)
4978 + refresh = hsync * 1000.0 / p->VTotal;
4979 + if (p->Flags & V_INTERLACE) {
4983 + if (p->Flags & V_DBLSCAN) {
4987 + if (p->VScan > 1) {
4988 + refresh /= p->VScan;
4989 + desc2 = " (VScan)";
4991 + if (p->VRefresh > 0.0)
4992 + refresh = p->VRefresh;
4993 + if (p->type & M_T_BUILTIN)
4994 + prefix = "Built-in mode";
4995 + else if (p->type & M_T_DEFAULT)
4996 + prefix = "Default mode";
4999 + if (p->type & M_T_USERDEF)
5004 + xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
5005 + "%s%s \"%s\"\n", uprefix, prefix, p->name);
5007 + xf86DrvMsg(scrp->scrnIndex, X_PROBED,
5008 + "%s%s %dx%d (unnamed)\n",
5009 + uprefix, prefix, p->HDisplay, p->VDisplay);
5011 + } while (p != NULL && p != scrp->modes);
5013 --- /dev/null 2004-06-24 14:04:38.000000000 -0400
5014 +++ xc/programs/Xserver/hw/xfree86/drivers/i810/i830_shadow.c 2005-08-18 19:40:24.000000000 -0400
5016 +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_shadow.c,v 1.3 2000/03/31 20:13:33 dawes Exp $ */
5019 + Copyright (c) 1999,2000 The XFree86 Project Inc.
5020 + based on code written by Mark Vojkovich <markv@valinux.com>
5024 + * Ported from the savage driver to the I830 by
5025 + * Helmar Spangenberg <hspangenberg@frey.de> and Dima Dorfman
5030 +#include "shadowfb.h"
5031 +#include "servermd.h"
5035 +I830RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
5037 + I830Ptr pI830 = I830PTR(pScrn);
5038 + int width, height, Bpp, FBPitch;
5039 + unsigned char *src, *dst;
5041 + Bpp = pScrn->bitsPerPixel >> 3;
5042 + FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
5045 + width = (pbox->x2 - pbox->x1) * Bpp;
5046 + height = pbox->y2 - pbox->y1;
5047 + src = pI830->shadowPtr + (pbox->y1 * pI830->shadowPitch) +
5049 + dst = pI830->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
5052 + memcpy(dst, src, width);
5054 + src += pI830->shadowPitch;
5063 +I830PointerMoved(int index, int x, int y)
5065 + ScrnInfoPtr pScrn = xf86Screens[index];
5066 + I830Ptr pI830 = I830PTR(pScrn);
5069 + if(pI830->rotate == 1) {
5070 + newX = pScrn->pScreen->height - y - 1;
5074 + newY = pScrn->pScreen->width - x - 1;
5077 + (*pI830->PointerMoved)(index, newX, newY);
5081 +I830RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
5083 + I830Ptr pI830 = I830PTR(pScrn);
5084 + int count, width, height, y1, y2, dstPitch, srcPitch;
5085 + CARD8 *dstPtr, *srcPtr, *src;
5088 + dstPitch = pScrn->displayWidth;
5089 + srcPitch = -pI830->rotate * pI830->shadowPitch;
5092 + width = pbox->x2 - pbox->x1;
5093 + y1 = pbox->y1 & ~3;
5094 + y2 = (pbox->y2 + 3) & ~3;
5095 + height = (y2 - y1) >> 2; /* in dwords */
5097 + if(pI830->rotate == 1) {
5098 + dstPtr = pI830->FbBase +
5099 + (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
5100 + srcPtr = pI830->shadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
5102 + dstPtr = pI830->FbBase +
5103 + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
5104 + srcPtr = pI830->shadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
5109 + dst = (CARD32*)dstPtr;
5112 + *(dst++) = src[0] | (src[srcPitch] << 8) |
5113 + (src[srcPitch * 2] << 16) |
5114 + (src[srcPitch * 3] << 24);
5115 + src += srcPitch * 4;
5117 + srcPtr += pI830->rotate;
5118 + dstPtr += dstPitch;
5127 +I830RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
5129 + I830Ptr pI830 = I830PTR(pScrn);
5130 + int count, width, height, y1, y2, dstPitch, srcPitch;
5131 + CARD16 *dstPtr, *srcPtr, *src;
5134 + dstPitch = pScrn->displayWidth;
5135 + srcPitch = -pI830->rotate * pI830->shadowPitch >> 1;
5138 + width = pbox->x2 - pbox->x1;
5139 + y1 = pbox->y1 & ~1;
5140 + y2 = (pbox->y2 + 1) & ~1;
5141 + height = (y2 - y1) >> 1; /* in dwords */
5143 + if(pI830->rotate == 1) {
5144 + dstPtr = (CARD16*)pI830->FbBase +
5145 + (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
5146 + srcPtr = (CARD16*)pI830->shadowPtr +
5147 + ((1 - y2) * srcPitch) + pbox->x1;
5149 + dstPtr = (CARD16*)pI830->FbBase +
5150 + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
5151 + srcPtr = (CARD16*)pI830->shadowPtr +
5152 + (y1 * srcPitch) + pbox->x2 - 1;
5157 + dst = (CARD32*)dstPtr;
5160 + *(dst++) = src[0] | (src[srcPitch] << 16);
5161 + src += srcPitch * 2;
5163 + srcPtr += pI830->rotate;
5164 + dstPtr += dstPitch;
5172 +/* this one could be faster */
5174 +I830RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
5176 + I830Ptr pI830 = I830PTR(pScrn);
5177 + int count, width, height, y1, y2, dstPitch, srcPitch;
5178 + CARD8 *dstPtr, *srcPtr, *src;
5181 + dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
5182 + srcPitch = -pI830->rotate * pI830->shadowPitch;
5185 + width = pbox->x2 - pbox->x1;
5186 + y1 = pbox->y1 & ~3;
5187 + y2 = (pbox->y2 + 3) & ~3;
5188 + height = (y2 - y1) >> 2; /* blocks of 3 dwords */
5190 + if(pI830->rotate == 1) {
5191 + dstPtr = pI830->FbBase +
5192 + (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
5193 + srcPtr = pI830->shadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
5195 + dstPtr = pI830->FbBase +
5196 + ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
5197 + srcPtr = pI830->shadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
5202 + dst = (CARD32*)dstPtr;
5205 + dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
5206 + (src[srcPitch] << 24);
5207 + dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
5208 + (src[srcPitch * 2] << 16) |
5209 + (src[(srcPitch * 2) + 1] << 24);
5210 + dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
5211 + (src[(srcPitch * 3) + 1] << 16) |
5212 + (src[(srcPitch * 3) + 2] << 24);
5214 + src += srcPitch * 4;
5216 + srcPtr += pI830->rotate * 3;
5217 + dstPtr += dstPitch;
5225 +I830RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
5227 + I830Ptr pI830 = I830PTR(pScrn);
5228 + int count, width, height, dstPitch, srcPitch;
5229 + CARD32 *dstPtr, *srcPtr, *src, *dst;
5231 + dstPitch = pScrn->displayWidth;
5232 + srcPitch = -pI830->rotate * pI830->shadowPitch >> 2;
5235 + width = pbox->x2 - pbox->x1;
5236 + height = pbox->y2 - pbox->y1;
5238 + if(pI830->rotate == 1) {
5239 + dstPtr = (CARD32*)pI830->FbBase +
5240 + (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
5241 + srcPtr = (CARD32*)pI830->shadowPtr +
5242 + ((1 - pbox->y2) * srcPitch) + pbox->x1;
5244 + dstPtr = (CARD32*)pI830->FbBase +
5245 + ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
5246 + srcPtr = (CARD32*)pI830->shadowPtr +
5247 + (pbox->y1 * srcPitch) + pbox->x2 - 1;
5258 + srcPtr += pI830->rotate;
5259 + dstPtr += dstPitch;