summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@fairlite.demon.co.uk>2004-06-22 14:28:46 +0000
committerAlan Hourihane <alanh@fairlite.demon.co.uk>2004-06-22 14:28:46 +0000
commit5ed7e6f8424236dd57d83f6ab1282693260969cb (patch)
treed34b866b0e45776b9eeeafb7663ba85c78853037 /src
parenta46e95722d3c2b9dfb9eacf9a390a7c47d427773 (diff)
i915 support
Dual Head support for i830, i855, i915. ARGB cursor support (including i810) for all chipsets.
Diffstat (limited to 'src')
-rw-r--r--src/common.h57
-rw-r--r--src/i810.h9
-rw-r--r--src/i810_accel.c85
-rw-r--r--src/i810_cursor.c83
-rw-r--r--src/i810_dri.c40
-rw-r--r--src/i810_driver.c82
-rw-r--r--src/i810_memory.c45
-rw-r--r--src/i810_reg.h29
-rw-r--r--src/i830.h75
-rw-r--r--src/i830_accel.c146
-rw-r--r--src/i830_common.h271
-rw-r--r--src/i830_cursor.c202
-rw-r--r--src/i830_dga.c9
-rw-r--r--src/i830_dri.c577
-rw-r--r--src/i830_dri.h80
-rw-r--r--src/i830_driver.c1784
-rw-r--r--src/i830_memory.c392
-rw-r--r--src/i830_video.c464
18 files changed, 2923 insertions, 1507 deletions
diff --git a/src/common.h b/src/common.h
index 9dbea332..1b98d695 100644
--- a/src/common.h
+++ b/src/common.h
@@ -27,7 +27,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/common.h,v 1.7 2003/06/18 13:14:17 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/common.h,v 1.9 2003/09/24 02:43:23 dawes Exp $ */
/*
* Authors:
@@ -79,7 +79,11 @@ extern const char *I810vbeSymbols[];
extern const char *I810ddcSymbols[];
extern const char *I810fbSymbols[];
extern const char *I810xaaSymbols[];
+#ifdef XF86DRI
+extern const char *I810driSymbols[];
+extern const char *I810drmSymbols[];
extern const char *I810shadowSymbols[];
+#endif
extern void I830DPRINTF_stub(const char *filename, int line,
const char *function, const char *fmt, ...);
@@ -111,7 +115,8 @@ extern void I830DPRINTF_stub(const char *filename, int line,
#define OUT_RING(n) do { \
if (I810_DEBUG & DEBUG_VERBOSE_RING) \
- ErrorF( "OUT_RING %x: %x, (mask %x)\n", outring, n, ringmask); \
+ ErrorF( "OUT_RING %lx: %x, (mask %x)\n", \
+ (unsigned long)(outring), (unsigned int)(n), ringmask); \
*(volatile unsigned int *)(virt + outring) = n; \
outring += 4; \
outring &= ringmask; \
@@ -119,7 +124,7 @@ extern void I830DPRINTF_stub(const char *filename, int line,
#if 1
#define ADVANCE_LP_RING() do { \
- RecPtr->LpRing.tail = outring; \
+ RecPtr->LpRing->tail = outring; \
if (outring & 0x07) \
ErrorF("ADVANCE_LP_RING: " \
"outring (0x%x) isn't on a QWord boundary", outring); \
@@ -127,7 +132,7 @@ extern void I830DPRINTF_stub(const char *filename, int line,
} while (0)
#else
#define ADVANCE_LP_RING() { \
- RecPtr->LpRing.tail = outring; \
+ RecPtr->LpRing->tail = outring; \
if (outring & 0x07) \
ErrorF("ADVANCE_LP_RING: " \
"outring (0x%x) isn't on a QWord boundary", outring); \
@@ -174,19 +179,19 @@ extern void I830DPRINTF_stub(const char *filename, int line,
if ((n) > 2 && (I810_DEBUG&DEBUG_ALWAYS_SYNC)) \
DO_RING_IDLE(); \
needed = (n) * 4; \
- if ((RecPtr->LpRing.tail > RecPtr->LpRing.tail_mask - AVOID_SIZE) || \
- (RecPtr->LpRing.tail + needed) > \
- RecPtr->LpRing.tail_mask - AVOID_SIZE) { \
- needed += RecPtr->LpRing.tail_mask + 1 - RecPtr->LpRing.tail; \
+ if ((RecPtr->LpRing->tail > RecPtr->LpRing->tail_mask - AVOID_SIZE) || \
+ (RecPtr->LpRing->tail + needed) > \
+ RecPtr->LpRing->tail_mask - AVOID_SIZE) { \
+ needed += RecPtr->LpRing->tail_mask + 1 - RecPtr->LpRing->tail; \
ErrorF("BEGIN_LP_RING: skipping last 64 bytes of " \
"ring (%d vs %d)\n", needed, (n) * 4); \
} \
- if (RecPtr->LpRing.space < needed) \
+ if (RecPtr->LpRing->space < needed) \
WaitRingFunc(pScrn, needed, 0); \
- RecPtr->LpRing.space -= needed; \
- outring = RecPtr->LpRing.tail; \
- ringmask = RecPtr->LpRing.tail_mask; \
- virt = RecPtr->LpRing.virtual_start; \
+ RecPtr->LpRing->space -= needed; \
+ outring = RecPtr->LpRing->tail; \
+ ringmask = RecPtr->LpRing->tail_mask; \
+ virt = RecPtr->LpRing->virtual_start; \
while (needed > (n) * 4) { \
ErrorF("BEGIN_LP_RING: putting MI_NOOP at 0x%x (remaining %d)\n", \
outring, needed - (n) * 4); \
@@ -207,12 +212,12 @@ extern void I830DPRINTF_stub(const char *filename, int line,
if ((n) > 2 && (I810_DEBUG&DEBUG_ALWAYS_SYNC)) \
DO_RING_IDLE(); \
needed = (n) * 4; \
- if (RecPtr->LpRing.space < needed) \
+ if (RecPtr->LpRing->space < needed) \
WaitRingFunc(pScrn, needed, 0); \
- RecPtr->LpRing.space -= needed; \
- outring = RecPtr->LpRing.tail; \
- ringmask = RecPtr->LpRing.tail_mask; \
- virt = RecPtr->LpRing.virtual_start; \
+ RecPtr->LpRing->space -= needed; \
+ outring = RecPtr->LpRing->tail; \
+ ringmask = RecPtr->LpRing->tail_mask; \
+ virt = RecPtr->LpRing->virtual_start; \
if (I810_DEBUG & DEBUG_VERBOSE_RING) \
ErrorF( "BEGIN_LP_RING %d in %s\n", n, FUNCTION_NAME);
@@ -227,21 +232,24 @@ extern void I830DPRINTF_stub(const char *filename, int line,
#define OUTREG8(addr, val) do { \
*(volatile CARD8 *)(RecPtr->MMIOBase + (addr)) = (val); \
if (I810_DEBUG&DEBUG_VERBOSE_OUTREG) { \
- ErrorF("OUTREG8(0x%x, 0x%x) in %s\n", addr, val, FUNCTION_NAME); \
+ ErrorF("OUTREG8(0x%lx, 0x%lx) in %s\n", (unsigned long)(addr), \
+ (unsigned long)(val), FUNCTION_NAME); \
} \
} while (0)
#define OUTREG16(addr, val) do { \
*(volatile CARD16 *)(RecPtr->MMIOBase + (addr)) = (val); \
if (I810_DEBUG&DEBUG_VERBOSE_OUTREG) { \
- ErrorF("OUTREG16(0x%x, 0x%x) in %s\n", addr, val, FUNCTION_NAME); \
+ ErrorF("OUTREG16(0x%lx, 0x%lx) in %s\n", (unsigned long)(addr), \
+ (unsigned long)(val), FUNCTION_NAME); \
} \
} while (0)
#define OUTREG(addr, val) do { \
*(volatile CARD32 *)(RecPtr->MMIOBase + (addr)) = (val); \
if (I810_DEBUG&DEBUG_VERBOSE_OUTREG) { \
- ErrorF("OUTREG(0x%x, 0x%x) in %s\n", addr, val, FUNCTION_NAME); \
+ ErrorF("OUTREG(0x%lx, 0x%lx) in %s\n", (unsigned long)(addr), \
+ (unsigned long)(val), FUNCTION_NAME); \
} \
} while (0)
@@ -292,6 +300,11 @@ extern int I810_DEBUG;
#define PCI_CHIP_I865_G_BRIDGE 0x2570
#endif
+#ifndef PCI_CHIP_I915_G
+#define PCI_CHIP_I915_G 0x2582
+#define PCI_CHIP_I915_G_BRIDGE 0x2580
+#endif
+
#define IS_I810(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I810 || \
pI810->PciInfo->chipType == PCI_CHIP_I810_DC100 || \
pI810->PciInfo->chipType == PCI_CHIP_I810_E)
@@ -300,6 +313,7 @@ extern int I810_DEBUG;
#define IS_845G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_845_G)
#define IS_I85X(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I855_GM)
#define IS_I865G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I865_G)
+#define IS_I915G(pI810) (pI810->PciInfo->chipType == PCI_CHIP_I915_G)
#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810))
@@ -312,6 +326,7 @@ extern int I810_DEBUG;
#define MIN_SCRATCH_BUFFER_SIZE KB(16)
#define MAX_SCRATCH_BUFFER_SIZE KB(64)
#define HWCURSOR_SIZE GTT_PAGE_SIZE
+#define HWCURSOR_SIZE_ARGB GTT_PAGE_SIZE * 4
#define OVERLAY_SIZE GTT_PAGE_SIZE
/* Use a 64x64 HW cursor */
diff --git a/src/i810.h b/src/i810.h
index 332cd81a..58345abc 100644
--- a/src/i810.h
+++ b/src/i810.h
@@ -162,9 +162,13 @@ typedef struct _I810Rec {
int auxPitch;
int auxPitchBits;
+ Bool CursorIsARGB;
int CursorOffset;
unsigned long CursorPhysical;
unsigned long CursorStart;
+ int CursorARGBOffset;
+ unsigned long CursorARGBPhysical;
+ unsigned long CursorARGBStart;
unsigned long OverlayPhysical;
unsigned long OverlayStart;
int colorKey;
@@ -184,7 +188,7 @@ typedef struct _I810Rec {
pciVideoPtr PciInfo;
PCITAG PciTag;
- I810RingBuffer LpRing;
+ I810RingBuffer *LpRing;
unsigned int BR[20];
int LmFreqSel;
@@ -195,6 +199,8 @@ typedef struct _I810Rec {
unsigned long DcacheOffset;
int HwcursKey;
unsigned long HwcursOffset;
+ int ARGBHwcursKey;
+ unsigned long ARGBHwcursOffset;
int GttBound;
@@ -235,6 +241,7 @@ typedef struct _I810Rec {
unsigned long backHandle;
unsigned long zHandle;
unsigned long cursorHandle;
+ unsigned long cursorARGBHandle;
unsigned long xvmcHandle;
unsigned long sysmemHandle;
Bool agpAcquired;
diff --git a/src/i810_accel.c b/src/i810_accel.c
index d8467424..ca74f966 100644
--- a/src/i810_accel.c
+++ b/src/i810_accel.c
@@ -25,7 +25,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c,v 1.19 2003/04/24 18:00:24 eich Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_accel.c,v 1.21 2004/01/02 20:22:17 dawes Exp $ */
/*
* Reformatted with GNU indent (2.2.8), using the following options:
@@ -48,47 +48,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86_ansic.h"
#include "xf86.h"
-
+#include "xaarop.h"
#include "i810.h"
-static unsigned int i810Rop[16] = {
- 0x00, /* GXclear */
- 0x88, /* GXand */
- 0x44, /* GXandReverse */
- 0xCC, /* GXcopy */
- 0x22, /* GXandInvert */
- 0xAA, /* GXnoop */
- 0x66, /* GXxor */
- 0xEE, /* GXor */
- 0x11, /* GXnor */
- 0x99, /* GXequiv */
- 0x55, /* GXinvert */
- 0xDD, /* GXorReverse */
- 0x33, /* GXcopyInvert */
- 0xBB, /* GXorInverted */
- 0x77, /* GXnand */
- 0xFF /* GXset */
-};
-
-static unsigned int i810PatternRop[16] = {
- 0x00, /* GXclear */
- 0xA0, /* GXand */
- 0x50, /* GXandReverse */
- 0xF0, /* GXcopy */
- 0x0A, /* GXandInvert */
- 0xAA, /* GXnoop */
- 0x5A, /* GXxor */
- 0xFA, /* GXor */
- 0x05, /* GXnor */
- 0xA5, /* GXequiv */
- 0x55, /* GXinvert */
- 0xF5, /* GXorReverse */
- 0x0F, /* GXcopyInvert */
- 0xAF, /* GXorInverted */
- 0x5F, /* GXnand */
- 0xFF /* GXset */
-};
-
static void I810SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
int pattx, int patty,
int fg, int bg, int rop,
@@ -130,10 +92,7 @@ I810AccelInit(ScreenPtr pScreen)
pI810->bufferOffset = 0;
infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
- /* There is a bit blt bug in 24 bpp. This is a problem, but
- * at least without the pixmap cache we can pass the test suite */
- if (pScrn->depth != 24)
- infoPtr->Flags |= PIXMAP_CACHE;
+ infoPtr->Flags |= PIXMAP_CACHE;
/* Sync
*/
@@ -227,7 +186,7 @@ int
I810WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis)
{
I810Ptr pI810 = I810PTR(pScrn);
- I810RingBuffer *ring = &(pI810->LpRing);
+ I810RingBuffer *ring = pI810->LpRing;
int iters = 0;
int start = 0;
int now = 0;
@@ -316,9 +275,9 @@ I810Sync(ScrnInfoPtr pScrn)
ADVANCE_LP_RING();
}
- I810WaitLpRing(pScrn, pI810->LpRing.mem.Size - 8, 0);
+ I810WaitLpRing(pScrn, pI810->LpRing->mem.Size - 8, 0);
- pI810->LpRing.space = pI810->LpRing.mem.Size - 8;
+ pI810->LpRing->space = pI810->LpRing->mem.Size - 8;
pI810->nextColorExpandBuf = 0;
}
@@ -334,7 +293,7 @@ I810SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
/* Color blit, p166 */
pI810->BR[13] = (BR13_SOLID_PATTERN |
- (i810PatternRop[rop] << 16) |
+ (XAAPatternROP[rop] << 16) |
(pScrn->displayWidth * pI810->cpp));
pI810->BR[16] = color;
}
@@ -380,7 +339,7 @@ I810SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
if (xdir == -1)
pI810->BR[13] |= BR13_RIGHT_TO_LEFT;
- pI810->BR[13] |= i810Rop[rop] << 16;
+ pI810->BR[13] |= XAACopyROP[rop] << 16;
pI810->BR[18] = 0;
}
@@ -401,9 +360,12 @@ I810SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
* This was developed empirically so it may not catch all
* cases.
*/
+#define I810_MWIDTH 8
+
if ( !(pI810->BR[13] & BR13_RIGHT_TO_LEFT) && (y2 - y1) < 3
- && (y2 - y1) >= 0 && (x2 - x1) <= (w + 4) && (w > 4))
- w = 4;
+ && (y2 - y1) >= 0 && (x2 - x1) <= (w + I810_MWIDTH)
+ && (w > I810_MWIDTH))
+ w = I810_MWIDTH;
do {
if (pI810->BR[13] & BR13_PITCH_SIGN_BIT) {
@@ -441,7 +403,10 @@ I810SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
break;
x2 += w;
x1 += w;
- w = w_back;
+ if (w_back > I810_MWIDTH)
+ w = I810_MWIDTH;
+ else
+ w = w_back;
} while (1);
}
@@ -460,9 +425,9 @@ I810SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
pI810->BR[18] = bg;
pI810->BR[19] = fg;
pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
- pI810->BR[13] |= i810PatternRop[rop] << 16;
+ pI810->BR[13] |= XAAPatternROP[rop] << 16;
if (bg == -1)
- pI810->BR[13] |= BR13_MONO_TRANSPCY;
+ pI810->BR[13] |= BR13_MONO_PATN_TRANS;
}
static void
@@ -524,7 +489,7 @@ I810SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
fg, bg, rop, planemask);
pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
- pI810->BR[13] |= i810Rop[rop] << 16;
+ pI810->BR[13] |= XAACopyROP[rop] << 16;
pI810->BR[13] |= (1 << 27);
if (bg == -1)
pI810->BR[13] |= BR13_MONO_TRANSPCY;
@@ -623,11 +588,11 @@ I810RefreshRing(ScrnInfoPtr pScrn)
{
I810Ptr pI810 = I810PTR(pScrn);
- pI810->LpRing.head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR;
- pI810->LpRing.tail = INREG(LP_RING + RING_TAIL);
- pI810->LpRing.space = pI810->LpRing.head - (pI810->LpRing.tail + 8);
- if (pI810->LpRing.space < 0)
- pI810->LpRing.space += pI810->LpRing.mem.Size;
+ pI810->LpRing->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR;
+ pI810->LpRing->tail = INREG(LP_RING + RING_TAIL);
+ pI810->LpRing->space = pI810->LpRing->head - (pI810->LpRing->tail + 8);
+ if (pI810->LpRing->space < 0)
+ pI810->LpRing->space += pI810->LpRing->mem.Size;
pI810->AccelInfoRec->NeedToSync = TRUE;
}
diff --git a/src/i810_cursor.c b/src/i810_cursor.c
index 26023f3f..23b006d3 100644
--- a/src/i810_cursor.c
+++ b/src/i810_cursor.c
@@ -25,7 +25,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_cursor.c,v 1.7 2002/10/30 12:52:17 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_cursor.c,v 1.6 2002/09/11 00:29:31 dawes Exp $ */
/*
* Reformatted with GNU indent (2.2.8), using the following options:
@@ -44,6 +44,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*
+ * Add ARGB HW cursor support:
+ * Alan Hourihane <alanh@tungstengraphics.com>
+ *
*/
#include "xf86.h"
@@ -55,6 +58,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i810.h"
+static Bool I810UseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs);
+static void I810LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs);
static void I810LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
static void I810ShowCursor(ScrnInfoPtr pScrn);
static void I810HideCursor(ScrnInfoPtr pScrn);
@@ -90,10 +95,63 @@ I810CursorInit(ScreenPtr pScreen)
infoPtr->HideCursor = I810HideCursor;
infoPtr->ShowCursor = I810ShowCursor;
infoPtr->UseHWCursor = I810UseHWCursor;
+#ifdef ARGB_CURSOR
+ pI810->CursorIsARGB = FALSE;
+
+ if (!pI810->CursorARGBPhysical) {
+ infoPtr->UseHWCursorARGB = I810UseHWCursorARGB;
+ infoPtr->LoadCursorARGB = I810LoadCursorARGB;
+ }
+#endif
return xf86InitCursor(pScreen, infoPtr);
}
+#ifdef ARGB_CURSOR
+#include "cursorstr.h"
+
+static Bool I810UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I810Ptr pI810 = I810PTR(pScrn);
+
+ if (!pI810->CursorARGBPhysical)
+ return FALSE;
+
+ if (pCurs->bits->height <= 64 && pCurs->bits->width <= 64)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void I810LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
+{
+ I810Ptr pI810 = I810PTR(pScrn);
+ CARD32 *pcurs = (CARD32 *) (pI810->FbBase + pI810->CursorStart);
+ CARD32 *image = (CARD32 *) pCurs->bits->argb;
+ int x, y, w, h;
+
+#ifdef ARGB_CURSOR
+ pI810->CursorIsARGB = TRUE;
+#endif
+
+ w = pCurs->bits->width;
+ h = pCurs->bits->height;
+
+ for (y = 0; y < h; y++)
+ {
+ for (x = 0; x < w; x++)
+ *pcurs++ = *image++;
+ for (; x < 64; x++)
+ *pcurs++ = 0;
+ }
+
+ for (; y < 64; y++)
+ for (x = 0; x < 64; x++)
+ *pcurs++ = 0;
+}
+#endif
+
static Bool
I810UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
{
@@ -113,6 +171,10 @@ I810LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
CARD8 *pcurs = (CARD8 *) (pI810->FbBase + pI810->CursorStart);
int x, y;
+#ifdef ARGB_CURSOR
+ pI810->CursorIsARGB = FALSE;
+#endif
+
for (y = 0; y < 64; y++) {
for (x = 0; x < 64 / 4; x++) {
*pcurs++ = *src++;
@@ -147,7 +209,10 @@ I810SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
OUTREG8(CURSOR_Y_LO, y & 0xFF);
OUTREG8(CURSOR_Y_HI, (((y >> 8) & 0x07) | flag));
- OUTREG(CURSOR_BASEADDR, pI810->CursorPhysical);
+ if (pI810->CursorIsARGB)
+ OUTREG(CURSOR_BASEADDR, pI810->CursorARGBPhysical);
+ else
+ OUTREG(CURSOR_BASEADDR, pI810->CursorPhysical);
}
static void
@@ -156,8 +221,13 @@ I810ShowCursor(ScrnInfoPtr pScrn)
I810Ptr pI810 = I810PTR(pScrn);
unsigned char tmp;
- OUTREG(CURSOR_BASEADDR, pI810->CursorPhysical);
- OUTREG8(CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C);
+ if (pI810->CursorIsARGB) {
+ OUTREG(CURSOR_BASEADDR, pI810->CursorARGBPhysical);
+ OUTREG8(CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_ARGB_AX);
+ } else {
+ OUTREG(CURSOR_BASEADDR, pI810->CursorPhysical);
+ OUTREG8(CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C);
+ }
tmp = INREG8(PIXPIPE_CONFIG_0);
tmp |= HW_CURSOR_ENABLE;
@@ -181,6 +251,11 @@ I810SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
int tmp;
I810Ptr pI810 = I810PTR(pScrn);
+#ifdef ARGB_CURSOR
+ if (pI810->CursorIsARGB)
+ return;
+#endif
+
tmp = INREG8(PIXPIPE_CONFIG_0);
tmp |= EXTENDED_PALETTE;
OUTREG8(PIXPIPE_CONFIG_0, tmp);
diff --git a/src/i810_dri.c b/src/i810_dri.c
index a09ba6b7..0750f3f8 100644
--- a/src/i810_dri.c
+++ b/src/i810_dri.c
@@ -104,7 +104,7 @@ Bool
I810InitDma(ScrnInfoPtr pScrn)
{
I810Ptr pI810 = I810PTR(pScrn);
- I810RingBuffer *ring = &(pI810->LpRing);
+ I810RingBuffer *ring = pI810->LpRing;
I810DRIPtr pI810DRI = (I810DRIPtr) pI810->pDRIInfo->devPrivate;
drmI810Init info;
@@ -517,6 +517,7 @@ I810DRIScreenInit(ScreenPtr pScreen)
memset(&pI810->BackBuffer, 0, sizeof(I810MemRange));
memset(&pI810->DepthBuffer, 0, sizeof(I810MemRange));
pI810->CursorPhysical = 0;
+ pI810->CursorARGBPhysical = 0;
/* Dcache - half the speed of normal ram, but has use as a Z buffer
* under the DRI.
@@ -590,6 +591,7 @@ I810DRIScreenInit(ScreenPtr pScreen)
}
sysmem_size -= 4096; /* remove 4k for the hw cursor */
+ sysmem_size -= 16384; /* remove 16k for the ARGB hw cursor */
pI810->SysMem.Start = 0;
pI810->SysMem.Size = sysmem_size;
@@ -771,6 +773,30 @@ I810DRIScreenInit(ScreenPtr pScreen)
pI810->CursorPhysical = 0;
}
+ drmAgpAlloc(pI810->drmSubFD, 16384, 2,
+ (unsigned long *)&pI810->CursorARGBPhysical, &agpHandle);
+
+ pI810->cursorARGBHandle = agpHandle;
+
+ if (agpHandle != DRM_AGP_NO_HANDLE) {
+ int r;
+
+ if ((r = drmAgpBind(pI810->drmSubFD, agpHandle, tom)) == 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[agp] GART: Allocated 16K for ARGB mouse cursor image\n");
+ pI810->CursorARGBStart = tom;
+ tom += 16384;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[agp] GART: ARGB cursor bind failed\n");
+ pI810->CursorARGBPhysical = 0;
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[agp] GART: ARGB cursor alloc failed\n");
+ pI810->CursorARGBPhysical = 0;
+ }
+
/* Steal some of the excess cursor space for the overlay regs.
*/
pI810->OverlayPhysical = pI810->CursorPhysical + 1024;
@@ -875,8 +901,8 @@ I810DRIScreenInit(ScreenPtr pScreen)
pI810DRI->agp_buffers = pI810->buffer_map;
pI810DRI->agp_buf_size = pI810->BufferMem.Size;
- if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->LpRing.mem.Start,
- pI810->LpRing.mem.Size, DRM_AGP, 0, &pI810->ring_map) < 0) {
+ if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->LpRing->mem.Start,
+ pI810->LpRing->mem.Size, DRM_AGP, 0, &pI810->ring_map) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[drm] drmAddMap(ring_map) failed. Disabling DRI.\n");
DRICloseScreen(pScreen);
@@ -966,8 +992,8 @@ I810DRIScreenInit(ScreenPtr pScreen)
pI810DRI->backOffset = pI810->BackBuffer.Start;
pI810DRI->depthOffset = pI810->DepthBuffer.Start;
- pI810DRI->ringOffset = pI810->LpRing.mem.Start;
- pI810DRI->ringSize = pI810->LpRing.mem.Size;
+ pI810DRI->ringOffset = pI810->LpRing->mem.Start;
+ pI810DRI->ringSize = pI810->LpRing->mem.Size;
pI810DRI->auxPitch = pI810->auxPitch;
pI810DRI->auxPitchBits = pI810->auxPitchBits;
@@ -1511,6 +1537,10 @@ I810DRIEnter(ScrnInfoPtr pScrn)
if (drmAgpBind(pI810->drmSubFD, pI810->cursorHandle,
pI810->CursorStart) != 0)
return FALSE;
+ if (pI810->cursorARGBHandle != 0)
+ if (drmAgpBind(pI810->drmSubFD, pI810->cursorARGBHandle,
+ pI810->CursorARGBStart) != 0)
+ return FALSE;
}
return TRUE;
}
diff --git a/src/i810_driver.c b/src/i810_driver.c
index caadc879..92bd7e88 100644
--- a/src/i810_driver.c
+++ b/src/i810_driver.c
@@ -44,6 +44,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*
+ * Add ARGB HW cursor support:
+ * Alan Hourihane <alanh@tungstengraphics.com>
+ *
*/
/*
@@ -69,12 +72,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "micmap.h"
#include "fb.h"
-#include "regionstr.h"
+#include "miscstruct.h"
#include "xf86xv.h"
#include "Xv.h"
#include "vbe.h"
#include "i810.h"
+#include "i830.h"
#ifdef XF86DRI
#include "dri.h"
@@ -124,6 +128,7 @@ static SymTabRec I810Chipsets[] = {
{PCI_CHIP_845_G, "845G"},
{PCI_CHIP_I855_GM, "852GM/855GM"},
{PCI_CHIP_I865_G, "865G"},
+ {PCI_CHIP_I915_G, "915G"},
{-1, NULL}
};
@@ -138,6 +143,7 @@ static PciChipsets I810PciChipsets[] = {
{PCI_CHIP_845_G, PCI_CHIP_845_G, RES_SHARED_VGA},
{PCI_CHIP_I855_GM, PCI_CHIP_I855_GM, RES_SHARED_VGA},
{PCI_CHIP_I865_G, PCI_CHIP_I865_G, RES_SHARED_VGA},
+ {PCI_CHIP_I915_G, PCI_CHIP_I915_G, RES_SHARED_VGA},
{-1, -1, RES_UNDEFINED }
};
@@ -358,6 +364,8 @@ static XF86ModuleVersionInfo i810VersRec = {
XF86ModuleData i810ModuleData = { &i810VersRec, i810Setup, 0 };
+int I830EntityIndex = -1;
+
static pointer
i810Setup(pointer module, pointer opts, int *errmaj, int *errmin)
{
@@ -467,6 +475,8 @@ static Bool
I810Probe(DriverPtr drv, int flags)
{
int i, numUsed, numDevSections, *usedChips;
+ I830EntPtr pI830Ent = NULL;
+ DevUnion *pPriv;
GDevPtr *devSections;
Bool foundScreen = FALSE;
pciVideoPtr *VideoInfo;
@@ -542,11 +552,39 @@ I810Probe(DriverPtr drv, int flags)
pScrn->Probe = I810Probe;
foundScreen = TRUE;
switch (pEnt->chipset) {
- case PCI_CHIP_I830_M:
case PCI_CHIP_845_G:
- case PCI_CHIP_I855_GM:
case PCI_CHIP_I865_G:
I830InitpScrn(pScrn);
+ break;
+ case PCI_CHIP_I830_M:
+ case PCI_CHIP_I855_GM:
+ case PCI_CHIP_I915_G:
+ xf86SetEntitySharable(usedChips[i]);
+
+ /* Allocate an entity private if necessary */
+ if (I830EntityIndex < 0)
+ I830EntityIndex = xf86AllocateEntityPrivateIndex();
+
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
+ I830EntityIndex);
+ if (!pPriv->ptr) {
+ pPriv->ptr = xnfcalloc(sizeof(I830EntRec), 1);
+ pI830Ent = pPriv->ptr;
+ pI830Ent->lastInstance = -1;
+ } else {
+ pI830Ent = pPriv->ptr;
+ }
+
+ /*
+ * Set the entity instance for this instance of the driver.
+ * For dual head per card, instance 0 is the "master"
+ * instance, driving the primary head, and instance 1 is
+ * the "slave".
+ */
+ pI830Ent->lastInstance++;
+ xf86SetEntityInstanceForScreen(pScrn,
+ pScrn->entityList[0], pI830Ent->lastInstance);
+ I830InitpScrn(pScrn);
break;
#ifndef I830_ONLY
default:
@@ -1122,7 +1160,7 @@ I810MapMem(ScrnInfoPtr pScrn)
if (!pI810->FbBase)
return FALSE;
- pI810->LpRing.virtual_start = pI810->FbBase + pI810->LpRing.mem.Start;
+ pI810->LpRing->virtual_start = pI810->FbBase + pI810->LpRing->mem.Start;
return TRUE;
}
@@ -1486,8 +1524,8 @@ DoRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, I810RegPtr i810Reg,
OUTREG(LP_RING + RING_TAIL, 0);
OUTREG(LP_RING + RING_HEAD, 0);
- pI810->LpRing.head = 0;
- pI810->LpRing.tail = 0;
+ pI810->LpRing->head = 0;
+ pI810->LpRing->tail = 0;
itemp = INREG(LP_RING + RING_START);
itemp &= ~(START_ADDR);
@@ -1527,12 +1565,12 @@ I810SetRingRegs(ScrnInfoPtr pScrn)
itemp = INREG(LP_RING + RING_START);
itemp &= ~(START_ADDR);
- itemp |= pI810->LpRing.mem.Start;
+ itemp |= pI810->LpRing->mem.Start;
OUTREG(LP_RING + RING_START, itemp);
itemp = INREG(LP_RING + RING_LEN);
itemp &= ~(RING_NR_PAGES | RING_REPORT_MASK | RING_VALID_MASK);
- itemp |= ((pI810->LpRing.mem.Size - 4096) | RING_NO_REPORT | RING_VALID);
+ itemp |= ((pI810->LpRing->mem.Size - 4096) | RING_NO_REPORT | RING_VALID);
OUTREG(LP_RING + RING_LEN, itemp);
}
@@ -1728,10 +1766,10 @@ I810SetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
/* Setup the ring buffer */
i810Reg->LprbTail = 0;
i810Reg->LprbHead = 0;
- i810Reg->LprbStart = pI810->LpRing.mem.Start;
+ i810Reg->LprbStart = pI810->LpRing->mem.Start;
if (i810Reg->LprbStart)
- i810Reg->LprbLen = ((pI810->LpRing.mem.Size - 4096) |
+ i810Reg->LprbLen = ((pI810->LpRing->mem.Size - 4096) |
RING_NO_REPORT | RING_VALID);
else
i810Reg->LprbLen = RING_INVALID;
@@ -1974,18 +2012,18 @@ I810AllocateFront(ScrnInfoPtr pScrn)
pI810->FrontBuffer.Start,
pI810->FrontBuffer.Size / 1024, pI810->FrontBuffer.Size);
- memset(&(pI810->LpRing), 0, sizeof(I810RingBuffer));
- if (I810AllocLow(&(pI810->LpRing.mem), &(pI810->SysMem), 16 * 4096)) {
+ memset(pI810->LpRing, 0, sizeof(I810RingBuffer));
+ if (I810AllocLow(&(pI810->LpRing->mem), &(pI810->SysMem), 16 * 4096)) {
DPRINTF(PFX,
"Ring buffer at 0x%.8x (%luk, %lu bytes)\n",
- pI810->LpRing.mem.Start,
- pI810->LpRing.mem.Size / 1024, pI810->LpRing.mem.Size);
-
- pI810->LpRing.tail_mask = pI810->LpRing.mem.Size - 1;
- pI810->LpRing.virtual_start = pI810->FbBase + pI810->LpRing.mem.Start;
- pI810->LpRing.head = 0;
- pI810->LpRing.tail = 0;
- pI810->LpRing.space = 0;
+ pI810->LpRing->mem.Start,
+ pI810->LpRing->mem.Size / 1024, pI810->LpRing->mem.Size);
+
+ pI810->LpRing->tail_mask = pI810->LpRing->mem.Size - 1;
+ pI810->LpRing->virtual_start = pI810->FbBase + pI810->LpRing->mem.Start;
+ pI810->LpRing->head = 0;
+ pI810->LpRing->tail = 0;
+ pI810->LpRing->space = 0;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Ring buffer allocation failed\n");
@@ -2114,7 +2152,7 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86SetBlackWhitePixels(pScreen);
#ifdef XF86DRI
- if (pI810->LpRing.mem.Start == 0 && pI810->directRenderingEnabled) {
+ if (pI810->LpRing->mem.Start == 0 && pI810->directRenderingEnabled) {
pI810->directRenderingEnabled = FALSE;
driFrom = X_PROBED;
I810DRICloseScreen(pScreen);
@@ -2138,7 +2176,7 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
}
if (!xf86ReturnOptValBool(pI810->Options, OPTION_NOACCEL, FALSE)) {
- if (pI810->LpRing.mem.Size != 0) {
+ if (pI810->LpRing->mem.Size != 0) {
I810SetRingRegs(pScrn);
if (!I810AccelInit(pScreen)) {
diff --git a/src/i810_memory.c b/src/i810_memory.c
index 5efa23a9..749997f4 100644
--- a/src/i810_memory.c
+++ b/src/i810_memory.c
@@ -149,7 +149,7 @@ I810AllocateGARTMemory(ScrnInfoPtr pScrn)
pI810->DcacheKey = key;
if (!xf86BindGARTMemory(pScrn->scrnIndex, key, tom)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Allocation of %d bytes for DCACHE failed\n", size);
+ "Allocation of %ld bytes for DCACHE failed\n", size);
pI810->DcacheKey = -1;
} else {
pI810->DcacheMem.Start = tom;
@@ -159,7 +159,7 @@ I810AllocateGARTMemory(ScrnInfoPtr pScrn)
}
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "No physical memory available for %d bytes of DCACHE\n",
+ "No physical memory available for %ld bytes of DCACHE\n",
size);
pI810->DcacheKey = -1;
}
@@ -188,9 +188,11 @@ I810AllocateGARTMemory(ScrnInfoPtr pScrn)
pI810->HwcursKey = key;
if (!xf86BindGARTMemory(pScrn->scrnIndex, key, tom)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Allocation of %d bytes for HW cursor failed\n", size);
+ "Allocation of %ld bytes for HW cursor failed\n", size);
pI810->HwcursKey = -1;
} else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Allocated of %ld bytes for HW cursor\n", size);
pI810->CursorPhysical = physical;
pI810->CursorStart = tom;
tom += size;
@@ -198,6 +200,34 @@ I810AllocateGARTMemory(ScrnInfoPtr pScrn)
}
/*
+ * 16k for the ARGB cursor
+ */
+
+ size = 16384;
+
+ if ((key =
+ xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, &physical)) == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "No physical memory available for ARGB HW cursor\n");
+ pI810->ARGBHwcursKey = -1;
+ pI810->CursorARGBStart = 0;
+ } else {
+ pI810->ARGBHwcursOffset = tom;
+ pI810->ARGBHwcursKey = key;
+ if (!xf86BindGARTMemory(pScrn->scrnIndex, key, tom)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Allocation of %ld bytes for ARGB HW cursor failed\n", size);
+ pI810->ARGBHwcursKey = -1;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Allocated of %ld bytes for ARGB HW cursor\n", size);
+ pI810->CursorARGBPhysical = physical;
+ pI810->CursorARGBStart = tom;
+ tom += size;
+ }
+ }
+
+ /*
* Overlay register buffer -- Just like the cursor, the i810 needs a
* physical address in system memory from which to upload the overlay
* registers.
@@ -345,6 +375,11 @@ I810BindGARTMemory(ScrnInfoPtr pScrn)
pI810->HwcursOffset))
return FALSE;
+ if (pI810->ARGBHwcursKey != -1
+ && !xf86BindGARTMemory(pScrn->scrnIndex, pI810->ARGBHwcursKey,
+ pI810->ARGBHwcursOffset))
+ return FALSE;
+
pI810->GttBound = 1;
}
@@ -370,6 +405,10 @@ I810UnbindGARTMemory(ScrnInfoPtr pScrn)
&& !xf86UnbindGARTMemory(pScrn->scrnIndex, pI810->HwcursKey))
return FALSE;
+ if (pI810->ARGBHwcursKey != -1
+ && !xf86UnbindGARTMemory(pScrn->scrnIndex, pI810->ARGBHwcursKey))
+ return FALSE;
+
if (!xf86ReleaseGART(pScrn->scrnIndex))
return FALSE;
diff --git a/src/i810_reg.h b/src/i810_reg.h
index c935982a..eac71ba9 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -209,6 +209,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define CURSOR_SIZE_HSHIFT 0
#define CURSOR_SIZE_VSHIFT 12
+#define CURSOR_B_CONTROL 0x700C0
+#define CURSOR_B_BASE 0x700C4
+#define CURSOR_B_POSITION 0x700C8
+#define CURSOR_B_PALETTE0 0x700D0
+#define CURSOR_B_PALETTE1 0x700D4
+#define CURSOR_B_PALETTE2 0x700D8
+#define CURSOR_B_PALETTE3 0x700DC
+
/* Similar registers exist in Device 0 on the i810 (pp55-65), but I'm
* not sure they refer to local (graphics) memory.
@@ -358,6 +366,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define FENCE 0x2000
#define FENCE_NR 8
+#define I915G_FENCE_START_MASK 0x0ff00000
+
#define I830_FENCE_START_MASK 0x07f80000
#define FENCE_START_MASK 0x03F80000
@@ -372,7 +382,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define FENCE_SIZE_16M 0x00000500
#define FENCE_SIZE_32M 0x00000600
#define FENCE_SIZE_64M 0x00000700
-#define FENCE_PITCH_MASK 0x00000070
+#define I915G_FENCE_SIZE_1M 0x00000000
+#define I915G_FENCE_SIZE_2M 0x00000100
+#define I915G_FENCE_SIZE_4M 0x00000200
+#define I915G_FENCE_SIZE_8M 0x00000300
+#define I915G_FENCE_SIZE_16M 0x00000400
+#define I915G_FENCE_SIZE_32M 0x00000500
+#define I915G_FENCE_SIZE_64M 0x00000600
+#define I915G_FENCE_SIZE_128M 0x00000700
#define FENCE_PITCH_1 0x00000000
#define FENCE_PITCH_2 0x00000010
#define FENCE_PITCH_4 0x00000020
@@ -497,6 +514,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define BR13_RIGHT_TO_LEFT 0x40000000
#define BR13_LEFT_TO_RIGHT 0x00000000
#define BR13_MONO_TRANSPCY 0x20000000
+#define BR13_MONO_PATN_TRANS 0x10000000
#define BR13_USE_DYN_DEPTH 0x04000000
#define BR13_DYN_8BPP 0x00000000
#define BR13_DYN_16BPP 0x01000000
@@ -708,6 +726,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define PIPEBCONF 0x71008
#define PIPEBCONF_ENABLE (1<<31)
#define PIPEBCONF_DISABLE 0
+#define PIPEBCONF_DOUBLE_WIDE (1<<30)
+#define PIPEBCONF_DISABLE 0
#define PIPEBCONF_GAMMA (1<<24)
#define PIPEBCONF_PALETTE 0
@@ -747,6 +767,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DSPBADDR DSPBBASE
#define DSPBSTRIDE 0x71188
+#define DSPAPOS 0x7018C /* reserved */
+#define DSPASIZE 0x70190
+#define DSPBPOS 0x7118C
+#define DSPBSIZE 0x71190
+
/* Various masks for reserved bits, etc. */
#define I830_FWATER1_MASK (~((1<<11)|(1<<10)|(1<<9)| \
(1<<8)|(1<<26)|(1<<25)|(1<<24)|(1<<5)|(1<<4)|(1<<3)| \
@@ -801,6 +826,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4)
#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4)
#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4)
+#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
+#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
#define I85X_CAPID 0x44
#define I85X_VARIANT_MASK 0x7
diff --git a/src/i830.h b/src/i830.h
index 34b76bb3..d23d31db 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -78,6 +78,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Paulo César Pereira de Andrade <pcpa@conectiva.com.br>.
*/
+#define PIPE_NONE 0<<0
+#define PIPE_CRT 1<<0
+#define PIPE_TV 1<<1
+#define PIPE_DFP 1<<2
+#define PIPE_LFP 1<<3
+#define PIPE_CRT2 1<<4
+#define PIPE_TV2 1<<5
+#define PIPE_DFP2 1<<6
+#define PIPE_LFP2 1<<7
+
typedef struct _VESARec {
/* SVGA state */
pointer state, pstate;
@@ -87,6 +97,8 @@ typedef struct _VESARec {
xf86MonPtr monitor;
/* Don't try to set the refresh rate for any modes. */
Bool useDefaultRefresh;
+ /* display start */
+ int x, y;
} VESARec, *VESAPtr;
@@ -133,13 +145,38 @@ typedef struct {
unsigned int Fence[8];
} I830RegRec, *I830RegPtr;
+typedef struct {
+ int lastInstance;
+ int refCount;
+ ScrnInfoPtr pScrn_1;
+ ScrnInfoPtr pScrn_2;
+ int RingRunning;
+#ifdef I830_XV
+ int XvInUse;
+#endif
+} I830EntRec, *I830EntPtr;
+
typedef struct _I830Rec {
unsigned char *MMIOBase;
unsigned char *FbBase;
int cpp;
+ unsigned int bios_version;
+
+ Bool newPipeSwitch;
+
+ Bool Clone;
+ int CloneRefresh;
+ int CloneHDisplay;
+ int CloneVDisplay;
+
+ I830EntPtr entityPrivate;
+ int pipe;
+ int init;
+
unsigned int bufferOffset; /* for I830SelectBuffer */
BoxRec FbMemBox;
+ BoxRec FbMemBox2;
int CacheLines;
/* These are set in PreInit and never changed. */
@@ -156,10 +193,16 @@ typedef struct _I830Rec {
unsigned long allocatedMemory;
/* Regions allocated either from the above pools, or from agpgart. */
+ /* for single and dual head configurations */
I830MemRange FrontBuffer;
- I830MemRange CursorMem;
- I830RingBuffer LpRing;
+ I830MemRange FrontBuffer2;
I830MemRange Scratch;
+ I830MemRange Scratch2;
+
+ /* Regions allocated either from the above pools, or from agpgart. */
+ I830MemRange *CursorMem;
+ I830MemRange *CursorMemARGB;
+ I830RingBuffer *LpRing;
#if REMAP_RESERVED
I830MemRange Dummy;
@@ -167,14 +210,13 @@ typedef struct _I830Rec {
#ifdef I830_XV
/* For Xvideo */
- I830MemRange OverlayMem;
+ I830MemRange *OverlayMem;
#endif
#ifdef XF86DRI
I830MemRange BackBuffer;
I830MemRange DepthBuffer;
I830MemRange TexMem;
- I830MemRange BufferMem;
I830MemRange ContextMem;
int TexGranularity;
int drmMinor;
@@ -185,10 +227,13 @@ typedef struct _I830Rec {
Bool allowPageFlip;
Bool disableTiling;
- int auxPitch;
- int auxPitchBits;
+ int backPitch;
Bool CursorNeedsPhysical;
+ Bool CursorIsARGB;
+
+ int MonType1;
+ int MonType2;
DGAModePtr DGAModes;
int numDGAModes;
@@ -221,7 +266,6 @@ typedef struct _I830Rec {
XAAInfoRecPtr AccelInfoRec;
xf86CursorInfoPtr CursorInfoRec;
CloseScreenProcPtr CloseScreen;
- ScreenBlockHandlerProcPtr BlockHandler;
I830WriteIndexedByteFunc writeControl;
I830ReadIndexedByteFunc readControl;
@@ -234,7 +278,8 @@ typedef struct _I830Rec {
#ifdef I830_XV
int colorKey;
XF86VideoAdaptorPtr adaptor;
- Bool overlayOn;
+ ScreenBlockHandlerProcPtr BlockHandler;
+ Bool *overlayOn;
#endif
Bool directRenderingDisabled; /* DRI disabled in PreInit. */
@@ -272,12 +317,13 @@ typedef struct _I830Rec {
CARD32 saveSWF0;
CARD32 saveSWF4;
- /* Use BIOS call 0x5f64 to explicitly enable displays. */
- Bool enableDisplays;
/* Use BIOS call 0x5f05 to set the refresh rate. */
Bool useExtendedRefresh;
- int configuredDevices;
+ Bool checkLid;
+ int monitorSwitch;
+ int operatingDevices;
+ int savedDevices;
/* These are indexed by the display types */
Bool displayAttached[NumDisplayTypes];
@@ -293,6 +339,7 @@ typedef struct _I830Rec {
int planeEnabled[MAX_DISPLAY_PIPES];
/* Driver phase/state information */
+ Bool preinit;
Bool starting;
Bool closing;
Bool suspended;
@@ -304,6 +351,9 @@ typedef struct _I830Rec {
int SaveGeneration;
Bool vbeRestoreWorkaround;
Bool displayInfo;
+ Bool devicePresence;
+
+ OsTimerPtr lidTimer;
} I830Rec;
#define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
@@ -401,8 +451,7 @@ extern void I830ChangeFrontbuffer(ScrnInfoPtr pScrn,int buffer);
#define ALLOCATE_DRY_RUN 0x80000000
/* Chipset registers for VIDEO BIOS memory RW access */
-#define _855_DRAM_RW_CONTROL 0x58
-#define _845_DRAM_RW_CONTROL 0x90
+#define DRAM_RW_CONTROL 0x58
#define DRAM_WRITE 0x33330000
#endif /* _I830_H_ */
diff --git a/src/i830_accel.c b/src/i830_accel.c
index 63dce22d..84012fac 100644
--- a/src/i830_accel.c
+++ b/src/i830_accel.c
@@ -55,53 +55,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86_ansic.h"
#include "xf86.h"
-
+#include "xaarop.h"
#include "i830.h"
#include "i810_reg.h"
-static unsigned int i810Rop[16] = {
- 0x00, /* GXclear */
- 0x88, /* GXand */
- 0x44, /* GXandReverse */
- 0xCC, /* GXcopy */
- 0x22, /* GXandInvert */
- 0xAA, /* GXnoop */
- 0x66, /* GXxor */
- 0xEE, /* GXor */
- 0x11, /* GXnor */
- 0x99, /* GXequiv */
- 0x55, /* GXinvert */
- 0xDD, /* GXorReverse */
- 0x33, /* GXcopyInvert */
- 0xBB, /* GXorInverted */
- 0x77, /* GXnand */
- 0xFF /* GXset */
-};
-
-static unsigned int i810PatternRop[16] = {
- 0x00, /* GXclear */
- 0xA0, /* GXand */
- 0x50, /* GXandReverse */
- 0xF0, /* GXcopy */
- 0x0A, /* GXandInvert */
- 0xAA, /* GXnoop */
- 0x5A, /* GXxor */
- 0xFA, /* GXor */
- 0x05, /* GXnor */
- 0xA5, /* GXequiv */
- 0x55, /* GXinvert */
- 0xF5, /* GXorReverse */
- 0x0F, /* GXcopyInvert */
- 0xAF, /* GXorInverted */
- 0x5F, /* GXnand */
- 0xFF /* GXset */
-};
-
int
I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis)
{
I830Ptr pI830 = I830PTR(pScrn);
- I830RingBuffer *ring = &(pI830->LpRing);
+ I830RingBuffer *ring = pI830->LpRing;
int iters = 0;
int start = 0;
int now = 0;
@@ -179,6 +141,8 @@ I830Sync(ScrnInfoPtr pScrn)
}
#endif
+ if (pI830->entityPrivate && !pI830->entityPrivate->RingRunning) return;
+
/* Send a flush instruction and then wait till the ring is empty.
* This is stronger than waiting for the blitter to finish as it also
* flushes the internal graphics caches.
@@ -190,9 +154,9 @@ I830Sync(ScrnInfoPtr pScrn)
ADVANCE_LP_RING();
}
- I830WaitLpRing(pScrn, pI830->LpRing.mem.Size - 8, 0);
+ I830WaitLpRing(pScrn, pI830->LpRing->mem.Size - 8, 0);
- pI830->LpRing.space = pI830->LpRing.mem.Size - 8;
+ pI830->LpRing->space = pI830->LpRing->mem.Size - 8;
pI830->nextColorExpandBuf = 0;
}
@@ -223,7 +187,7 @@ I830SelectBuffer(ScrnInfoPtr pScrn, int buffer)
#endif
default:
case I830_SELECT_FRONT:
- pI830->bufferOffset = pI830->FrontBuffer.Start;
+ pI830->bufferOffset = pScrn->fbOffset;
break;
}
@@ -237,11 +201,11 @@ I830RefreshRing(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
- pI830->LpRing.head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK;
- pI830->LpRing.tail = INREG(LP_RING + RING_TAIL);
- pI830->LpRing.space = pI830->LpRing.head - (pI830->LpRing.tail + 8);
- if (pI830->LpRing.space < 0)
- pI830->LpRing.space += pI830->LpRing.mem.Size;
+ pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK;
+ pI830->LpRing->tail = INREG(LP_RING + RING_TAIL);
+ pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8);
+ if (pI830->LpRing->space < 0)
+ pI830->LpRing->space += pI830->LpRing->mem.Size;
if (pI830->AccelInfoRec)
pI830->AccelInfoRec->NeedToSync = TRUE;
@@ -280,6 +244,7 @@ static void I830SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
int skipleft);
static void I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno);
#endif
+static void I830RestoreAccelState(ScrnInfoPtr pScrn);
/* The following function sets up the supported acceleration. Call it
@@ -292,6 +257,10 @@ I830AccelInit(ScreenPtr pScreen)
XAAInfoRecPtr infoPtr;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
+ int i;
+ int width = 0;
+ int nr_buffers = 0;
+ unsigned char *ptr = NULL;
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830AccelInit\n");
@@ -335,12 +304,26 @@ I830AccelInit(ScreenPtr pScreen)
}
- if (pI830->Scratch.Size != 0) {
- int i;
- int width = ((pScrn->displayWidth + 31) & ~31) / 8;
- int nr_buffers = pI830->Scratch.Size / width;
- unsigned char *ptr = pI830->FbBase + pI830->Scratch.Start;
+ /* On the primary screen */
+ if (pI830->init == 0) {
+ if (pI830->Scratch.Size != 0) {
+ width = ((pScrn->displayWidth + 31) & ~31) / 8;
+ nr_buffers = pI830->Scratch.Size / width;
+ ptr = pI830->FbBase + pI830->Scratch.Start;
+ }
+ } else {
+ /* On the secondary screen */
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ if (pI8301->Scratch2.Size != 0) {
+ width = ((pScrn->displayWidth + 31) & ~31) / 8;
+ nr_buffers = pI8301->Scratch2.Size / width;
+ /* We have to use the primary screen's FbBase, as that's where
+ * we allocated Scratch2, so we get the correct pointer */
+ ptr = pI8301->FbBase + pI8301->Scratch2.Start;
+ }
+ }
+ if (nr_buffers) {
pI830->NumScanlineColorExpandBuffers = nr_buffers;
pI830->ScanlineColorExpandBuffers = (unsigned char **)
xnfcalloc(nr_buffers, sizeof(unsigned char *));
@@ -382,6 +365,18 @@ I830AccelInit(ScreenPtr pScreen)
#endif
}
+ {
+ Bool shared_accel = FALSE;
+ int i;
+
+ for(i = 0; i < pScrn->numEntities; i++) {
+ if(xf86IsEntityShared(pScrn->entityList[i]))
+ shared_accel = TRUE;
+ }
+ if(shared_accel == TRUE)
+ infoPtr->RestoreAccelState = I830RestoreAccelState;
+ }
+
I830SelectBuffer(pScrn, I830_SELECT_FRONT);
return XAAInit(pScreen, infoPtr);
@@ -397,7 +392,7 @@ I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
ErrorF("I830SetupForFillRectSolid color: %x rop: %x mask: %x\n",
color, rop, planemask);
- pI830->BR[13] = ((i810PatternRop[rop] << 16) |
+ pI830->BR[13] = ((XAAPatternROP[rop] << 16) |
(pScrn->displayWidth * pI830->cpp));
pI830->BR[16] = color;
@@ -453,7 +448,7 @@ I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
xdir, ydir, rop, planemask, transparency_color);
pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
- pI830->BR[13] |= i810Rop[rop] << 16;
+ pI830->BR[13] |= XAACopyROP[rop] << 16;
switch (pScrn->bitsPerPixel) {
case 8:
@@ -519,7 +514,7 @@ I830SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
pI830->BR[19] = fg;
pI830->BR[13] = (pScrn->displayWidth * pI830->cpp); /* In bytes */
- pI830->BR[13] |= i810PatternRop[rop] << 16;
+ pI830->BR[13] |= XAAPatternROP[rop] << 16;
if (bg == -1)
pI830->BR[13] |= (1 << 28);
@@ -608,7 +603,7 @@ I830SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
/* Fill out register values */
pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
- pI830->BR[13] |= i810Rop[rop] << 16;
+ pI830->BR[13] |= XAACopyROP[rop] << 16;
if (bg == -1)
pI830->BR[13] |= (1 << 29);
@@ -651,8 +646,17 @@ I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
{
I830Ptr pI830 = I830PTR(pScrn);
- pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
- pI830->FbBase);
+ if (pI830->init == 0) {
+ pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
+ pI830->FbBase);
+ } else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+
+ /* We have to use the primary screen's FbBase, as that's where
+ * we allocated Scratch2, so we get the correct pointer */
+ pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
+ pI8301->FbBase);
+ }
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentColorExpandScanline %d (addr %x)\n",
@@ -697,7 +701,7 @@ I830SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
/* Fill out register values */
pI830->BR[13] = (pScrn->displayWidth * pI830->cpp);
- pI830->BR[13] |= i810Rop[rop] << 16;
+ pI830->BR[13] |= XAACopyROP[rop] << 16;
switch (pScrn->bitsPerPixel) {
case 8:
@@ -734,8 +738,17 @@ I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
{
I830Ptr pI830 = I830PTR(pScrn);
- pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
- pI830->FbBase);
+ if (pI830->init == 0) {
+ pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
+ pI830->FbBase);
+ } else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+
+ /* We have to use the primary screen's FbBase, as that's where
+ * we allocated Scratch2, so we get the correct pointer */
+ pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] -
+ pI8301->FbBase);
+ }
if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
ErrorF("I830SubsequentImageWriteScanline %d (addr %x)\n",
@@ -766,5 +779,14 @@ I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
pI830->BR[9] += pScrn->displayWidth * pI830->cpp;
I830GetNextScanlineColorExpandBuffer(pScrn);
}
+#endif
+/* Support for multiscreen */
+static void
+I830RestoreAccelState(ScrnInfoPtr pScrn)
+{
+#if 0
+ /* might be needed, but everything is on a ring, so I don't think so */
+ I830Sync(pScrn);
#endif
+}
diff --git a/src/i830_common.h b/src/i830_common.h
index 3367bfc1..4328baa9 100644
--- a/src/i830_common.h
+++ b/src/i830_common.h
@@ -26,184 +26,31 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.2 2002/12/10 01:27:05 dawes Exp $ */
-
-/* Author: Jeff Hartmann <jhartmann@valinux.com>
-
- Converted to common header format:
- Jens Owen <jens@tungstengraphics.com>
- */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */
#ifndef _I830_COMMON_H_
#define _I830_COMMON_H_
-/* WARNING: These defines must be the same as what the Xserver uses.
- * if you change them, you must change the defines in the Xserver.
- */
-
-#ifndef _I830_DEFINES_
-#define _I830_DEFINES_
-#define I830_DMA_BUF_ORDER 12
-#define I830_DMA_BUF_SZ (1<<I830_DMA_BUF_ORDER)
-#define I830_DMA_BUF_NR 256
-#define I830_NR_SAREA_CLIPRECTS 8
+#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */
+#define I830_LOG_MIN_TEX_REGION_SIZE 14
-/* Each region is a minimum of 64k, and there are at most 64 of them.
- */
-#define I830_NR_TEX_REGIONS 64
-#define I830_LOG_MIN_TEX_REGION_SIZE 16
-
-/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */
-#if !defined(I830_ENABLE_4_TEXTURES)
-#define I830_TEXTURE_COUNT 2
-#define I830_TEXBLEND_COUNT 2 /* always same as TEXTURE_COUNT? */
-#else /* defined(I830_ENABLE_4_TEXTURES) */
-#define I830_TEXTURE_COUNT 4
-#define I830_TEXBLEND_COUNT 4 /* always same as TEXTURE_COUNT? */
-#endif /* I830_ENABLE_4_TEXTURES */
-
-#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */
-
-#define I830_UPLOAD_CTX 0x1
-#define I830_UPLOAD_BUFFERS 0x2
-#define I830_UPLOAD_CLIPRECTS 0x4
-#define I830_UPLOAD_TEX0_IMAGE 0x100 /* handled clientside */
-#define I830_UPLOAD_TEX0_CUBE 0x200 /* handled clientside */
-#define I830_UPLOAD_TEX1_IMAGE 0x400 /* handled clientside */
-#define I830_UPLOAD_TEX1_CUBE 0x800 /* handled clientside */
-#define I830_UPLOAD_TEX2_IMAGE 0x1000 /* handled clientside */
-#define I830_UPLOAD_TEX2_CUBE 0x2000 /* handled clientside */
-#define I830_UPLOAD_TEX3_IMAGE 0x4000 /* handled clientside */
-#define I830_UPLOAD_TEX3_CUBE 0x8000 /* handled clientside */
-#define I830_UPLOAD_TEX_N_IMAGE(n) (0x100 << (n * 2))
-#define I830_UPLOAD_TEX_N_CUBE(n) (0x200 << (n * 2))
-#define I830_UPLOAD_TEXIMAGE_MASK 0xff00
-#define I830_UPLOAD_TEX0 0x10000
-#define I830_UPLOAD_TEX1 0x20000
-#define I830_UPLOAD_TEX2 0x40000
-#define I830_UPLOAD_TEX3 0x80000
-#define I830_UPLOAD_TEX_N(n) (0x10000 << (n))
-#define I830_UPLOAD_TEX_MASK 0xf0000
-#define I830_UPLOAD_TEXBLEND0 0x100000
-#define I830_UPLOAD_TEXBLEND1 0x200000
-#define I830_UPLOAD_TEXBLEND2 0x400000
-#define I830_UPLOAD_TEXBLEND3 0x800000
-#define I830_UPLOAD_TEXBLEND_N(n) (0x100000 << (n))
-#define I830_UPLOAD_TEXBLEND_MASK 0xf00000
-#define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n))
-#define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000
-#define I830_UPLOAD_STIPPLE 0x8000000
-
-/* Indices into buf.Setup where various bits of state are mirrored per
- * context and per buffer. These can be fired at the card as a unit,
- * or in a piecewise fashion as required.
- */
-
-/* Destbuffer state
- * - backbuffer linear offset and pitch -- invarient in the current dri
- * - zbuffer linear offset and pitch -- also invarient
- * - drawing origin in back and depth buffers.
- *
- * Keep the depth/back buffer state here to acommodate private buffers
- * in the future.
- */
-
-#define I830_DESTREG_CBUFADDR 0
-/* Invarient */
-#define I830_DESTREG_DBUFADDR 1
-#define I830_DESTREG_DV0 2
-#define I830_DESTREG_DV1 3
-#define I830_DESTREG_SENABLE 4
-#define I830_DESTREG_SR0 5
-#define I830_DESTREG_SR1 6
-#define I830_DESTREG_SR2 7
-#define I830_DESTREG_DR0 8
-#define I830_DESTREG_DR1 9
-#define I830_DESTREG_DR2 10
-#define I830_DESTREG_DR3 11
-#define I830_DESTREG_DR4 12
-#define I830_DEST_SETUP_SIZE 13
-
-/* Context state
- */
-#define I830_CTXREG_STATE1 0
-#define I830_CTXREG_STATE2 1
-#define I830_CTXREG_STATE3 2
-#define I830_CTXREG_STATE4 3
-#define I830_CTXREG_STATE5 4
-#define I830_CTXREG_IALPHAB 5
-#define I830_CTXREG_STENCILTST 6
-#define I830_CTXREG_ENABLES_1 7
-#define I830_CTXREG_ENABLES_2 8
-#define I830_CTXREG_AA 9
-#define I830_CTXREG_FOGCOLOR 10
-#define I830_CTXREG_BLENDCOLR0 11
-#define I830_CTXREG_BLENDCOLR 12 /* Dword 1 of 2 dword command */
-#define I830_CTXREG_VF 13
-#define I830_CTXREG_VF2 14
-#define I830_CTXREG_MCSB0 15
-#define I830_CTXREG_MCSB1 16
-#define I830_CTX_SETUP_SIZE 17
-
-/* 1.3: Stipple state
- */
-#define I830_STPREG_ST0 0
-#define I830_STPREG_ST1 1
-#define I830_STP_SETUP_SIZE 2
-
-/* Texture state (per tex unit)
- */
-#define I830_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (6 dwords) */
-#define I830_TEXREG_MI1 1
-#define I830_TEXREG_MI2 2
-#define I830_TEXREG_MI3 3
-#define I830_TEXREG_MI4 4
-#define I830_TEXREG_MI5 5
-#define I830_TEXREG_MF 6 /* GFX_OP_MAP_FILTER */
-#define I830_TEXREG_MLC 7 /* GFX_OP_MAP_LOD_CTL */
-#define I830_TEXREG_MLL 8 /* GFX_OP_MAP_LOD_LIMITS */
-#define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */
-#define I830_TEX_SETUP_SIZE 10
-
-/* New version. Kernel auto-detects.
- */
-#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */
-#define I830_TEXREG_TM0S0 1
-#define I830_TEXREG_TM0S1 2
-#define I830_TEXREG_TM0S2 3
-#define I830_TEXREG_TM0S3 4
-#define I830_TEXREG_TM0S4 5
-#define I830_TEXREG_NOP0 6 /* noop */
-#define I830_TEXREG_NOP1 7 /* noop */
-#define I830_TEXREG_NOP2 8 /* noop */
-#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */
-#define __I830_TEX_SETUP_SIZE 10
-
-
-#define I830_FRONT 0x1
-#define I830_BACK 0x2
-#define I830_DEPTH 0x4
/* Driver specific DRM command indices
* NOTE: these are not OS specific, but they are driver specific
*/
#define DRM_I830_INIT 0x00
-#define DRM_I830_VERTEX 0x01
-#define DRM_I830_CLEAR 0x02
-#define DRM_I830_FLUSH 0x03
-#define DRM_I830_GETAGE 0x04
-#define DRM_I830_GETBUF 0x05
-#define DRM_I830_SWAP 0x06
-#define DRM_I830_COPY 0x07
-#define DRM_I830_DOCOPY 0x08
-#define DRM_I830_FLIP 0x09
-#define DRM_I830_IRQ_EMIT 0x0a
-#define DRM_I830_IRQ_WAIT 0x0b
-#define DRM_I830_GETPARAM 0x0c
-#define DRM_I830_SETPARAM 0x0d
-
-#endif /* _I830_DEFINES_ */
+#define DRM_I830_FLUSH 0x01
+#define DRM_I830_FLIP 0x02
+#define DRM_I830_BATCHBUFFER 0x03
+#define DRM_I830_IRQ_EMIT 0x04
+#define DRM_I830_IRQ_WAIT 0x05
+#define DRM_I830_GETPARAM 0x06
+#define DRM_I830_SETPARAM 0x07
+#define DRM_I830_ALLOC 0x08
+#define DRM_I830_FREE 0x09
+#define DRM_I830_INIT_HEAP 0x0a
+#define DRM_I830_CMDBUFFER 0x0b
typedef struct {
enum {
@@ -211,7 +58,6 @@ typedef struct {
I830_CLEANUP_DMA = 0x02
} func;
unsigned int mmio_offset;
- unsigned int buffers_offset;
int sarea_priv_offset;
unsigned int ring_start;
unsigned int ring_end;
@@ -226,63 +72,88 @@ typedef struct {
unsigned int back_pitch;
unsigned int depth_pitch;
unsigned int cpp;
+ unsigned int chipset;
} drmI830Init;
typedef struct {
- int clear_color;
- int clear_depth;
- int flags;
- unsigned int clear_colormask;
- unsigned int clear_depthmask;
-} drmI830Clear;
-
-/* These may be placeholders if we have more cliprects than
- * I830_NR_SAREA_CLIPRECTS. In that case, the client sets discard to
- * false, indicating that the buffer will be dispatched again with a
- * new set of cliprects.
+ drmTextureRegion texList[I830_NR_TEX_REGIONS+1];
+ int last_upload; /* last time texture was uploaded */
+ int last_enqueue; /* last time a buffer was enqueued */
+ int last_dispatch; /* age of the most recently dispatched buffer */
+ int ctxOwner; /* last context to upload state */
+ int texAge;
+ int pf_enabled; /* is pageflipping allowed? */
+ int pf_active;
+ int pf_current_page; /* which buffer is being displayed? */
+ int perf_boxes; /* performance boxes to be displayed */
+} drmI830Sarea;
+
+/* Flags for perf_boxes
*/
-typedef struct {
- int idx; /* buffer index */
- int used; /* nr bytes in use */
- int discard; /* client is finished with the buffer? */
-} drmI830Vertex;
+#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */
+#define I830_BOX_FLIP 0x2 /* populated by kernel */
+#define I830_BOX_WAIT 0x4 /* populated by kernel & client */
+#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */
+#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */
-typedef struct {
- int idx; /* buffer index */
- int used; /* nr bytes in use */
- void *address; /* Address to copy from */
-} drmI830Copy;
typedef struct {
- void *virtual;
- int request_idx;
- int request_size;
- int granted;
-} drmI830DMA;
+ int start; /* agp offset */
+ int used; /* nr bytes in use */
+ int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
+ int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/
+ int num_cliprects; /* mulitpass with multiple cliprects? */
+ drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */
+} drmI830BatchBuffer;
+
-typedef struct drm_i830_irq_emit {
+typedef struct {
int *irq_seq;
} drmI830IrqEmit;
-typedef struct drm_i830_irq_wait {
+typedef struct {
int irq_seq;
} drmI830IrqWait;
-typedef struct drm_i830_getparam {
+typedef struct {
int param;
int *value;
} drmI830GetParam;
-#define I830_PARAM_IRQ_ACTIVE 1
+#define I830_PARAM_IRQ_ACTIVE 1
+#define I830_PARAM_LAST_ENQUEUE 2
+#define I830_PARAM_LAST_DEQUEUE 3
-
-typedef struct drm_i830_setparam {
+typedef struct {
int param;
int value;
} drmI830SetParam;
#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1
+#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2
+
+
+/* A memory manager for regions of shared memory:
+ */
+#define I830_MEM_REGION_AGP 1
+typedef struct {
+ int region;
+ int alignment;
+ int size;
+ int *region_offset; /* offset from start of fb or agp */
+} drmI830MemAlloc;
+
+typedef struct {
+ int region;
+ int region_offset;
+} drmI830MemFree;
+
+typedef struct {
+ int region;
+ int size;
+ int start;
+} drmI830MemInitHeap;
#endif /* _I830_DRM_H_ */
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index ef9a81ee..d59c19dd 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -26,7 +26,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_cursor.c,v 1.7 2003/06/18 13:14:17 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_cursor.c,v 1.6 2002/12/18 15:49:01 dawes Exp $ */
/*
* Reformatted with GNU indent (2.2.8), using the following options:
@@ -46,6 +46,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Keith Whitwell <keith@tungstengraphics.com>
* David Dawes <dawes@xfree86.org>
*
+ * Updated for Dual Head capabilities:
+ * Alan Hourihane <alanh@tungstengraphics.com>
+ *
+ * Add ARGB HW cursor support:
+ * Alan Hourihane <alanh@tungstengraphics.com>
+ *
*/
#include "xf86.h"
@@ -63,6 +69,10 @@ static void I830HideCursor(ScrnInfoPtr pScrn);
static void I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb);
static void I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
static Bool I830UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
+#ifdef ARGB_CURSOR
+static void I830LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs);
+static Bool I830UseHWCursorARGB(ScreenPtr pScrn, CursorPtr pCurs);
+#endif
void
I830InitHWCursor(ScrnInfoPtr pScrn)
@@ -71,24 +81,28 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
CARD32 temp;
DPRINTF(PFX, "I830InitHWCursor\n");
-
/* Initialise the HW cursor registers, leaving the cursor hidden. */
- if (IS_MOBILE(pI830)) {
+ if (IS_MOBILE(pI830) || IS_I915G(pI830)) {
temp = INREG(CURSOR_A_CONTROL);
temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_MEM_TYPE_LOCAL |
MCURSOR_PIPE_SELECT);
temp |= CURSOR_MODE_DISABLE;
- /*
- * XXX Should enable cursor B when both pipes are enabled.
- * For now, give pipe A preference.
- */
- if (pI830->pipeEnabled[0])
- temp |= MCURSOR_PIPE_A;
- else if (pI830->pipeEnabled[1])
- temp |= MCURSOR_PIPE_B;
+ temp |= (pI830->pipe << 28);
/* Need to set control, then address. */
OUTREG(CURSOR_A_CONTROL, temp);
- OUTREG(CURSOR_A_BASE, pI830->CursorMem.Physical);
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+ if (pI830->Clone) {
+ temp &= ~MCURSOR_PIPE_SELECT;
+ temp |= (!pI830->pipe << 28);
+ OUTREG(CURSOR_B_CONTROL, temp);
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+ }
} else {
temp = INREG(CURSOR_CONTROL);
temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE |
@@ -97,7 +111,10 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
/* This initialises the format and leave the cursor disabled. */
OUTREG(CURSOR_CONTROL, temp);
/* Need to set address and size after disabling. */
- OUTREG(CURSOR_BASEADDR, pI830->CursorMem.Start);
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_BASEADDR, pI830->CursorMemARGB->Start);
+ else
+ OUTREG(CURSOR_BASEADDR, pI830->CursorMem->Start);
temp = ((I810_CURSOR_X & CURSOR_SIZE_MASK) << CURSOR_SIZE_HSHIFT) |
((I810_CURSOR_Y & CURSOR_SIZE_MASK) << CURSOR_SIZE_VSHIFT);
OUTREG(CURSOR_SIZE, temp);
@@ -134,7 +151,17 @@ I830CursorInit(ScreenPtr pScreen)
infoPtr->ShowCursor = I830ShowCursor;
infoPtr->UseHWCursor = I830UseHWCursor;
- if (pI830->CursorNeedsPhysical && !pI830->CursorMem.Physical)
+#ifdef ARGB_CURSOR
+ pI830->CursorIsARGB = FALSE;
+
+ if (pI830->CursorMemARGB->Start) {
+ /* Use ARGB if we were able to allocate the 16kb needed */
+ infoPtr->UseHWCursorARGB = I830UseHWCursorARGB;
+ infoPtr->LoadCursorARGB = I830LoadCursorARGB;
+ }
+#endif
+
+ if (pI830->CursorNeedsPhysical && !pI830->CursorMem->Physical)
return FALSE;
I830HideCursor(pScrn);
@@ -149,7 +176,7 @@ I830UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
I830Ptr pI830 = I830PTR(pScrn);
DPRINTF(PFX, "I830UseHWCursor\n");
- if (pI830->CursorNeedsPhysical && !pI830->CursorMem.Physical)
+ if (pI830->CursorNeedsPhysical && !pI830->CursorMem->Physical)
return FALSE;
return TRUE;
@@ -159,10 +186,15 @@ static void
I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
{
I830Ptr pI830 = I830PTR(pScrn);
- CARD8 *pcurs = (CARD8 *) (pI830->FbBase + pI830->CursorMem.Start);
+ CARD8 *pcurs = (CARD8 *) (pI830->FbBase + pI830->CursorMem->Start);
int x, y;
DPRINTF(PFX, "I830LoadCursorImage\n");
+
+#ifdef ARGB_CURSOR
+ pI830->CursorIsARGB = FALSE;
+#endif
+
for (y = 0; y < 64; y++) {
for (x = 0; x < 64 / 4; x++) {
*pcurs++ = *src++;
@@ -170,6 +202,59 @@ I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
}
}
+#ifdef ARGB_CURSOR
+#include "cursorstr.h"
+
+static Bool I830UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ DPRINTF(PFX, "I830UseHWCursorARGB\n");
+ if (pScrn->bitsPerPixel == 8)
+ return FALSE;
+
+ if (pI830->CursorNeedsPhysical && !pI830->CursorMemARGB->Physical)
+ return FALSE;
+
+ if (pCurs->bits->height <= 64 && pCurs->bits->width <= 64)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void I830LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 *dst = (CARD32 *) (pI830->FbBase + pI830->CursorMemARGB->Start);
+ CARD32 *image = (CARD32 *)pCurs->bits->argb;
+ int x, y, w, h;
+
+ DPRINTF(PFX, "I830LoadCursorARGB\n");
+
+ if (!image)
+ return; /* XXX can't happen */
+
+#ifdef ARGB_CURSOR
+ pI830->CursorIsARGB = TRUE;
+#endif
+
+ w = pCurs->bits->width;
+ h = pCurs->bits->height;
+
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++)
+ *dst++ = *image++;
+ for(; x < 64; x++)
+ *dst++ = 0;
+ }
+
+ for(; y < 64; y++) {
+ for(x = 0; x < 64; x++)
+ *dst++ = 0;
+ }
+}
+#endif
static void
I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
@@ -207,6 +292,8 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
OUTREG(CURSOR_A_POSITION, temp);
+ if (pI830->Clone)
+ OUTREG(CURSOR_B_POSITION, temp);
if (pI830->cursorOn) {
if (hide)
@@ -215,6 +302,20 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
pI830->CursorInfoRec->ShowCursor(pScrn);
pI830->cursorOn = TRUE;
}
+
+ /* have to upload the base for the new position */
+ if (IS_I915G(pI830)) {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+ if (pI830->Clone) {
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+ }
+ }
}
static void
@@ -225,22 +326,51 @@ I830ShowCursor(ScrnInfoPtr pScrn)
DPRINTF(PFX, "I830ShowCursor\n");
DPRINTF(PFX,
- "Value of CursorMem.Physical is %x, "
- " Value of CursorMem.Start is %x ",
- pI830->CursorMem.Physical, pI830->CursorMem.Start);
+ "Value of CursorMem->Physical is %x, "
+ " Value of CursorMem->Start is %x ",
+ pI830->CursorMem->Physical, pI830->CursorMem->Start);
+ DPRINTF(PFX,
+ "Value of CursorMemARGB->Physical is %x, "
+ " Value of CursorMemARGB->Start is %x ",
+ pI830->CursorMemARGB->Physical, pI830->CursorMemARGB->Start);
pI830->cursorOn = TRUE;
- if (IS_MOBILE(pI830)) {
+ if (IS_MOBILE(pI830) || IS_I915G(pI830)) {
temp = INREG(CURSOR_A_CONTROL);
- temp &= ~CURSOR_MODE;
- temp |= CURSOR_MODE_64_4C_AX;
+ temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
+ if (pI830->CursorIsARGB)
+ temp |= CURSOR_MODE_64_ARGB_AX;
+ else
+ temp |= CURSOR_MODE_64_4C_AX;
+ temp |= (pI830->pipe << 28); /* Connect to correct pipe */
/* Need to set mode, then address. */
OUTREG(CURSOR_A_CONTROL, temp);
- OUTREG(CURSOR_A_BASE, pI830->CursorMem.Physical);
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+ if (pI830->Clone) {
+ temp &= ~MCURSOR_PIPE_SELECT;
+ temp |= (!pI830->pipe << 28);
+ OUTREG(CURSOR_B_CONTROL, temp);
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+ }
} else {
temp = INREG(CURSOR_CONTROL);
+ temp &= ~(CURSOR_FORMAT_MASK);
temp |= CURSOR_ENABLE;
+ if (pI830->CursorIsARGB)
+ temp |= CURSOR_FORMAT_ARGB;
+ else
+ temp |= CURSOR_FORMAT_3C;
OUTREG(CURSOR_CONTROL, temp);
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_BASEADDR, pI830->CursorMemARGB->Start);
+ else
+ OUTREG(CURSOR_BASEADDR, pI830->CursorMem->Start);
}
}
@@ -253,13 +383,23 @@ I830HideCursor(ScrnInfoPtr pScrn)
DPRINTF(PFX, "I830HideCursor\n");
pI830->cursorOn = FALSE;
- if (IS_MOBILE(pI830)) {
+ if (IS_MOBILE(pI830) || IS_I915G(pI830)) {
temp = INREG(CURSOR_A_CONTROL);
temp &= ~CURSOR_MODE;
temp |= CURSOR_MODE_DISABLE;
OUTREG(CURSOR_A_CONTROL, temp);
/* This is needed to flush the above change. */
- OUTREG(CURSOR_A_BASE, pI830->CursorMem.Physical);
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical);
+ if (pI830->Clone) {
+ OUTREG(CURSOR_B_CONTROL, temp);
+ if (pI830->CursorIsARGB)
+ OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical);
+ }
} else {
temp = INREG(CURSOR_CONTROL);
temp &= ~CURSOR_ENABLE;
@@ -272,10 +412,22 @@ I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
I830Ptr pI830 = I830PTR(pScrn);
+#ifdef ARGB_CURSOR
+ /* Don't recolour cursors set with SetCursorARGB. */
+ if (pI830->CursorIsARGB)
+ return;
+#endif
+
DPRINTF(PFX, "I830SetCursorColors\n");
OUTREG(CURSOR_A_PALETTE0, bg & 0x00ffffff);
OUTREG(CURSOR_A_PALETTE1, fg & 0x00ffffff);
OUTREG(CURSOR_A_PALETTE2, fg & 0x00ffffff);
OUTREG(CURSOR_A_PALETTE3, bg & 0x00ffffff);
+ if (pI830->Clone) {
+ OUTREG(CURSOR_B_PALETTE0, bg & 0x00ffffff);
+ OUTREG(CURSOR_B_PALETTE1, fg & 0x00ffffff);
+ OUTREG(CURSOR_B_PALETTE2, fg & 0x00ffffff);
+ OUTREG(CURSOR_B_PALETTE3, bg & 0x00ffffff);
+ }
}
diff --git a/src/i830_dga.c b/src/i830_dga.c
index bb4c103a..b1416598 100644
--- a/src/i830_dga.c
+++ b/src/i830_dga.c
@@ -34,7 +34,7 @@
* with <TAB> characters expanded at 8-column intervals.
*/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c,v 1.3 2003/02/26 04:11:23 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dga.c,v 1.2 2002/11/05 02:01:18 dawes Exp $ */
#include "xf86.h"
#include "xf86_OSproc.h"
@@ -281,7 +281,12 @@ I830_OpenFramebuffer(ScrnInfoPtr pScrn,
*name = NULL; /* no special device */
*mem = (unsigned char *)(pI830->LinearAddr + pScrn->fbOffset);
- *size = pI830->FrontBuffer.Size;
+ if (pI830->init == 0)
+ *size = pI830->FrontBuffer.Size;
+ else {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ *size = pI8301->FrontBuffer2.Size;
+ }
*offset = 0;
*flags = DGA_NEED_ROOT;
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 9ed9bb79..9e236f98 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -73,10 +73,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i830.h"
#include "i830_dri.h"
-#include "i830_3d_reg.h"
-static char I830KernelDriverName[] = "i830";
-static char I830ClientDriverName[] = "i830";
+static char I830KernelDriverName[] = "i915";
+static char I830ClientDriverName[] = "i915";
static Bool I830InitVisualConfigs(ScreenPtr pScreen);
static Bool I830CreateContext(ScreenPtr pScreen, VisualPtr visual,
@@ -128,7 +127,7 @@ static Bool
I830InitDma(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
- I830RingBuffer *ring = &(pI830->LpRing);
+ I830RingBuffer *ring = pI830->LpRing;
I830DRIPtr pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate;
drmI830Init info;
@@ -140,7 +139,6 @@ I830InitDma(ScrnInfoPtr pScrn)
info.ring_size = ring->mem.Size;
info.mmio_offset = (unsigned int)pI830DRI->regs;
- info.buffers_offset = (unsigned int)pI830->buffer_map;
info.sarea_priv_offset = sizeof(XF86DRISAREARec);
@@ -149,10 +147,9 @@ I830InitDma(ScrnInfoPtr pScrn)
info.depth_offset = pI830->DepthBuffer.Start;
info.w = pScrn->virtualX;
info.h = pScrn->virtualY;
- info.pitch = pI830->auxPitch;
- info.pitch_bits = pI830->auxPitchBits;
- info.back_pitch = pI830->auxPitch;
- info.depth_pitch = pI830->auxPitch;
+ info.pitch = pI830->backPitch;
+ info.back_pitch = pI830->backPitch;
+ info.depth_pitch = pI830->backPitch;
info.cpp = pI830->cpp;
if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT,
@@ -241,6 +238,7 @@ I830InitVisualConfigs(ScreenPtr pScreen)
pConfigs[i].redSize = 5;
pConfigs[i].greenSize = 6;
pConfigs[i].blueSize = 5;
+ pConfigs[i].alphaSize = 0;
pConfigs[i].redMask = 0x0000F800;
pConfigs[i].greenMask = 0x000007E0;
pConfigs[i].blueMask = 0x0000001F;
@@ -270,10 +268,10 @@ I830InitVisualConfigs(ScreenPtr pScreen)
pConfigs[i].auxBuffers = 0;
pConfigs[i].level = 0;
if (stencil || accum)
- pConfigs[i].visualRating = GLX_SLOW_CONFIG;
+ pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT;
else
- pConfigs[i].visualRating = GLX_NONE;
- pConfigs[i].transparentPixel = GLX_NONE;
+ pConfigs[i].visualRating = GLX_NONE_EXT;
+ pConfigs[i].transparentPixel = GLX_NONE_EXT;
pConfigs[i].transparentRed = 0;
pConfigs[i].transparentGreen = 0;
pConfigs[i].transparentBlue = 0;
@@ -328,7 +326,7 @@ I830InitVisualConfigs(ScreenPtr pScreen)
pConfigs[i].redMask = 0x00FF0000;
pConfigs[i].greenMask = 0x0000FF00;
pConfigs[i].blueMask = 0x000000FF;
- pConfigs[i].alphaMask = 0xFF000000;;
+ pConfigs[i].alphaMask = 0xFF000000;
if (accum) {
pConfigs[i].accumRedSize = 16;
pConfigs[i].accumGreenSize = 16;
@@ -357,11 +355,11 @@ I830InitVisualConfigs(ScreenPtr pScreen)
pConfigs[i].auxBuffers = 0;
pConfigs[i].level = 0;
if (accum) {
- pConfigs[i].visualRating = GLX_SLOW_CONFIG;
+ pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT;
} else {
- pConfigs[i].visualRating = GLX_NONE;
+ pConfigs[i].visualRating = GLX_NONE_EXT;
}
- pConfigs[i].transparentPixel = GLX_NONE;
+ pConfigs[i].transparentPixel = GLX_NONE_EXT;
pConfigs[i].transparentRed = 0;
pConfigs[i].transparentGreen = 0;
pConfigs[i].transparentBlue = 0;
@@ -468,7 +466,7 @@ I830DRIScreenInit(ScreenPtr pScreen)
else
pDRIInfo->maxDrawableTableEntry = I830_MAX_DRAWABLES;
- if (sizeof(XF86DRISAREARec) + sizeof(I830SAREARec) > SAREA_MAX) {
+ if (sizeof(XF86DRISAREARec) + sizeof(drmI830Sarea) > SAREA_MAX) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[dri] Data does not fit in SAREA\n");
return FALSE;
@@ -554,14 +552,14 @@ I830DRIScreenInit(ScreenPtr pScreen)
drmFreeVersion(version);
}
- /* Check the i830 DRM version */
+ /* Check the i915 DRM version */
version = drmGetVersion(pI830->drmSubFD);
if (version) {
- if (version->version_major != 1 || version->version_minor < 3) {
+ if (version->version_major != 1 || version->version_minor < 1) {
/* incompatible drm version */
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[dri] %s failed because of a version mismatch.\n"
- "[dri] i830.o kernel module version is %d.%d.%d but version 1.3 or greater is needed.\n"
+ "[dri] i915 kernel module version is %d.%d.%d but version 1.1 or greater is needed.\n"
"[dri] Disabling DRI.\n",
"I830DRIScreenInit",
version->version_major,
@@ -584,7 +582,6 @@ I830DRIDoMappings(ScreenPtr pScreen)
I830Ptr pI830 = I830PTR(pScrn);
DRIInfoPtr pDRIInfo = pI830->pDRIInfo;
I830DRIPtr pI830DRI = pDRIInfo->devPrivate;
- int bufs;
DPRINTF(PFX, "I830DRIDoMappings\n");
pI830DRI->regsSize = I830_REG_SIZE;
@@ -601,8 +598,7 @@ I830DRIDoMappings(ScreenPtr pScreen)
* The tile setup is now initiated from I830BIOSScreenInit().
*/
- pI830->auxPitch = pScrn->displayWidth;
- pI830->auxPitchBits = 0;
+ pI830->backPitch = pScrn->displayWidth;
pI830DRI->backbufferSize = pI830->BackBuffer.Size;
@@ -631,24 +627,10 @@ I830DRIDoMappings(ScreenPtr pScreen)
xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Depth Buffer = 0x%08lx\n",
pI830DRI->depthbuffer);
- if (drmAddMap(pI830->drmSubFD,
- (drm_handle_t)pI830->BufferMem.Start + pI830->LinearAddr,
- pI830->BufferMem.Size, DRM_AGP, 0,
- &pI830->buffer_map) < 0) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] drmAddMap(buffer_map) failed. Disabling DRI\n");
- DRICloseScreen(pScreen);
- return FALSE;
- }
- xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] DMA Buffers = 0x%08lx\n",
- pI830->buffer_map);
-
- pI830DRI->agp_buffers = pI830->buffer_map;
- pI830DRI->agp_buf_size = pI830->BufferMem.Size;
if (drmAddMap(pI830->drmSubFD,
- (drm_handle_t)pI830->LpRing.mem.Start + pI830->LinearAddr,
- pI830->LpRing.mem.Size, DRM_AGP, 0,
+ (drm_handle_t)pI830->LpRing->mem.Start + pI830->LinearAddr,
+ pI830->LpRing->mem.Size, DRM_AGP, 0,
&pI830->ring_map) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[drm] drmAddMap(ring_map) failed. Disabling DRI\n");
@@ -673,20 +655,6 @@ I830DRIDoMappings(ScreenPtr pScreen)
xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] textures = 0x%08lx\n",
pI830DRI->textures);
- if ((bufs = drmAddBufs(pI830->drmSubFD,
- I830_DMA_BUF_NR,
- I830_DMA_BUF_SZ,
- DRM_AGP_BUFFER, pI830DRI->agp_buffers)) <= 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] failure adding %d %d byte DMA buffers\n",
- I830_DMA_BUF_NR, I830_DMA_BUF_SZ);
- DRICloseScreen(pScreen);
- return FALSE;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] added %d %d byte DMA buffers\n", bufs, I830_DMA_BUF_SZ);
-
I830InitDma(pScrn);
if (pI830->PciInfo->chipType != PCI_CHIP_845_G &&
@@ -695,7 +663,7 @@ I830DRIDoMappings(ScreenPtr pScreen)
}
/* Okay now initialize the dma engine */
- if (!pI830DRI->irq) {
+ {
pI830DRI->irq = drmGetInterruptFromBusID(pI830->drmSubFD,
((pciConfigPtr) pI830->
PciInfo->thisCard)->busnum,
@@ -703,20 +671,42 @@ I830DRIDoMappings(ScreenPtr pScreen)
PciInfo->thisCard)->devnum,
((pciConfigPtr) pI830->
PciInfo->thisCard)->funcnum);
-#if 1
- if ((drmCtlInstHandler(pI830->drmSubFD, pI830DRI->irq)) != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] failure adding irq handler, there is a device already using that irq\n"
- "[drm] Consider rearranging your PCI cards\n");
+
+ if (drmCtlInstHandler(pI830->drmSubFD, pI830DRI->irq)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failure adding irq handler\n");
+ pI830DRI->irq = 0;
DRICloseScreen(pScreen);
return FALSE;
}
-#endif
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] dma control initialized, using IRQ %d\n",
+ pI830DRI->irq);
+ }
+
+ /* Start up the simple memory manager for agp space */
+ {
+ drmI830MemInitHeap drmHeap;
+ drmHeap.region = I830_MEM_REGION_AGP;
+ drmHeap.start = 0;
+ drmHeap.size = pI830DRI->textureSize;
+
+ if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT_HEAP,
+ &drmHeap, sizeof(drmHeap))) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] Failed to initialized agp heap manager\n");
+ } else {
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Initialized kernel agp heap manager, %d\n",
+ pI830DRI->textureSize);
+
+ I830SetParam(pScrn, I830_SETPARAM_TEX_LRU_LOG_GRANULARITY,
+ pI830->TexGranularity);
+ }
}
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] dma control initialized, using IRQ %d\n", pI830DRI->irq);
pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate;
pI830DRI->deviceID = pI830->PciInfo->chipType;
@@ -726,7 +716,7 @@ I830DRIDoMappings(ScreenPtr pScreen)
pI830DRI->cpp = pI830->cpp;
pI830DRI->fbOffset = pI830->FrontBuffer.Start;
- pI830DRI->fbStride = pI830->auxPitch;
+ pI830DRI->fbStride = pI830->backPitch;
pI830DRI->bitsPerPixel = pScrn->bitsPerPixel;
@@ -735,11 +725,8 @@ I830DRIDoMappings(ScreenPtr pScreen)
pI830DRI->backOffset = pI830->BackBuffer.Start;
pI830DRI->depthOffset = pI830->DepthBuffer.Start;
- pI830DRI->ringOffset = pI830->LpRing.mem.Start;
- pI830DRI->ringSize = pI830->LpRing.mem.Size;
-
- pI830DRI->auxPitch = pI830->auxPitch;
- pI830DRI->auxPitchBits = pI830->auxPitchBits;
+ pI830DRI->backPitch = pI830->backPitch;
+ pI830DRI->depthPitch = pI830->backPitch;
pI830DRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
if (!(I830InitVisualConfigs(pScreen))) {
@@ -804,7 +791,7 @@ I830DestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
Bool
I830DRIFinishScreenInit(ScreenPtr pScreen)
{
- I830SAREARec *sPriv = (I830SAREARec *) DRIGetSAREAPrivate(pScreen);
+ drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
@@ -814,7 +801,7 @@ I830DRIFinishScreenInit(ScreenPtr pScreen)
/* Have shadow run only while there is 3d active.
*/
- if (pI830->allowPageFlip && pI830->drmMinor >= 3) {
+ if (pI830->allowPageFlip && pI830->drmMinor >= 1) {
shadowSetup(pScreen);
shadowAdd(pScreen, 0, I830DRIShadowUpdate, 0, 0, 0);
}
@@ -832,9 +819,6 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- if (!pScrn->vtSema)
- return;
-
if (syncType == DRI_3D_SYNC &&
oldContextType == DRI_2D_CONTEXT && newContextType == DRI_2D_CONTEXT) {
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -842,6 +826,8 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
if (I810_DEBUG & DEBUG_VERBOSE_DRI)
ErrorF("i830DRISwapContext (in)\n");
+ if (!pScrn->vtSema)
+ return;
pI830->LockHeld = 1;
I830RefreshRing(pScrn);
} else if (syncType == DRI_2D_SYNC &&
@@ -1057,445 +1043,26 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
pI830->AccelInfoRec->NeedToSync = TRUE;
}
-/* Completely Initialize the first context */
+/* Initialize the first context */
void
I830EmitInvarientState(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
- I830DRIPtr pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate;
- CARD32 ctx_addr, temp;
+ CARD32 ctx_addr;
- BEGIN_LP_RING(128-2);
ctx_addr = pI830->ContextMem.Start;
/* Align to a 2k boundry */
ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048;
- OUT_RING(MI_SET_CONTEXT);
- OUT_RING(ctx_addr |
- CTXT_NO_RESTORE |
- CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE);
-
- OUT_RING(STATE3D_AA_CMD |
- AA_LINE_ECAAR_WIDTH_ENABLE |
- AA_LINE_ECAAR_WIDTH_1_0 |
- AA_LINE_REGION_WIDTH_ENABLE |
- AA_LINE_REGION_WIDTH_1_0 | AA_LINE_DISABLE);
-
- OUT_RING(STATE3D_BUF_INFO_CMD);
- OUT_RING(BUF_3D_ID_COLOR_BACK |
- BUF_3D_USE_FENCE |
- BUF_3D_PITCH((pI830->cpp * pScrn->displayWidth) / 4));
- OUT_RING(BUF_3D_ADDR(pI830DRI->backOffset));
-
- OUT_RING(STATE3D_BUF_INFO_CMD);
- OUT_RING(BUF_3D_ID_DEPTH |
- BUF_3D_USE_FENCE |
- BUF_3D_PITCH((pI830->cpp * pScrn->displayWidth) / 4));
- OUT_RING(BUF_3D_ADDR(pI830DRI->depthOffset));
-
- OUT_RING(STATE3D_COLOR_FACTOR);
- OUT_RING(0);
-
- OUT_RING(STATE3D_COLOR_FACTOR_CMD(0));
- OUT_RING(0);
-
- OUT_RING(STATE3D_COLOR_FACTOR_CMD(1));
- OUT_RING(0);
-
- OUT_RING(STATE3D_COLOR_FACTOR_CMD(2));
- OUT_RING(0);
-
- OUT_RING(STATE3D_COLOR_FACTOR_CMD(3));
- OUT_RING(0);
-
- OUT_RING(STATE3D_CONST_BLEND_COLOR_CMD);
- OUT_RING(0);
-
- OUT_RING(STATE3D_DFLT_DIFFUSE_CMD);
- OUT_RING(0);
-
- OUT_RING(STATE3D_DFLT_SPEC_CMD);
- OUT_RING(0);
-
- OUT_RING(STATE3D_DFLT_Z_CMD);
- OUT_RING(0);
-
- switch (pScrn->bitsPerPixel) {
- case 15:
- temp = DEPTH_FRMT_16_FIXED | COLR_BUF_RGB555;
- break;
- case 16:
- temp = DEPTH_FRMT_16_FIXED | COLR_BUF_RGB565;
- break;
- case 32:
- temp = DEPTH_FRMT_24_FIXED_8_OTHER | COLR_BUF_ARGB8888;
- break;
- default:
- temp = DEPTH_FRMT_16_FIXED | COLR_BUF_RGB565;
- break;
+ {
+ BEGIN_LP_RING(2);
+ OUT_RING(MI_SET_CONTEXT);
+ OUT_RING(ctx_addr |
+ CTXT_NO_RESTORE |
+ CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE);
+ ADVANCE_LP_RING();
}
-
- OUT_RING(STATE3D_DST_BUF_VARS_CMD);
- OUT_RING(DSTORG_HORT_BIAS(0x8) |
- DSTORG_VERT_BIAS(0x8) | DEPTH_IS_Z | temp);
-
- OUT_RING(STATE3D_DRAW_RECT_CMD);
- OUT_RING(DRAW_RECT_DIS_DEPTH_OFS);
- OUT_RING(0);
- OUT_RING((pI830DRI->height << 16) | pI830DRI->width);
- OUT_RING(0);
-
- OUT_RING(STATE3D_ENABLES_1_CMD |
- DISABLE_LOGIC_OP |
- DISABLE_STENCIL_TEST |
- DISABLE_DEPTH_BIAS |
- DISABLE_SPEC_ADD |
- I830_DISABLE_FOG |
- DISABLE_ALPHA_TEST | DISABLE_COLOR_BLEND | DISABLE_DEPTH_TEST);
-
- OUT_RING(STATE3D_ENABLES_2_CMD |
- DISABLE_STENCIL_WRITE |
- ENABLE_TEX_CACHE |
- ENABLE_DITHER |
- ENABLE_COLOR_MASK | ENABLE_COLOR_WRITE | ENABLE_DEPTH_WRITE);
-
- OUT_RING(STATE3D_FOG_COLOR_CMD |
- FOG_COLOR_RED(0) | FOG_COLOR_GREEN(0) | FOG_COLOR_BLUE(0));
-
- OUT_RING(STATE3D_FOG_MODE);
- OUT_RING(FOG_MODE_VERTEX |
- ENABLE_FOG_CONST | ENABLE_FOG_SOURCE | ENABLE_FOG_DENSITY);
- OUT_RING(0);
- OUT_RING(0);
-
- OUT_RING(STATE3D_INDPT_ALPHA_BLEND_CMD |
- DISABLE_INDPT_ALPHA_BLEND |
- ENABLE_ALPHA_BLENDFUNC |
- ABLENDFUNC_ADD |
- ENABLE_SRC_ABLEND_FACTOR |
- SRC_ABLEND_FACT(BLENDFACT_ONE) |
- ENABLE_DST_ABLEND_FACTOR | SRC_ABLEND_FACT(BLENDFACT_ZERO));
-
- /* I need to come back to texture state */
- OUT_RING(STATE3D_MAP_BLEND_ARG_CMD(0) |
- TEXPIPE_COLOR |
- TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE);
- OUT_RING(STATE3D_MAP_BLEND_ARG_CMD(1) |
- TEXPIPE_COLOR |
- TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE);
- OUT_RING(STATE3D_MAP_BLEND_ARG_CMD(2) |
- TEXPIPE_COLOR |
- TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE);
- OUT_RING(STATE3D_MAP_BLEND_ARG_CMD(3) |
- TEXPIPE_COLOR |
- TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE);
-
- OUT_RING(STATE3D_MAP_BLEND_ARG_CMD(0) |
- TEXPIPE_ALPHA |
- TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE);
- OUT_RING(STATE3D_MAP_BLEND_ARG_CMD(1) |
- TEXPIPE_ALPHA |
- TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE);
- OUT_RING(STATE3D_MAP_BLEND_ARG_CMD(2) |
- TEXPIPE_ALPHA |
- TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE);
- OUT_RING(STATE3D_MAP_BLEND_ARG_CMD(3) |
- TEXPIPE_ALPHA |
- TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE);
-
- OUT_RING(STATE3D_MAP_BLEND_OP_CMD(0) |
- TEXPIPE_COLOR |
- ENABLE_TEXOUTPUT_WRT_SEL |
- TEXOP_OUTPUT_CURRENT |
- DISABLE_TEX_CNTRL_STAGE |
- TEXOP_SCALE_1X |
- TEXOP_MODIFY_PARMS | TEXOP_LAST_STAGE | TEXBLENDOP_ARG1);
- OUT_RING(STATE3D_MAP_BLEND_OP_CMD(0) |
- TEXPIPE_ALPHA |
- ENABLE_TEXOUTPUT_WRT_SEL |
- TEXOP_OUTPUT_CURRENT |
- TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1);
-
- OUT_RING(STATE3D_MAP_COORD_SETBIND_CMD);
- OUT_RING(TEXBIND_SET3(TEXCOORDSRC_DEFAULT) |
- TEXBIND_SET2(TEXCOORDSRC_DEFAULT) |
- TEXBIND_SET1(TEXCOORDSRC_DEFAULT) |
- TEXBIND_SET0(TEXCOORDSRC_DEFAULT));
-
- OUT_RING(STATE3D_MAP_COORD_SET_CMD |
- MAP_UNIT(0) |
- TEXCOORDS_ARE_IN_TEXELUNITS |
- TEXCOORDTYPE_CARTESIAN |
- ENABLE_ADDR_V_CNTL |
- ENABLE_ADDR_U_CNTL |
- TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP) |
- TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP));
- OUT_RING(STATE3D_MAP_COORD_SET_CMD |
- MAP_UNIT(1) |
- TEXCOORDS_ARE_IN_TEXELUNITS |
- TEXCOORDTYPE_CARTESIAN |
- ENABLE_ADDR_V_CNTL |
- ENABLE_ADDR_U_CNTL |
- TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP) |
- TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP));
- OUT_RING(STATE3D_MAP_COORD_SET_CMD |
- MAP_UNIT(2) |
- TEXCOORDS_ARE_IN_TEXELUNITS |
- TEXCOORDTYPE_CARTESIAN |
- ENABLE_ADDR_V_CNTL |
- ENABLE_ADDR_U_CNTL |
- TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP) |
- TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP));
- OUT_RING(STATE3D_MAP_COORD_SET_CMD |
- MAP_UNIT(3) |
- TEXCOORDS_ARE_IN_TEXELUNITS |
- TEXCOORDTYPE_CARTESIAN |
- ENABLE_ADDR_V_CNTL |
- ENABLE_ADDR_U_CNTL |
- TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP) |
- TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP));
-
- OUT_RING(STATE3D_MAP_TEX_STREAM_CMD |
- MAP_UNIT(0) |
- DISABLE_TEX_STREAM_BUMP |
- ENABLE_TEX_STREAM_COORD_SET |
- TEX_STREAM_COORD_SET(0) |
- ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(0));
- OUT_RING(STATE3D_MAP_TEX_STREAM_CMD |
- MAP_UNIT(1) |
- DISABLE_TEX_STREAM_BUMP |
- ENABLE_TEX_STREAM_COORD_SET |
- TEX_STREAM_COORD_SET(1) |
- ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(1));
- OUT_RING(STATE3D_MAP_TEX_STREAM_CMD |
- MAP_UNIT(2) |
- DISABLE_TEX_STREAM_BUMP |
- ENABLE_TEX_STREAM_COORD_SET |
- TEX_STREAM_COORD_SET(2) |
- ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(2));
- OUT_RING(STATE3D_MAP_TEX_STREAM_CMD |
- MAP_UNIT(3) |
- DISABLE_TEX_STREAM_BUMP |
- ENABLE_TEX_STREAM_COORD_SET |
- TEX_STREAM_COORD_SET(3) |
- ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3));
-
-#if 0
- OUT_RING(STATE3D_MAP_FILTER_CMD |
- MAP_UNIT(0) |
- ENABLE_CHROMA_KEY_PARAMS |
- ENABLE_MIP_MODE_FILTER |
- MIPFILTER_NEAREST |
- ENABLE_MAG_MODE_FILTER |
- ENABLE_MIN_MODE_FILTER |
- MAG_FILTER(FILTER_NEAREST) | MIN_FILTER(FILTER_NEAREST));
- OUT_RING(STATE3D_MAP_FILTER_CMD |
- MAP_UNIT(1) |
- ENABLE_CHROMA_KEY_PARAMS |
- ENABLE_MIP_MODE_FILTER |
- MIPFILTER_NEAREST |
- ENABLE_MAG_MODE_FILTER |
- ENABLE_MIN_MODE_FILTER |
- MAG_FILTER(FILTER_NEAREST) | MIN_FILTER(FILTER_NEAREST));
- OUT_RING(STATE3D_MAP_FILTER_CMD |
- MAP_UNIT(2) |
- ENABLE_CHROMA_KEY_PARAMS |
- ENABLE_MIP_MODE_FILTER |
- MIPFILTER_NEAREST |
- ENABLE_MAG_MODE_FILTER |
- ENABLE_MIN_MODE_FILTER |
- MAG_FILTER(FILTER_NEAREST) | MIN_FILTER(FILTER_NEAREST));
- OUT_RING(STATE3D_MAP_FILTER_CMD |
- MAP_UNIT(3) |
- ENABLE_CHROMA_KEY_PARAMS |
- ENABLE_MIP_MODE_FILTER |
- MIPFILTER_NEAREST |
- ENABLE_MAG_MODE_FILTER |
- ENABLE_MIN_MODE_FILTER |
- MAG_FILTER(FILTER_NEAREST) | MIN_FILTER(FILTER_NEAREST));
-
- OUT_RING(STATE3D_MAP_INFO_COLR_CMD);
- OUT_RING(MAP_INFO_TEX(0) |
- MAPSURF_32BIT |
- MT_32BIT_ARGB8888 |
- MAP_INFO_OUTMUX_F0F1F2F3 |
- MAP_INFO_VERTLINESTRIDEOFS_0 |
- MAP_INFO_FORMAT_2D | MAP_INFO_USE_FENCE);
- OUT_RING(MAP_INFO_HEIGHT(0) | MAP_INFO_WIDTH(0));
- OUT_RING(MAP_INFO_BASEADDR(pI830->TexMem.Start));
- OUT_RING(MAP_INFO_DWORD_PITCH(31));
- OUT_RING(MAP_INFO_DFLT_COLR(0));
-
- OUT_RING(STATE3D_MAP_INFO_COLR_CMD);
- OUT_RING(MAP_INFO_TEX(1) |
- MAPSURF_32BIT |
- MT_32BIT_ARGB8888 |
- MAP_INFO_OUTMUX_F0F1F2F3 |
- MAP_INFO_VERTLINESTRIDEOFS_0 |
- MAP_INFO_FORMAT_2D | MAP_INFO_USE_FENCE);
- OUT_RING(MAP_INFO_HEIGHT(0) | MAP_INFO_WIDTH(0));
- OUT_RING(MAP_INFO_BASEADDR(pI830->TexMem.Start));
- OUT_RING(MAP_INFO_DWORD_PITCH(31));
- OUT_RING(MAP_INFO_DFLT_COLR(0));
-
- OUT_RING(STATE3D_MAP_INFO_COLR_CMD);
- OUT_RING(MAP_INFO_TEX(2) |
- MAPSURF_32BIT |
- MT_32BIT_ARGB8888 |
- MAP_INFO_OUTMUX_F0F1F2F3 |
- MAP_INFO_VERTLINESTRIDEOFS_0 |
- MAP_INFO_FORMAT_2D | MAP_INFO_USE_FENCE);
- OUT_RING(MAP_INFO_HEIGHT(0) | MAP_INFO_WIDTH(0));
- OUT_RING(MAP_INFO_BASEADDR(pI830->TexMem.Start));
- OUT_RING(MAP_INFO_DWORD_PITCH(31));
- OUT_RING(MAP_INFO_DFLT_COLR(0));
-
- OUT_RING(STATE3D_MAP_INFO_COLR_CMD);
- OUT_RING(MAP_INFO_TEX(3) |
- MAPSURF_32BIT |
- MT_32BIT_ARGB8888 |
- MAP_INFO_OUTMUX_F0F1F2F3 |
- MAP_INFO_VERTLINESTRIDEOFS_0 |
- MAP_INFO_FORMAT_2D | MAP_INFO_USE_FENCE);
- OUT_RING(MAP_INFO_HEIGHT(0) | MAP_INFO_WIDTH(0));
- OUT_RING(MAP_INFO_BASEADDR(pI830->TexMem.Start));
- OUT_RING(MAP_INFO_DWORD_PITCH(31));
- OUT_RING(MAP_INFO_DFLT_COLR(0));
-
- OUT_RING(STATE3D_MAP_LOD_CNTL_CMD |
- MAP_UNIT(0) | ENABLE_TEXLOD_BIAS | MAP_LOD_BIAS(0));
- OUT_RING(STATE3D_MAP_LOD_CNTL_CMD |
- MAP_UNIT(1) | ENABLE_TEXLOD_BIAS | MAP_LOD_BIAS(0));
- OUT_RING(STATE3D_MAP_LOD_CNTL_CMD |
- MAP_UNIT(2) | ENABLE_TEXLOD_BIAS | MAP_LOD_BIAS(0));
- OUT_RING(STATE3D_MAP_LOD_CNTL_CMD |
- MAP_UNIT(3) | ENABLE_TEXLOD_BIAS | MAP_LOD_BIAS(0));
-
- OUT_RING(STATE3D_MAP_LOD_LIMITS_CMD |
- MAP_UNIT(0) |
- ENABLE_MAX_MIP_LVL |
- ENABLE_MIN_MIP_LVL | LOD_MAX(0) | LOD_MIN(0));
- OUT_RING(STATE3D_MAP_LOD_LIMITS_CMD |
- MAP_UNIT(1) |
- ENABLE_MAX_MIP_LVL |
- ENABLE_MIN_MIP_LVL | LOD_MAX(0) | LOD_MIN(0));
- OUT_RING(STATE3D_MAP_LOD_LIMITS_CMD |
- MAP_UNIT(2) |
- ENABLE_MAX_MIP_LVL |
- ENABLE_MIN_MIP_LVL | LOD_MAX(0) | LOD_MIN(0));
- OUT_RING(STATE3D_MAP_LOD_LIMITS_CMD |
- MAP_UNIT(3) |
- ENABLE_MAX_MIP_LVL |
- ENABLE_MIN_MIP_LVL | LOD_MAX(0) | LOD_MIN(0));
-#endif
-
- OUT_RING(STATE3D_MAP_COORD_TRANSFORM);
- OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0));
- OUT_RING(STATE3D_MAP_COORD_TRANSFORM);
- OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(1));
- OUT_RING(STATE3D_MAP_COORD_TRANSFORM);
- OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(2));
- OUT_RING(STATE3D_MAP_COORD_TRANSFORM);
- OUT_RING(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3));
-
- /* End texture state */
-
- OUT_RING(STATE3D_MODES_1_CMD |
- ENABLE_COLR_BLND_FUNC |
- BLENDFUNC_ADD |
- ENABLE_SRC_BLND_FACTOR |
- ENABLE_DST_BLND_FACTOR |
- SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ZERO));
-
- OUT_RING(STATE3D_MODES_2_CMD |
- ENABLE_GLOBAL_DEPTH_BIAS |
- GLOBAL_DEPTH_BIAS(0) |
- ENABLE_ALPHA_TEST_FUNC |
- ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) | ALPHA_REF_VALUE(0));
-
- OUT_RING(STATE3D_MODES_3_CMD |
- ENABLE_DEPTH_TEST_FUNC |
- DEPTH_TEST_FUNC(COMPAREFUNC_LESS) |
- ENABLE_ALPHA_SHADE_MODE |
- ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
- ENABLE_FOG_SHADE_MODE |
- FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
- ENABLE_SPEC_SHADE_MODE |
- SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
- ENABLE_COLOR_SHADE_MODE |
- COLOR_SHADE_MODE(SHADE_MODE_LINEAR) |
- ENABLE_CULL_MODE | CULLMODE_NONE);
-
- OUT_RING(STATE3D_MODES_4_CMD |
- ENABLE_LOGIC_OP_FUNC |
- LOGIC_OP_FUNC(LOGICOP_COPY) |
- ENABLE_STENCIL_TEST_MASK |
- STENCIL_TEST_MASK(0xff) |
- ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff));
-
- OUT_RING(STATE3D_MODES_5_CMD |
- ENABLE_SPRITE_POINT_TEX |
- SPRITE_POINT_TEX_OFF |
- FLUSH_RENDER_CACHE |
- FLUSH_TEXTURE_CACHE |
- ENABLE_FIXED_LINE_WIDTH |
- FIXED_LINE_WIDTH(0x2) |
- ENABLE_FIXED_POINT_WIDTH | FIXED_POINT_WIDTH(1));
-
- OUT_RING(STATE3D_RASTER_RULES_CMD |
- ENABLE_POINT_RASTER_RULE |
- OGL_POINT_RASTER_RULE |
- ENABLE_LINE_STRIP_PROVOKE_VRTX |
- ENABLE_TRI_FAN_PROVOKE_VRTX |
- ENABLE_TRI_STRIP_PROVOKE_VRTX |
- LINE_STRIP_PROVOKE_VRTX(1) |
- TRI_FAN_PROVOKE_VRTX(2) | TRI_STRIP_PROVOKE_VRTX(2));
-
- OUT_RING(STATE3D_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
-
- OUT_RING(STATE3D_SCISSOR_RECT_0_CMD);
- OUT_RING(0);
- OUT_RING(0);
-
- OUT_RING(STATE3D_STENCIL_TEST_CMD |
- ENABLE_STENCIL_PARMS |
- STENCIL_FAIL_OP(STENCILOP_KEEP) |
- STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP) |
- STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP) |
- ENABLE_STENCIL_TEST_FUNC |
- STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS) |
- ENABLE_STENCIL_REF_VALUE | STENCIL_REF_VALUE(0));
-
- OUT_RING(STATE3D_VERTEX_FORMAT_CMD |
- VRTX_TEX_COORD_COUNT(1) |
- VRTX_HAS_SPEC |
- VRTX_HAS_DIFFUSE |
- VRTX_HAS_XYZW);
-
- OUT_RING(STATE3D_VERTEX_FORMAT_2_CMD |
- VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) |
- VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) |
- VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) |
- VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D) |
- VRTX_TEX_SET_4_FMT(TEXCOORDFMT_2D) |
- VRTX_TEX_SET_5_FMT(TEXCOORDFMT_2D) |
- VRTX_TEX_SET_6_FMT(TEXCOORDFMT_2D) |
- VRTX_TEX_SET_7_FMT(TEXCOORDFMT_2D));
-
- OUT_RING(STATE3D_VERTEX_TRANSFORM);
- OUT_RING(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE);
-
- OUT_RING(STATE3D_W_STATE_CMD);
- OUT_RING(MAGIC_W_STATE_DWORD1);
- OUT_RING(0x3f800000 /* 1.0 in IEEE float */ );
-
-#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
-
- OUT_RING(GFX_OP_STIPPLE);
- OUT_RING(0);
-
- ADVANCE_LP_RING();
}
/* Fullscreen hooks. The DRI fullscreen mode can probably be removed
@@ -1551,7 +1118,7 @@ I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
RegionPtr damage = &pBuf->damage;
int i, num = REGION_NUM_RECTS(damage);
BoxPtr pbox = REGION_RECTS(damage);
- I830SAREARec *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+ drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
int cmd, br13;
/* Don't want to do this when no 3d is active and pages are
@@ -1591,7 +1158,7 @@ I830EnablePageFlip(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- I830SAREARec *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+ drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
pSAREAPriv->pf_enabled = pI830->allowPageFlip;
pSAREAPriv->pf_active = 0;
@@ -1625,7 +1192,7 @@ I830EnablePageFlip(ScreenPtr pScreen)
static void
I830DisablePageFlip(ScreenPtr pScreen)
{
- I830SAREARec *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+ drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
pSAREAPriv->pf_active = 0;
}
@@ -1666,7 +1233,7 @@ I830DRITransitionTo2d(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- I830SAREARec *sPriv = (I830SAREARec *) DRIGetSAREAPrivate(pScreen);
+ drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
/* Try flipping back to the front page if necessary */
if (sPriv->pf_current_page == 1)
diff --git a/src/i830_dri.h b/src/i830_dri.h
index 684d7e32..aef93a8b 100644
--- a/src/i830_dri.h
+++ b/src/i830_dri.h
@@ -38,24 +38,19 @@ typedef struct _I830DRIRec {
int mem;
int cpp;
int bitsPerPixel;
+
int fbOffset;
int fbStride;
int backOffset;
- int depthOffset;
+ int backPitch;
- int auxPitch;
- int auxPitchBits;
+ int depthOffset;
+ int depthPitch;
int logTextureGranularity;
int textureOffset;
- /* For non-dma direct rendering.
- */
- int ringOffset;
- int ringSize;
-
- drmBufMapPtr drmBufs;
int irq;
int sarea_priv_offset;
} I830DRIRec, *I830DRIPtr;
@@ -70,72 +65,5 @@ typedef struct {
int dummy;
} I830DRIContextRec, *I830DRIContextPtr;
-/* Warning: If you change the SAREA structure you must change the kernel
- * structure as well */
-
-typedef struct _I830SAREA {
- unsigned int ContextState[I830_CTX_SETUP_SIZE];
- unsigned int BufferState[I830_DEST_SETUP_SIZE];
- unsigned int TexState[I830_TEXTURE_COUNT][I830_TEX_SETUP_SIZE];
- unsigned int TexBlendState[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE];
- unsigned int TexBlendStateWordsUsed[I830_TEXBLEND_COUNT];
- unsigned int Palette[2][256];
- unsigned int dirty;
-
- unsigned int nbox;
- drm_clip_rect_t boxes[I830_NR_SAREA_CLIPRECTS];
-
- /* Maintain an LRU of contiguous regions of texture space. If
- * you think you own a region of texture memory, and it has an
- * age different to the one you set, then you are mistaken and
- * it has been stolen by another client. If global texAge
- * hasn't changed, there is no need to walk the list.
- *
- * These regions can be used as a proxy for the fine-grained
- * texture information of other clients - by maintaining them
- * in the same lru which is used to age their own textures,
- * clients have an approximate lru for the whole of global
- * texture space, and can make informed decisions as to which
- * areas to kick out. There is no need to choose whether to
- * kick out your own texture or someone else's - simply eject
- * them all in LRU order.
- */
-
- drmTextureRegion texList[I830_NR_TEX_REGIONS + 1];
- /* Last elt is sentinal */
- int texAge; /* last time texture was uploaded */
- int last_enqueue; /* last time a buffer was enqueued */
- int last_dispatch; /* age of the most recently dispatched buffer */
- int last_quiescent; /* */
- int ctxOwner; /* last context to upload state */
-
- int vertex_prim;
-
- int pf_enabled; /* is pageflipping allowed? */
- int pf_active; /* is pageflipping active right now? */
- int pf_current_page; /* which buffer is being displayed? */
-
- int perf_boxes; /* performance boxes to be displayed */
-
- /* Here's the state for texunits 2,3:
- */
- unsigned int TexState2[I830_TEX_SETUP_SIZE];
- unsigned int TexBlendState2[I830_TEXBLEND_SIZE];
- unsigned int TexBlendStateWordsUsed2;
-
- unsigned int TexState3[I830_TEX_SETUP_SIZE];
- unsigned int TexBlendState3[I830_TEXBLEND_SIZE];
- unsigned int TexBlendStateWordsUsed3;
-
- unsigned int StippleState[I830_STP_SETUP_SIZE];
-} I830SAREARec, *I830SAREAPtr;
-
-/* Flags for perf_boxes
- */
-#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */
-#define I830_BOX_FLIP 0x2 /* populated by kernel */
-#define I830_BOX_WAIT 0x4 /* populated by kernel & client */
-#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */
-#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */
#endif
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5f5c36d6..458feb28 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c,v 1.36 2003/09/03 15:32:26 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c,v 1.50 2004/02/20 00:06:00 alanh Exp $ */
/**************************************************************************
Copyright 2001 VA Linux Systems Inc., Fremont, California.
@@ -44,6 +44,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* Authors: Jeff Hartmann <jhartmann@valinux.com>
* Abraham van der Merwe <abraham@2d3d.co.za>
* David Dawes <dawes@xfree86.org>
+ * Alan Hourihane <alanh@tungstengraphics.com>
*/
/*
@@ -126,17 +127,24 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* 08/2002 Keith Whitwell
* - Fix DRI initialisation.
- */
-/*
+ *
+ *
* 08/2002 Alan Hourihane and David Dawes
* - Add XVideo support.
- */
-/*
+ *
+ *
* 10/2002 David Dawes
* - Add Intel(R) 865G support.
+ *
+ *
+ * 01/2004 Alan Hourihane
+ * - Add Intel(R) 915G support.
+ * - Add Dual Head and Clone capabilities.
+ * - Add lid status checking
+ * - Fix Xvideo with high-res LFP's
+ * - Add ARGB HW cursor support
*/
-
#ifndef PRINT_MODE_INFO
#define PRINT_MODE_INFO 0
#endif
@@ -154,7 +162,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "micmap.h"
#include "fb.h"
-#include "regionstr.h"
+#include "miscstruct.h"
#include "xf86xv.h"
#include "Xv.h"
#include "vbe.h"
@@ -176,6 +184,7 @@ static SymTabRec I830BIOSChipsets[] = {
{PCI_CHIP_845_G, "845G"},
{PCI_CHIP_I855_GM, "852GM/855GM"},
{PCI_CHIP_I865_G, "865G"},
+ {PCI_CHIP_I915_G, "915G"},
{-1, NULL}
};
@@ -184,6 +193,7 @@ static PciChipsets I830BIOSPciChipsets[] = {
{PCI_CHIP_845_G, PCI_CHIP_845_G, RES_SHARED_VGA},
{PCI_CHIP_I855_GM, PCI_CHIP_I855_GM, RES_SHARED_VGA},
{PCI_CHIP_I865_G, PCI_CHIP_I865_G, RES_SHARED_VGA},
+ {PCI_CHIP_I915_G, PCI_CHIP_I915_G, RES_SHARED_VGA},
{-1, -1, RES_UNDEFINED}
};
@@ -202,8 +212,14 @@ typedef enum {
OPTION_XVIDEO,
OPTION_VIDEO_KEY,
OPTION_COLOR_KEY,
- OPTION_STRETCH,
- OPTION_CENTER
+ OPTION_VBE_RESTORE,
+ OPTION_DISPLAY_INFO,
+ OPTION_DEVICE_PRESENCE,
+ OPTION_MONITOR_LAYOUT,
+ OPTION_CLONE,
+ OPTION_CLONE_REFRESH,
+ OPTION_CHECKLID,
+ OPTION_FLIP_PRIMARY
} I830Opts;
static OptionInfoRec I830BIOSOptions[] = {
@@ -215,8 +231,14 @@ static OptionInfoRec I830BIOSOptions[] = {
{OPTION_XVIDEO, "XVideo", OPTV_BOOLEAN, {0}, TRUE},
{OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE},
{OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE},
- {OPTION_STRETCH, "Stretch", OPTV_BOOLEAN, {0}, FALSE},
- {OPTION_CENTER, "Center", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_VBE_RESTORE, "VBERestore", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_DISPLAY_INFO,"DisplayInfo", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_DEVICE_PRESENCE,"DevicePresence",OPTV_BOOLEAN,{0}, FALSE},
+ {OPTION_MONITOR_LAYOUT, "MonitorLayout", OPTV_ANYSTR,{0}, FALSE},
+ {OPTION_CLONE, "Clone", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_CLONE_REFRESH,"CloneRefresh",OPTV_INTEGER, {0}, FALSE},
+ {OPTION_CHECKLID, "CheckLid", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_FLIP_PRIMARY,"FlipPrimary", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
/* *INDENT-ON* */
@@ -229,6 +251,11 @@ static Bool I830BIOSSaveScreen(ScreenPtr pScreen, int unblack);
static Bool I830BIOSEnterVT(int scrnIndex, int flags);
static Bool I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode,
VbeCRTCInfoBlock *block);
+static CARD32 I830LidTimer(OsTimerPtr timer, CARD32 now, pointer arg);
+static Bool SetPipeAccess(ScrnInfoPtr pScrn);
+static Bool IsPrimary(ScrnInfoPtr pScrn);
+
+extern int I830EntityIndex;
#ifdef I830DEBUG
@@ -386,6 +413,8 @@ GetRefreshRate(ScrnInfoPtr pScrn, int mode, int refresh, int *availRefresh)
if (mode & 0x100)
return 0;
+ SetPipeAccess(pScrn);
+
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x5f05;
pVbe->pInt10->bx = (mode & 0xff) | 0x100;
@@ -552,34 +581,103 @@ GetDisplayDevices(ScrnInfoPtr pScrn)
return -1;
}
+/* This is needed for SetDisplayDevices to work correctly on I915G
+ * and possibly later Video BIOS builds around 3272 (but not sure here).
+ * So enable for all chipsets now as it has no bad side effects, apart
+ * from slightly longer startup time.
+ */
+#define I915G_WORKAROUND
+
static Bool
SetDisplayDevices(ScrnInfoPtr pScrn, int devices)
{
I830Ptr pI830 = I830PTR(pScrn);
vbeInfoPtr pVbe = pI830->pVbe;
CARD32 temp;
+#ifdef I915G_WORKAROUND
+ int getmode;
+ int mode;
+ switch (pScrn->depth) {
+ case 8:
+ mode = 0x30;
+ break;
+ case 15:
+ mode = 0x40;
+ break;
+ case 16:
+ mode = 0x41;
+ break;
+ case 24:
+ mode = 0x50;
+ break;
+ default:
+ mode = 0x30;
+ break;
+ }
+ mode |= (1 << 15) | (1 << 14);
+#endif
DPRINTF(PFX, "SetDisplayDevices: devices 0x%x\n", devices);
+#ifdef I915G_WORKAROUND
+ if (pI830->bios_version >= 3272) {
+ VBEGetVBEMode(pVbe, &getmode);
+ I830VESASetVBEMode(pScrn, mode, NULL);
+ }
+#endif
+
pVbe->pInt10->num = 0x10;
pVbe->pInt10->ax = 0x5f64;
pVbe->pInt10->bx = 0x1;
pVbe->pInt10->cx = devices;
xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
- if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))
+ if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {
+#ifdef I915G_WORKAROUND
+ if (pI830->bios_version >= 3272)
+ I830VESASetVBEMode(pScrn, getmode, NULL);
+#endif
return TRUE;
- else {
- ErrorF("Writing config directly to SWF0\n");
- temp = INREG(SWF0);
- OUTREG(SWF0, (temp & ~(0xffff)) | (devices & 0xffff));
- ErrorF("SetDisplayDevices failed. devices is 0x%x instead of 0x%x\n",
- GetDisplayDevices(pScrn), devices);
- return FALSE;
}
+
+#ifdef I915G_WORKAROUND
+ if (pI830->bios_version >= 3272)
+ I830VESASetVBEMode(pScrn, getmode, NULL);
+#endif
+
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "SetDisplayDevices call failed, writing config directly to SWF0.\n");
+ temp = INREG(SWF0);
+ OUTREG(SWF0, (temp & ~(0xffff)) | (devices & 0xffff));
+
+ if (GetDisplayDevices(pScrn) != devices)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "SetDisplayDevices failed with devices 0x%x instead of 0x%x\n",
+ GetDisplayDevices(pScrn), devices);
+
+ return FALSE;
+}
+
+static Bool
+GetBIOSVersion(ScrnInfoPtr pScrn, unsigned int *version)
+{
+ vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;
+
+ DPRINTF(PFX, "GetBIOSVersion\n");
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x5f01;
+
+ xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
+ if (Check5fStatus(pScrn, 0x5f01, pVbe->pInt10->ax)) {
+ *version = pVbe->pInt10->bx;
+ return TRUE;
+ }
+
+ *version = 0;
+ return FALSE;
}
-#if 0
static Bool
GetDevicePresence(ScrnInfoPtr pScrn, Bool *required, int *attached,
int *encoderPresent)
@@ -604,7 +702,6 @@ GetDevicePresence(ScrnInfoPtr pScrn, Bool *required, int *attached,
} else
return FALSE;
}
-#endif
static Bool
GetDisplayInfo(ScrnInfoPtr pScrn, int device, Bool *attached, Bool *present,
@@ -663,8 +760,10 @@ static const char *displayDevices[] = {
"TV",
"DFP (digital flat panel)",
"LFP (local flat panel)",
+ "CRT2 (second CRT)",
"TV2 (second TV)",
"DFP2 (second digital flat panel)",
+ "LFP2 (second local flat panel)",
NULL
};
@@ -672,7 +771,7 @@ static const char *
DeviceToString(int device)
{
static int savedDevice = -1;
- static int bit = 0;
+ int bit = 0;
const char *name;
if (device == -1) {
@@ -704,7 +803,7 @@ PrintDisplayDeviceInfo(ScrnInfoPtr pScrn)
DPRINTF(PFX, "PrintDisplayDeviceInfo\n");
- displays = pI830->configuredDevices;
+ displays = pI830->operatingDevices;
if (displays == -1) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"No active display devices.\n");
@@ -758,7 +857,7 @@ GetPipeSizes(ScrnInfoPtr pScrn)
for (n = 0; n < pI830->availablePipes; n++) {
- pipe = (pI830->configuredDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK;
+ pipe = (pI830->operatingDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK;
pI830->pipeDisplaySize[n].x1 = pI830->pipeDisplaySize[n].y1 = 0;
pI830->pipeDisplaySize[n].x2 = pI830->pipeDisplaySize[n].y2 = 4096;
for (i = 0; i < NumKnownDisplayTypes; i++) {
@@ -790,47 +889,38 @@ I830DetectDisplayDevice(ScrnInfoPtr pScrn)
I830Ptr pI830 = I830PTR(pScrn);
int pipe, n;
DisplayType i;
-
- for (i = 0; i < NumKnownDisplayTypes; i++) {
- if (GetDisplayInfo(pScrn, 1 << i, &pI830->displayAttached[i],
+
+ /* This seems to lockup some Dell BIOS'. So it's on option to turn on */
+ if (pI830->displayInfo) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Broken BIOSes cause the system to hang here.\n"
+ "\t If you encounter this problem please add \n"
+ "\t\t Option \"DisplayInfo\" \"FALSE\"\n"
+ "\t to the Device section of your XF86Config file.\n");
+ for (i = 0; i < NumKnownDisplayTypes; i++) {
+ if (GetDisplayInfo(pScrn, 1 << i, &pI830->displayAttached[i],
&pI830->displayPresent[i],
&pI830->displaySize[i].x2,
&pI830->displaySize[i].y2)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Display Info: %s: attached: %s, present: %s, size: "
"(%d,%d)\n", displayDevices[i],
BOOLTOSTRING(pI830->displayAttached[i]),
BOOLTOSTRING(pI830->displayPresent[i]),
pI830->displaySize[i].x2, pI830->displaySize[i].y2);
+ }
}
}
- pI830->configuredDevices = GetDisplayDevices(pScrn);
- if (pI830->configuredDevices == -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Failed to detect active display devices\n");
- return FALSE;
- }
-
/* Check for active devices connected to each display pipe. */
for (n = 0; n < pI830->availablePipes; n++) {
- pipe = ((pI830->configuredDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK);
+ pipe = ((pI830->operatingDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK);
if (pipe) {
pI830->pipeEnabled[n] = TRUE;
}
}
GetPipeSizes(pScrn);
- PrintDisplayDeviceInfo(pScrn);
-
-#if 0
- /* A quick hack to change the set of enabled devices. */
- enabledDevices = PIPE_CRT_ACTIVE;
- if (!SetDisplayDevices(pScrn, enabledDevices)) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Failed to switch to configured display devices\n");
- }
-#endif
return TRUE;
}
@@ -842,40 +932,51 @@ I830DetectMemory(ScrnInfoPtr pScrn)
PCITAG bridge;
CARD16 gmch_ctrl;
int memsize = 0;
+ int range;
bridge = pciTag(0, 0, 0); /* This is always the host bridge */
gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
- if (IS_I85X(pI830) || IS_I865G(pI830))
- {
+ /* We need to reduce the stolen size, by the GTT and the popup.
+ * The GTT varying according the the FbMapSize and the popup is 4KB */
+ range = (pI830->FbMapSize / (1024*1024)) + 4;
+
+ if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I915G(pI830)) {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
case I855_GMCH_GMS_STOLEN_1M:
- memsize = MB(1) - KB(132);
+ memsize = MB(1) - KB(range);
break;
case I855_GMCH_GMS_STOLEN_4M:
- memsize = MB(4) - KB(132);
+ memsize = MB(4) - KB(range);
break;
case I855_GMCH_GMS_STOLEN_8M:
- memsize = MB(8) - KB(132);
+ memsize = MB(8) - KB(range);
break;
case I855_GMCH_GMS_STOLEN_16M:
- memsize = MB(16) - KB(132);
+ memsize = MB(16) - KB(range);
break;
case I855_GMCH_GMS_STOLEN_32M:
- memsize = MB(32) - KB(132);
+ memsize = MB(32) - KB(range);
+ break;
+ case I915G_GMCH_GMS_STOLEN_48M:
+ if (IS_I915G(pI830))
+ memsize = MB(48) - KB(range);
+ break;
+ case I915G_GMCH_GMS_STOLEN_64M:
+ if (IS_I915G(pI830))
+ memsize = MB(64) - KB(range);
break;
}
- } else
- {
+ } else {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
case I830_GMCH_GMS_STOLEN_512:
- memsize = KB(512) - KB(132);
+ memsize = KB(512) - KB(range);
break;
case I830_GMCH_GMS_STOLEN_1024:
- memsize = MB(1) - KB(132);
+ memsize = MB(1) - KB(range);
break;
case I830_GMCH_GMS_STOLEN_8192:
- memsize = MB(8) - KB(132);
+ memsize = MB(8) - KB(range);
break;
case I830_GMCH_GMS_LOCAL:
memsize = 0;
@@ -931,7 +1032,8 @@ I830MapMem(ScrnInfoPtr pScrn)
if (!pI830->FbBase)
return FALSE;
- pI830->LpRing.virtual_start = pI830->FbBase + pI830->LpRing.mem.Start;
+ if (IsPrimary(pScrn))
+ pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem.Start;
return TRUE;
}
@@ -1063,6 +1165,93 @@ SaveBIOSMemSize(ScrnInfoPtr pScrn)
return FALSE;
}
+/*
+ * TweakMemorySize() tweaks the BIOS image to set the correct size.
+ * Original implementation by Christian Zietz in a stand-alone tool.
+ */
+static CARD32
+TweakMemorySize(ScrnInfoPtr pScrn, CARD32 newsize)
+{
+#define SIZE 0x10000
+#define IDOFFSET (-23)
+ const char *MAGICstring = "Total time for VGA POST:";
+ const int len = strlen(MAGICstring);
+ I830Ptr pI830 = I830PTR(pScrn);
+ char *position;
+ char *biosAddr;
+ CARD32 oldsize;
+ CARD32 oldpermission;
+ CARD32 ret = 0;
+ int i,j = 0;
+ PCITAG tag =pciTag(0,0,0);
+
+ if(!pI830->PciInfo
+ || !(pI830->PciInfo->chipType == PCI_CHIP_I855_GM
+ || pI830->PciInfo->chipType == PCI_CHIP_I865_G))
+ return 0;
+
+ if (!pI830->pVbe)
+ return 0;
+
+ biosAddr = xf86int10Addr(pI830->pVbe->pInt10,
+ pI830->pVbe->pInt10->BIOSseg << 4);
+
+ if (!pI830->BIOSMemSizeLoc) {
+
+ if (!pI830->preinit)
+ return 0;
+
+ /* Search for MAGIC string */
+ for (i = 0; i < SIZE; i++) {
+ if (biosAddr[i] == MAGICstring[j]) {
+ if (++j == len)
+ break;
+ } else {
+ i -= j;
+ j = 0;
+ }
+ }
+ if (j < len) return 0;
+
+ pI830->BIOSMemSizeLoc = (i - j + 1 + IDOFFSET);
+ }
+
+ position = biosAddr + pI830->BIOSMemSizeLoc;
+ oldsize = *(CARD32 *)position;
+ ret = oldsize - (3 << 16);
+
+ /* verify that register really contains current size */
+ if (pI830->preinit && ((oldsize) >> 16) - 3 != pI830->vbeInfo->TotalMemory)
+ return 0;
+
+ oldpermission = pciReadLong(tag, DRAM_RW_CONTROL);
+ pciWriteLong(tag, DRAM_RW_CONTROL, 0x33330000);
+
+ *(CARD32 *)position = newsize + (3 << 16);
+ if (pI830->preinit) {
+ /* reinitialize VBE for new size */
+ VBEFreeVBEInfo(pI830->vbeInfo);
+ vbeFree(pI830->pVbe);
+ pI830->pVbe = VBEInit(NULL, pI830->pEnt->index);
+ pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
+
+ /* verify that change was successful */
+ if (pI830->vbeInfo->TotalMemory * 64 * 1024 != pI830->newBIOSMemSize) {
+ ret = 0;
+ *(CARD32 *)position = oldsize;
+ } else {
+ pI830->BIOSMemorySize = KB(pI830->vbeInfo->TotalMemory * 64);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Tweak BIOS image to %d kB VideoRAM\n",
+ (int)(pI830->BIOSMemorySize / 1024));
+ }
+ }
+
+ pciWriteLong(tag, DRAM_RW_CONTROL, oldpermission);
+
+ return ret;
+}
+
static void
RestoreBIOSMemSize(ScrnInfoPtr pScrn)
{
@@ -1071,6 +1260,9 @@ RestoreBIOSMemSize(ScrnInfoPtr pScrn)
DPRINTF(PFX, "RestoreBIOSMemSize\n");
+ if (TweakMemorySize(pScrn, pI830->saveBIOSMemSize))
+ return;
+
if (!pI830->overrideBIOSMemSize)
return;
@@ -1093,7 +1285,7 @@ static void
SetBIOSMemSize(ScrnInfoPtr pScrn, int newSize)
{
I830Ptr pI830 = I830PTR(pScrn);
- CARD32 swf1;
+ unsigned long swf1;
Bool mapped;
DPRINTF(PFX, "SetBIOSMemSize: %d kB\n", newSize / 1024);
@@ -1109,7 +1301,7 @@ SetBIOSMemSize(ScrnInfoPtr pScrn, int newSize)
#endif
if ((IS_I830(pI830) || IS_845G(pI830)) && pI830->useSWF1) {
- CARD32 newSWF1;
+ unsigned long newSWF1;
/* Need MMIO access here. */
mapped = (pI830->MMIOBase != NULL);
@@ -1122,10 +1314,10 @@ SetBIOSMemSize(ScrnInfoPtr pScrn, int newSize)
newSWF1 = 8;
swf1 = INREG(SWF1);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Before: SWF1 is 0x%08x\n", swf1);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Before: SWF1 is 0x%08lx\n", swf1);
swf1 &= ~0x0f;
swf1 |= (newSWF1 & 0x0f);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "After: SWF1 is 0x%08x\n", swf1);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "After: SWF1 is 0x%08lx\n", swf1);
OUTREG(SWF1, swf1);
if (!mapped)
I830UnmapMMIO(pScrn);
@@ -1151,7 +1343,7 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
pI830 = I830PTR(pScrn);
- if (pI830->pipeEnabled[0]) {
+ if (pI830->pipe == 0) {
/* It seems that an initial read is needed. */
temp = INREG(PALETTE_A);
for (i = 0; i < numColors; i++) {
@@ -1163,7 +1355,7 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
OUTREG(PALETTE_A + index * 4, val);
}
}
- if (pI830->pipeEnabled[1]) {
+ if (pI830->pipe == 1) {
/* It seems that an initial read is needed. */
temp = INREG(PALETTE_B);
for (i = 0; i < numColors; i++) {
@@ -1182,6 +1374,28 @@ PreInitCleanup(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
+ if (IsPrimary(pScrn) && pI830->LpRing) {
+ xfree(pI830->LpRing);
+ pI830->LpRing = NULL;
+ }
+ if (IsPrimary(pScrn) && pI830->CursorMem) {
+ xfree(pI830->CursorMem);
+ pI830->CursorMem = NULL;
+ }
+ if (IsPrimary(pScrn) && pI830->CursorMemARGB) {
+ xfree(pI830->CursorMemARGB);
+ pI830->CursorMemARGB = NULL;
+ }
+ if (IsPrimary(pScrn) && pI830->OverlayMem) {
+ xfree(pI830->OverlayMem);
+ pI830->OverlayMem = NULL;
+ }
+ if (IsPrimary(pScrn) && pI830->overlayOn) {
+ xfree(pI830->overlayOn);
+ pI830->overlayOn = NULL;
+ }
+ if (!IsPrimary(pScrn) && pI830->entityPrivate)
+ pI830->entityPrivate->pScrn_2 = NULL;
RestoreBIOSMemSize(pScrn);
if (pI830->swfSaved) {
OUTREG(SWF0, pI830->saveSWF0);
@@ -1192,6 +1406,90 @@ PreInitCleanup(ScrnInfoPtr pScrn)
I830BIOSFreeRec(pScrn);
}
+static int
+GetBIOSPipe(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ vbeInfoPtr pVbe = pI830->pVbe;
+ int pipe;
+
+ DPRINTF(PFX, "GetBIOSPipe:\n");
+
+ /* single pipe machines should always return Pipe A */
+ if (pI830->availablePipes == 1) return 0;
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x5f1c;
+ pVbe->pInt10->bx = 0x100;
+
+ xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
+ if (Check5fStatus(pScrn, 0x5f1c, pVbe->pInt10->ax)) {
+ if (pI830->newPipeSwitch) {
+ pipe = ((pVbe->pInt10->bx & 0x0001));
+ } else {
+ pipe = ((pVbe->pInt10->cx & 0x0100) >> 8);
+ }
+ return pipe;
+ }
+
+ return -1;
+}
+
+static Bool
+SetBIOSPipe(ScrnInfoPtr pScrn, int pipe)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ vbeInfoPtr pVbe = pI830->pVbe;
+
+ DPRINTF(PFX, "SetBIOSPipe: pipe 0x%x\n", pipe);
+
+ /* single pipe machines should always return TRUE */
+ if (pI830->availablePipes == 1) return TRUE;
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x5f1c;
+ if (pI830->newPipeSwitch) {
+ pVbe->pInt10->bx = pipe;
+ pVbe->pInt10->cx = 0;
+ } else {
+ pVbe->pInt10->bx = 0x0;
+ pVbe->pInt10->cx = pipe << 8;
+ }
+
+ xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
+ if (Check5fStatus(pScrn, 0x5f1c, pVbe->pInt10->ax))
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool
+SetPipeAccess(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ /* Don't try messing with the pipe, unless we're dual head */
+ if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) {
+ if (!SetBIOSPipe(pScrn, pI830->pipe))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+IsPrimary(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ if (pI830->init == 0) return TRUE;
+ else return FALSE;
+ }
+
+ return TRUE;
+}
+
static Bool
I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
{
@@ -1199,14 +1497,17 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
I830Ptr pI830;
MessageType from;
rgb defaultWeight = { 0, 0, 0 };
- vbeInfoPtr pVbe;
EntityInfoPtr pEnt;
+ I830EntPtr pI830Ent = NULL;
int mem, memsize;
int flags24;
int i, n;
+ char *s;
pointer pDDCModule, pVBEModule;
Bool enable;
const char *chipname;
+ unsigned int ver;
+ char v[5];
if (pScrn->numEntities != 1)
return FALSE;
@@ -1233,7 +1534,6 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
xf86LoaderReqSymLists(I810vgahwSymbols, NULL);
-
/* Allocate a vgaHWRec */
if (!vgaHWGetHWRec(pScrn))
return FALSE;
@@ -1243,6 +1543,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
pI830 = I830PTR(pScrn);
+ pI830->SaveGeneration = -1;
pI830->pEnt = pEnt;
if (pI830->pEnt->location.type != BUS_PCI)
@@ -1252,10 +1553,17 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->PciTag = pciTag(pI830->PciInfo->bus, pI830->PciInfo->device,
pI830->PciInfo->func);
+ /* Allocate an entity private if necessary */
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ pI830Ent = xf86GetEntityPrivate(pScrn->entityList[0],
+ I830EntityIndex)->ptr;
+ pI830->entityPrivate = pI830Ent;
+ } else
+ pI830->entityPrivate = NULL;
+
if (xf86RegisterResources(pI830->pEnt->index, 0, ResNone)) {
PreInitCleanup(pScrn);
return FALSE;
-
}
pScrn->racMemFlags = RAC_FB | RAC_COLORMAP;
@@ -1290,6 +1598,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
hwp = VGAHWPTR(pScrn);
pI830->cpp = pScrn->bitsPerPixel / 8;
+ pI830->preinit = TRUE;
+
/* Process the options */
xf86CollectOptions(pScrn, NULL);
if (!(pI830->Options = xalloc(sizeof(I830BIOSOptions))))
@@ -1340,6 +1650,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_I865_G:
chipname = "865G";
break;
+ case PCI_CHIP_I915_G:
+ chipname = "915G";
+ break;
default:
chipname = "unknown chipset";
break;
@@ -1347,9 +1660,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Integrated Graphics Chipset: Intel(R) %s\n", chipname);
- pVbe = pI830->pVbe;
-
- pI830->vbeInfo = VBEGetVBEInfo(pVbe);
+ pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
/* Set the Chipset and ChipRev, allowing config file entries to override. */
if (pI830->pEnt->device->chipset && *pI830->pEnt->device->chipset) {
@@ -1379,7 +1690,10 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->LinearAddr = pI830->pEnt->device->MemBase;
from = X_CONFIG;
} else {
- if (pI830->PciInfo->memBase[1] != 0) {
+ if (IS_I915G(pI830)) {
+ pI830->LinearAddr = pI830->PciInfo->memBase[2] & 0xF0000000;
+ from = X_PROBED;
+ } else if (pI830->PciInfo->memBase[1] != 0) {
/* XXX Check mask. */
pI830->LinearAddr = pI830->PciInfo->memBase[0] & 0xFF000000;
from = X_PROBED;
@@ -1398,7 +1712,10 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
pI830->MMIOAddr = pI830->pEnt->device->IOBase;
from = X_CONFIG;
} else {
- if (pI830->PciInfo->memBase[1]) {
+ if (IS_I915G(pI830)) {
+ pI830->MMIOAddr = pI830->PciInfo->memBase[0] & 0xFFF80000;
+ from = X_PROBED;
+ } else if (pI830->PciInfo->memBase[1]) {
pI830->MMIOAddr = pI830->PciInfo->memBase[1] & 0xFFF80000;
from = X_PROBED;
} else {
@@ -1437,14 +1754,43 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
pI830->FbMapSize = 0x8000000;
} else {
- pI830->FbMapSize = 0x4000000;
+ pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */
}
+ } else {
+ if (IS_I915G(pI830)) {
+ if (pI830->PciInfo->memBase[2] & 0x08000000)
+ pI830->FbMapSize = 0x8000000; /* 128MB aperture */
+ else
+ pI830->FbMapSize = 0x10000000; /* 256MB aperture */
+ } else
+ /* 128MB aperture for later chips */
+ pI830->FbMapSize = 0x8000000;
}
- else {
- /* 128MB aperture for later chips */
- pI830->FbMapSize = 0x8000000;
+
+
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ if (xf86IsPrimInitDone(pScrn->entityList[0])) {
+ pI830->init = 1;
+
+ if (!pI830Ent->pScrn_1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to setup second head due to primary head failure.\n");
+ return FALSE;
+ }
+
+ } else {
+ xf86SetPrimInitDone(pScrn->entityList[0]);
+ pI830->init = 0;
+ }
}
+ if (IS_MOBILE(pI830) || IS_I915G(pI830))
+ pI830->availablePipes = 2;
+ else
+ pI830->availablePipes = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n",
+ pI830->availablePipes, pI830->availablePipes > 1 ? "s" : "");
+
/*
* Get the pre-allocated (stolen) memory size.
*/
@@ -1455,15 +1801,21 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
/* Sanity check: compare with what the BIOS thinks. */
if (pI830->vbeInfo->TotalMemory != pI830->StolenMemory.Size / 1024 / 64) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Detected stolen memory (%d kB) doesn't match what the BIOS"
+ "Detected stolen memory (%ld kB) doesn't match what the BIOS"
" reports (%d kB)\n",
ROUND_DOWN_TO(pI830->StolenMemory.Size / 1024, 64),
pI830->vbeInfo->TotalMemory * 64);
}
/* Find the maximum amount of agpgart memory available. */
- mem = I830CheckAvailableMemory(pScrn);
- pI830->StolenOnly = FALSE;
+ if (IsPrimary(pScrn)) {
+ mem = I830CheckAvailableMemory(pScrn);
+ pI830->StolenOnly = FALSE;
+ } else {
+ /* videoRam isn't used on the second head, but faked */
+ mem = pI830->entityPrivate->pScrn_1->videoRam;
+ pI830->StolenOnly = TRUE;
+ }
if (mem <= 0) {
if (pI830->StolenMemory.Size <= 0) {
@@ -1507,6 +1859,154 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
#endif
+ pI830->MonType1 = PIPE_NONE;
+ pI830->MonType2 = PIPE_NONE;
+
+ if ((s = xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT)) &&
+ IsPrimary(pScrn)) {
+ char *Mon1;
+ char *Mon2;
+ char *sub;
+
+ Mon1 = strtok(s, ",");
+ Mon2 = strtok(NULL, ",");
+
+ if (Mon1) {
+ sub = strtok(Mon1, "+");
+ do {
+ if (strcmp(sub, "NONE") == 0)
+ pI830->MonType1 |= PIPE_NONE;
+ else if (strcmp(sub, "CRT") == 0)
+ pI830->MonType1 |= PIPE_CRT;
+ else if (strcmp(sub, "TV") == 0)
+ pI830->MonType1 |= PIPE_TV;
+ else if (strcmp(sub, "DFP") == 0)
+ pI830->MonType1 |= PIPE_DFP;
+ else if (strcmp(sub, "LFP") == 0)
+ pI830->MonType1 |= PIPE_LFP;
+ else if (strcmp(sub, "CRT2") == 0)
+ pI830->MonType1 |= PIPE_CRT2;
+ else if (strcmp(sub, "TV2") == 0)
+ pI830->MonType1 |= PIPE_TV2;
+ else if (strcmp(sub, "DFP2") == 0)
+ pI830->MonType1 |= PIPE_DFP2;
+ else if (strcmp(sub, "LFP2") == 0)
+ pI830->MonType1 |= PIPE_LFP2;
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Invalid Monitor type specified for Pipe A\n");
+
+ sub = strtok(NULL, "+");
+ } while (sub);
+ }
+
+ if (Mon2) {
+ sub = strtok(Mon2, "+");
+ do {
+ if (strcmp(sub, "NONE") == 0)
+ pI830->MonType2 |= PIPE_NONE;
+ else if (strcmp(sub, "CRT") == 0)
+ pI830->MonType2 |= PIPE_CRT;
+ else if (strcmp(sub, "TV") == 0)
+ pI830->MonType2 |= PIPE_TV;
+ else if (strcmp(sub, "DFP") == 0)
+ pI830->MonType2 |= PIPE_DFP;
+ else if (strcmp(sub, "LFP") == 0)
+ pI830->MonType2 |= PIPE_LFP;
+ else if (strcmp(sub, "CRT2") == 0)
+ pI830->MonType2 |= PIPE_CRT2;
+ else if (strcmp(sub, "TV2") == 0)
+ pI830->MonType2 |= PIPE_TV2;
+ else if (strcmp(sub, "DFP2") == 0)
+ pI830->MonType2 |= PIPE_DFP2;
+ else if (strcmp(sub, "LFP2") == 0)
+ pI830->MonType2 |= PIPE_LFP2;
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Invalid Monitor type specified for Pipe B\n");
+
+ sub = strtok(NULL, "+");
+ } while (sub);
+ }
+
+ if (pI830->availablePipes == 1 && pI830->MonType2 != PIPE_NONE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Monitor 2 cannot be specified on single pipe devices\n");
+ return FALSE;
+ }
+
+ if (pI830->MonType1 == PIPE_NONE && pI830->MonType2 == PIPE_NONE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Monitor 1 and 2 cannot be type NONE\n");
+ return FALSE;
+ }
+ }
+
+ if (xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) {
+ if (pI830->availablePipes == 1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Can't enable Clone Mode because this is a single pipe device\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+ if (pI830->entityPrivate) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Can't enable Clone Mode because second head is configured\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling Clone Mode\n");
+ pI830->CloneRefresh = 60; /* default to 60Hz */
+ if (xf86GetOptValInteger(pI830->Options, OPTION_CLONE_REFRESH,
+ &(pI830->CloneRefresh))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Clone Monitor Refresh Rate %d\n",
+ pI830->CloneRefresh);
+ }
+ if (pI830->CloneRefresh < 60 || pI830->CloneRefresh > 120) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Bad Clone Refresh Rate\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+ pI830->Clone = TRUE;
+ }
+
+ if ((pI830->entityPrivate && IsPrimary(pScrn)) || pI830->Clone) {
+ if ((!xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "You must have a MonitorLayout "
+ "defined for use in a DualHead or Clone setup.\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+
+ if (pI830->MonType1 == PIPE_NONE || pI830->MonType2 == PIPE_NONE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Monitor 1 or Monitor 2 "
+ "cannot be type NONE in Dual or Clone setup.\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+ }
+
+ /*
+ * Let's setup the mobile systems to check the lid status
+ */
+ if (IS_MOBILE(pI830)) {
+ pI830->checkLid = TRUE;
+
+ if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKLID, TRUE)) {
+ pI830->checkLid = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Checking Lid status disabled\n");
+ } else
+ if (pI830->entityPrivate && !IsPrimary(pScrn) &&
+ !I830PTR(pI830->entityPrivate->pScrn_1)->checkLid) {
+ /* If checklid is off, on the primary head, then
+ * turn it off on the secondary*/
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Checking Lid status disabled\n");
+ pI830->checkLid = FALSE;
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Checking Lid status enabled\n");
+ } else
+ pI830->checkLid = FALSE;
+
/*
* The "VideoRam" config file parameter specifies the total amount of
* memory that will be used/allocated. When agpgart support isn't
@@ -1520,6 +2020,10 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
* amount is higher, default to it rounded up to the nearest MB. This
* guarantees that by default there will be at least some run-time
* space for things that need a physical address.
+ * But, we double the amounts when dual head is enabled, and therefore
+ * for 2D-only we use 16384KB, and 3D we use 65536KB. The VideoRAM
+ * for the second head is never used, as the primary head does the
+ * allocation.
*/
if (!pI830->pEnt->device->videoRam) {
from = X_DEFAULT;
@@ -1529,6 +2033,14 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
else
#endif
pScrn->videoRam = I830_DEFAULT_VIDEOMEM_2D;
+
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ if (IsPrimary(pScrn))
+ pScrn->videoRam *= 2;
+ else
+ pScrn->videoRam = I830_MAXIMUM_VBIOS_MEM;
+ }
+
if (pI830->StolenMemory.Size / 1024 > pScrn->videoRam)
pScrn->videoRam = ROUND_TO(pI830->StolenMemory.Size / 1024, 1024);
} else {
@@ -1559,7 +2071,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
"VideoRam reduced to %d kByte (limited to aperture size)\n",
pScrn->videoRam);
}
-
+
if (mem > 0) {
/*
* If the reserved (BIOS accessible) memory is less than the desired
@@ -1579,20 +2091,18 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
*/
/* Try to keep HW cursor and Overlay amounts separate from this. */
- int reserve = (HWCURSOR_SIZE + OVERLAY_SIZE) / 1024;
+ int reserve = (HWCURSOR_SIZE + HWCURSOR_SIZE_ARGB + OVERLAY_SIZE) / 1024;
if (pScrn->videoRam - reserve >= I830_MAXIMUM_VBIOS_MEM)
pI830->newBIOSMemSize = KB(I830_MAXIMUM_VBIOS_MEM);
else
pI830->newBIOSMemSize =
KB(ROUND_DOWN_TO(pScrn->videoRam - reserve, 64));
-
if (pI830->vbeInfo->TotalMemory * 64 < pI830->newBIOSMemSize / 1024) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Will attempt to tell the BIOS that there is "
"%d kB VideoRAM\n", pI830->newBIOSMemSize / 1024);
-
if (SaveBIOSMemSize(pScrn)) {
pI830->overrideBIOSMemSize = TRUE;
SetBIOSMemSize(pScrn, pI830->newBIOSMemSize);
@@ -1600,14 +2110,17 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
VBEFreeVBEInfo(pI830->vbeInfo);
vbeFree(pI830->pVbe);
pI830->pVbe = VBEInit(NULL, pI830->pEnt->index);
- pVbe = pI830->pVbe;
- pI830->vbeInfo = VBEGetVBEInfo(pVbe);
+ pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
pI830->BIOSMemorySize = KB(pI830->vbeInfo->TotalMemory * 64);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "BIOS now sees %d kB VideoRAM\n",
+ "BIOS now sees %ld kB VideoRAM\n",
pI830->BIOSMemorySize / 1024);
- } else {
+ } else
+ if ((pI830->saveBIOSMemSize =
+ TweakMemorySize(pScrn, pI830->newBIOSMemSize)) != 0)
+ pI830->overrideBIOSMemSize = TRUE;
+ else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"BIOS view of memory size can't be changed "
"(this is not an error).\n");
@@ -1615,9 +2128,11 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
}
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Pre-allocated VideoRAM: %d kByte\n",
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Pre-allocated VideoRAM: %ld kByte\n",
pI830->StolenMemory.Size / 1024);
- xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", pScrn->videoRam);
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
pI830->TotalVideoRam = KB(pScrn->videoRam);
/*
@@ -1668,20 +2183,203 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
#endif
+ /*
+ * If the driver can do gamma correction, it should call xf86SetGamma() here.
+ */
+
+ {
+ Gamma zeros = { 0.0, 0.0, 0.0 };
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+ }
+
+ GetBIOSVersion(pScrn, &ver);
+
+ v[0] = (ver & 0xff000000) >> 24;
+ v[1] = (ver & 0x00ff0000) >> 16;
+ v[2] = (ver & 0x0000ff00) >> 8;
+ v[3] = (ver & 0x000000ff) >> 0;
+
+ pI830->bios_version = atoi(v);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS Build: %d\n",pI830->bios_version);
+
+ /* BIOS build 3062 changed the pipe switching functionality */
+ if (pI830->availablePipes == 2 && pI830->bios_version >= 3062) {
+ pI830->newPipeSwitch = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using new Pipe switch code\n");
+ } else
+ pI830->newPipeSwitch = FALSE;
+
+ pI830->devicePresence = FALSE;
+ from = X_DEFAULT;
+ if (xf86ReturnOptValBool(pI830->Options, OPTION_DEVICE_PRESENCE, FALSE)) {
+ pI830->devicePresence = TRUE;
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Device Presence: %s.\n",
+ pI830->devicePresence ? "enabled" : "disabled");
+
+ /* This performs an active detect of the currently attached monitors
+ * or, at least it's meant to..... alas it doesn't seem to always work.
+ */
+ if (pI830->devicePresence) {
+ int req, att, enc;
+ GetDevicePresence(pScrn, &req, &att, &enc);
+ for (i = 0; i < NumDisplayTypes; i++) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Display Presence: %s: attached: %s, encoder: %s\n",
+ displayDevices[i],
+ BOOLTOSTRING(((1<<i) & att)>>i),
+ BOOLTOSTRING(((1<<i) & enc)>>i));
+ }
+ }
+
+ /* Save old configuration of detected devices */
+ pI830->savedDevices = GetDisplayDevices(pScrn);
+
+ if (IsPrimary(pScrn)) {
+ pI830->pipe = GetBIOSPipe(pScrn);
+
+ if (xf86ReturnOptValBool(pI830->Options, OPTION_FLIP_PRIMARY, FALSE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Primary flipping enabled\n");
+ pI830->pipe = !pI830->pipe;
+ }
+
+ /* If the monitors aren't setup, read from the current config */
+ if (pI830->MonType1 == PIPE_NONE)
+ pI830->MonType1 = pI830->savedDevices & 0xff;
+ if (pI830->MonType2 == PIPE_NONE)
+ pI830->MonType2 = (pI830->savedDevices & 0xff00) >> 8;
+
+ pI830->operatingDevices = (pI830->MonType2 << 8) | pI830->MonType1;
+
+ if (!xf86IsEntityShared(pScrn->entityList[0]) && !pI830->Clone) {
+ /* If we're not dual head or clone, turn off the second head,
+ * if monitorlayout is also specified. */
+
+ if (pI830->pipe == 0)
+ pI830->operatingDevices = pI830->MonType1;
+ else
+ pI830->operatingDevices = pI830->MonType2 << 8;
+
+ if (pI830->operatingDevices & 0xFF00)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Primary Pipe is %s, switching off second monitor (0x%x)\n",
+ pI830->pipe ? "B" : "A", pI830->operatingDevices);
+ }
+ } else {
+ I830Ptr pI8301 = I830PTR(pI830Ent->pScrn_1);
+ pI830->operatingDevices = pI8301->operatingDevices;
+ }
+
+ /* Buggy BIOS 3066 is known to cause this, so turn this off */
+ if (pI830->bios_version == 3066) {
+ pI830->displayInfo = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected Broken Video BIOS, turning off displayInfo.\n");
+ } else
+ pI830->displayInfo = TRUE;
+ from = X_DEFAULT;
+ if (!xf86ReturnOptValBool(pI830->Options, OPTION_DISPLAY_INFO, TRUE)) {
+ pI830->displayInfo = FALSE;
+ from = X_CONFIG;
+ }
+ if (xf86ReturnOptValBool(pI830->Options, OPTION_DISPLAY_INFO, FALSE)) {
+ pI830->displayInfo = TRUE;
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Display Info: %s.\n",
+ pI830->displayInfo ? "enabled" : "disabled");
+
+ if (!I830DetectDisplayDevice(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't detect display devices.\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+
+ if (!SetDisplayDevices(pScrn, pI830->operatingDevices)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to switch to monitor configuration (0x%x)\n",
+ pI830->operatingDevices);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Please check the devices specified in your MonitorLayout\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "is configured correctly.\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+
+ PrintDisplayDeviceInfo(pScrn);
+
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ if (!IsPrimary(pScrn)) {
+ I830Ptr pI8301 = I830PTR(pI830Ent->pScrn_1);
+
+ pI830Ent->pScrn_2 = pScrn;
+ pI830->pipe = !pI8301->pipe;
+
+ /* This could be made to work with a little more fiddling */
+ pI830->directRenderingDisabled = TRUE;
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Secondary head is using Pipe %s\n",
+ pI830->pipe ? "B" : "A");
+ } else {
+ pI830Ent->pScrn_1 = pScrn;
+ pI830Ent->pScrn_2 = NULL;
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Primary head is using Pipe %s\n",
+ pI830->pipe ? "B" : "A");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, from, "Display is using Pipe %s\n",
+ pI830->pipe ? "B" : "A");
+ }
+
+ /* Alloc our pointers for the primary head */
+ if (IsPrimary(pScrn)) {
+ pI830->LpRing = xalloc(sizeof(I830RingBuffer));
+ pI830->CursorMem = xalloc(sizeof(I830MemRange));
+ pI830->CursorMemARGB = xalloc(sizeof(I830MemRange));
+ pI830->OverlayMem = xalloc(sizeof(I830MemRange));
+ pI830->overlayOn = xalloc(sizeof(Bool));
+ if (!pI830->LpRing || !pI830->CursorMem || !pI830->CursorMemARGB ||
+ !pI830->OverlayMem || !pI830->overlayOn) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not allocate primary data structures.\n");
+ PreInitCleanup(pScrn);
+ return FALSE;
+ }
+ *pI830->overlayOn = FALSE;
+ if (pI830->entityPrivate)
+ pI830->entityPrivate->XvInUse = -1;
+ }
+
/* Check if the HW cursor needs physical address. */
- if (IS_MOBILE(pI830))
+ if (IS_MOBILE(pI830) || IS_I915G(pI830))
pI830->CursorNeedsPhysical = TRUE;
else
pI830->CursorNeedsPhysical = FALSE;
- /* Force ring buffer to be in low memory for the 845G. */
- if (IS_845G(pI830) || IS_I85X(pI830) || IS_I865G(pI830))
+ /* Force ring buffer to be in low memory for the 845G and later. */
+ if (IS_845G(pI830) || IS_I85X(pI830) || IS_I865G(pI830) || IS_I915G(pI830))
pI830->NeedRingBufferLow = TRUE;
/*
* XXX If we knew the pre-initialised GTT format for certain, we could
* probably figure out the physical address even in the StolenOnly case.
*/
+ if (!IsPrimary(pScrn)) {
+ I830Ptr pI8301 = I830PTR(pI830Ent->pScrn_1);
+ if (!pI8301->SWCursor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using HW Cursor because it's enabled on primary head.\n");
+ pI830->SWCursor = FALSE;
+ }
+ } else
if (pI830->StolenOnly && pI830->CursorNeedsPhysical && !pI830->SWCursor) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"HW Cursor disabled because it needs agpgart memory.\n");
@@ -1692,8 +2390,10 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
* Reduce the maximum videoram available for video modes by the ring buffer,
* minimum scratch space and HW cursor amounts.
*/
- if (!pI830->SWCursor)
+ if (!pI830->SWCursor) {
pScrn->videoRam -= (HWCURSOR_SIZE / 1024);
+ pScrn->videoRam -= (HWCURSOR_SIZE_ARGB / 1024);
+ }
if (!pI830->XvDisabled)
pScrn->videoRam -= (OVERLAY_SIZE / 1024);
if (!pI830->noAccel) {
@@ -1704,37 +2404,13 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Maximum frambuffer space: %d kByte\n", pScrn->videoRam);
- /*
- * If the driver can do gamma correction, it should call xf86SetGamma() here.
- */
-
- {
- Gamma zeros = { 0.0, 0.0, 0.0 };
-
- if (!xf86SetGamma(pScrn, zeros))
- return FALSE;
- }
-
- if (IS_MOBILE(pI830))
- pI830->availablePipes = 2;
- else
- pI830->availablePipes = 1;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n",
- pI830->availablePipes, pI830->availablePipes > 1 ? "s" : "");
-
- if (!I830DetectDisplayDevice(pScrn)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Couldn't detect display devices.\n");
- PreInitCleanup(pScrn);
- return FALSE;
- }
-
+ SetPipeAccess(pScrn);
if ((pDDCModule = xf86LoadSubModule(pScrn, "ddc")) == NULL) {
PreInitCleanup(pScrn);
return FALSE;
}
- if ((pI830->vesa->monitor = vbeDoEDID(pVbe, pDDCModule)) != NULL) {
+ if ((pI830->vesa->monitor = vbeDoEDID(pI830->pVbe, pDDCModule)) != NULL) {
xf86PrintEDID(pI830->vesa->monitor);
}
if ((pScrn->monitor->DDC = pI830->vesa->monitor) != NULL)
@@ -1763,22 +2439,42 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
#endif
- for (i = 0; i < pI830->availablePipes; i++) {
+ pI830->useExtendedRefresh = FALSE;
+
+ if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) {
int pipe =
- (pI830->configuredDevices >> PIPE_SHIFT(i)) & PIPE_ACTIVE_MASK;
+ (pI830->operatingDevices >> PIPE_SHIFT(pI830->pipe)) & PIPE_ACTIVE_MASK;
if (pipe & ~PIPE_CRT_ACTIVE) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"A non-CRT device is attached to pipe %c.\n"
"\tNo refresh rate overrides will be attempted.\n",
- PIPE_NAME(i));
+ PIPE_NAME(pI830->pipe));
pI830->vesa->useDefaultRefresh = TRUE;
}
/*
* Some desktop platforms might not have 0x5f05, so useExtendedRefresh
* would need to be set to FALSE for those cases.
*/
- if (!pI830->vesa->useDefaultRefresh)
+ if (!pI830->vesa->useDefaultRefresh)
pI830->useExtendedRefresh = TRUE;
+ } else {
+ for (i = 0; i < pI830->availablePipes; i++) {
+ int pipe =
+ (pI830->operatingDevices >> PIPE_SHIFT(i)) & PIPE_ACTIVE_MASK;
+ if (pipe & ~PIPE_CRT_ACTIVE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "A non-CRT device is attached to pipe %c.\n"
+ "\tNo refresh rate overrides will be attempted.\n",
+ PIPE_NAME(i));
+ pI830->vesa->useDefaultRefresh = TRUE;
+ }
+ /*
+ * Some desktop platforms might not have 0x5f05, so useExtendedRefresh
+ * would need to be set to FALSE for those cases.
+ */
+ if (!pI830->vesa->useDefaultRefresh)
+ pI830->useExtendedRefresh = TRUE;
+ }
}
if (pI830->useExtendedRefresh) {
@@ -1787,18 +2483,6 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
/*
- * Calling 0x5f64 can reset the refresh rate, so only do this when
- * using 0x5f05, or when not overriding the default refresh rate.
- * Also, 0x5f64 doesn't work correctly in i830 platforms.
- */
- pI830->enableDisplays = !IS_I830(pI830) && pI830->useExtendedRefresh;
-
- if (pI830->enableDisplays) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Will use BIOS call 0x5f64 to enable displays.\n");
- }
-
- /*
* Limit videoram available for mode selection to what the video
* BIOS can see.
*/
@@ -1814,7 +2498,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
* functions. For that reason it's important to set only
* V_MODETYPE_VGA in the flags for VBEGetModePool().
*/
- pScrn->modePool = VBEGetModePool(pScrn, pVbe, pI830->vbeInfo,
+ pScrn->modePool = VBEGetModePool(pScrn, pI830->pVbe, pI830->vbeInfo,
V_MODETYPE_VGA);
if (!pScrn->modePool) {
@@ -1824,6 +2508,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
+ SetPipeAccess(pScrn);
VBESetModeNames(pScrn->modePool);
/*
@@ -1835,6 +2520,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
/* XXX Need to get relevant modes and virtual parameters. */
/* Do the mode validation without regard to special scanline pitches. */
+ SetPipeAccess(pScrn);
n = VBEValidateModes(pScrn, NULL, pScrn->display->modes, NULL,
NULL, 0, MAX_DISPLAY_PITCH, 1,
0, MAX_DISPLAY_HEIGHT,
@@ -1856,17 +2542,17 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
PreInitCleanup(pScrn);
return FALSE;
}
-
#ifndef USE_PITCHES
#define USE_PITCHES 1
#endif
+ pI830->disableTiling = FALSE;
/*
* If DRI is potentially usable, check if there is enough memory available
* for it, and if there's also enough to allow tiling to be enabled.
*/
#if defined(XF86DRI)
- if (!pI830->directRenderingDisabled) {
+ if (IsPrimary(pScrn) && !pI830->directRenderingDisabled) {
int savedDisplayWidth = pScrn->displayWidth;
int memNeeded = 0;
/* Good pitches to allow tiling. Don't care about pitches < 256. */
@@ -1920,7 +2606,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Allocation with DRI tiling enabled would "
"exceed the\n"
- "\tmemory aperture size (%d kB) by %d kB.\n"
+ "\tmemory aperture size (%ld kB) by %ld kB.\n"
"\tReduce VideoRam amount to avoid this!\n",
pI830->FbMapSize / 1024,
-pI830->MemoryAperture.Size / 1024);
@@ -1944,6 +2630,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
* Tiling can't be enabled. Check if there's enough memory for DRI
* without tiling.
*/
+ pI830->disableTiling = TRUE;
I830ResetAllocations(pScrn, 0);
if (I830Allocate2DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_INITIAL) &&
I830Allocate3DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_NO_TILING)) {
@@ -1959,7 +2646,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Allocation with DRI enabled would "
"exceed the\n"
- "\tmemory aperture size (%d kB) by %d kB.\n"
+ "\tmemory aperture size (%ld kB) by %ld kB.\n"
"\tReduce VideoRam amount to avoid this!\n",
pI830->FbMapSize / 1024,
-pI830->MemoryAperture.Size / 1024);
@@ -1975,6 +2662,7 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
#endif
+ SetPipeAccess(pScrn);
VBEPrintModes(pScrn);
if (!pI830->vesa->useDefaultRefresh) {
@@ -1985,7 +2673,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
* This only works for VBE 3.0 and later. Also, we only do this
* if there are no non-CRT devices attached.
*/
- VBESetModeParameters(pScrn, pVbe);
+ SetPipeAccess(pScrn);
+ VBESetModeParameters(pScrn, pI830->pVbe);
}
/* PreInit shouldn't leave any state changes, so restore this. */
@@ -1996,7 +2685,6 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
OUTREG(SWF0, pI830->saveSWF0);
OUTREG(SWF4, pI830->saveSWF4);
}
- I830UnmapMMIO(pScrn);
/* Set display resolution */
xf86SetDpi(pScrn, 0, 0);
@@ -2025,15 +2713,40 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
xf86LoaderReqSymLists(I810ramdacSymbols, NULL);
}
+ if (!SetDisplayDevices(pScrn, pI830->savedDevices)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to switch to saved display devices, continuing.\n");
+ }
+
+ I830UnmapMMIO(pScrn);
+
/* We won't be using the VGA access after the probe. */
I830SetMMIOAccess(pI830);
xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr);
xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr);
VBEFreeVBEInfo(pI830->vbeInfo);
- vbeFree(pVbe);
+ vbeFree(pI830->pVbe);
+ /* Use the VBE mode restore workaround by default. */
+ pI830->vbeRestoreWorkaround = TRUE;
+ from = X_DEFAULT;
+ if (xf86ReturnOptValBool(pI830->Options, OPTION_VBE_RESTORE, FALSE)) {
+ pI830->vbeRestoreWorkaround = FALSE;
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "VBE Restore workaround: %s.\n",
+ pI830->vbeRestoreWorkaround ? "enabled" : "disabled");
+
#if defined(XF86DRI)
+ /* Load the dri module if requested. */
+ if (xf86ReturnOptValBool(pI830->Options, OPTION_DRI, FALSE) &&
+ !pI830->directRenderingDisabled) {
+ if (xf86LoadSubModule(pScrn, "dri")) {
+ xf86LoaderReqSymLists(I810driSymbols, I810drmSymbols, NULL);
+ }
+ }
+
if (!pI830->directRenderingDisabled) {
if (!xf86LoadSubModule(pScrn, "shadow")) {
PreInitCleanup(pScrn);
@@ -2043,6 +2756,8 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags)
}
#endif
+ pI830->preinit = FALSE;
+
return TRUE;
}
@@ -2057,32 +2772,35 @@ CheckInheritedState(ScrnInfoPtr pScrn)
int errors = 0, fatal = 0;
unsigned long temp, head, tail;
+ if (!IsPrimary(pScrn)) return TRUE;
+
/* Check first for page table errors */
temp = INREG(PGE_ERR);
if (temp != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "PGTBL_ER is 0x%08x\n", temp);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "PGTBL_ER is 0x%08lx\n", temp);
errors++;
}
temp = INREG(PGETBL_CTL);
if (!(temp & 1)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "PGTBL_CTL (0x%08x) indicates GTT is disabled\n", temp);
+ "PGTBL_CTL (0x%08lx) indicates GTT is disabled\n", temp);
errors++;
}
temp = INREG(LP_RING + RING_LEN);
if (temp & 1) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "PRB0_CTL (0x%08x) indicates ring buffer enabled\n", temp);
+ "PRB0_CTL (0x%08lx) indicates ring buffer enabled\n", temp);
errors++;
}
head = INREG(LP_RING + RING_HEAD);
tail = INREG(LP_RING + RING_TAIL);
if ((tail & I830_TAIL_MASK) != (head & I830_HEAD_MASK)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "PRB0_HEAD (0x%08x) and PRB0_TAIL (0x%08x) indicate "
+ "PRB0_HEAD (0x%08lx) and PRB0_TAIL (0x%08lx) indicate "
"ring buffer not flushed\n", head, tail);
errors++;
}
+
#if 0
if (errors)
I830PrintErrorState(pScrn);
@@ -2109,6 +2827,11 @@ ResetState(ScrnInfoPtr pScrn, Bool flush)
DPRINTF(PFX, "ResetState: flush is %s\n", BOOLTOSTRING(flush));
+ if (!IsPrimary(pScrn)) return;
+
+ if (pI830->entityPrivate)
+ pI830->entityPrivate->RingRunning = 0;
+
/* Reset the fence registers to 0 */
for (i = 0; i < 8; i++)
OUTREG(FENCE + i * 4, 0);
@@ -2139,6 +2862,8 @@ SetFenceRegs(ScrnInfoPtr pScrn)
DPRINTF(PFX, "SetFenceRegs\n");
+ if (!IsPrimary(pScrn)) return;
+
for (i = 0; i < 8; i++) {
OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
if (I810_DEBUG & DEBUG_VERBOSE_VGA)
@@ -2157,29 +2882,34 @@ SetRingRegs(ScrnInfoPtr pScrn)
if (pI830->noAccel)
return;
+ if (!IsPrimary(pScrn)) return;
+
+ if (pI830->entityPrivate)
+ pI830->entityPrivate->RingRunning = 1;
+
OUTREG(LP_RING + RING_LEN, 0);
OUTREG(LP_RING + RING_TAIL, 0);
OUTREG(LP_RING + RING_HEAD, 0);
- if ((pI830->LpRing.mem.Start & I830_RING_START_MASK) !=
- pI830->LpRing.mem.Start) {
+ if ((pI830->LpRing->mem.Start & I830_RING_START_MASK) !=
+ pI830->LpRing->mem.Start) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "I830SetRingRegs: Ring buffer start (%x) violates its "
- "mask (%x)\n", pI830->LpRing.mem.Start, I830_RING_START_MASK);
+ "I830SetRingRegs: Ring buffer start (%lx) violates its "
+ "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK);
}
/* Don't care about the old value. Reserved bits must be zero anyway. */
- itemp = pI830->LpRing.mem.Start & I830_RING_START_MASK;
+ itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK;
OUTREG(LP_RING + RING_START, itemp);
- if (((pI830->LpRing.mem.Size - 4096) & I830_RING_NR_PAGES) !=
- pI830->LpRing.mem.Size - 4096) {
+ if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) !=
+ pI830->LpRing->mem.Size - 4096) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "I830SetRingRegs: Ring buffer size - 4096 (%x) violates its "
- "mask (%x)\n", pI830->LpRing.mem.Size - 4096,
+ "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its "
+ "mask (%x)\n", pI830->LpRing->mem.Size - 4096,
I830_RING_NR_PAGES);
}
/* Don't care about the old value. Reserved bits must be zero anyway. */
- itemp = (pI830->LpRing.mem.Size - 4096) & I830_RING_NR_PAGES;
+ itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES;
itemp |= (RING_NO_REPORT | RING_VALID);
OUTREG(LP_RING + RING_LEN, itemp);
I830RefreshRing(pScrn);
@@ -2215,7 +2945,10 @@ SaveHWState(ScrnInfoPtr pScrn)
DPRINTF(PFX, "SaveHWState\n");
+ SetPipeAccess(pScrn);
+
pVesa = pI830->vesa;
+
/* Make sure we save at least this information in case of failure. */
VBEGetVBEMode(pVbe, &pVesa->stateMode);
modeInfo = VBEGetModeInfo(pVbe, pVesa->stateMode);
@@ -2230,21 +2963,18 @@ SaveHWState(ScrnInfoPtr pScrn)
vgaHWUnlock(hwp);
vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS);
-#ifndef I845G_VBE_WORKAROUND
-#define I845G_VBE_WORKAROUND 1
-#endif
-
pVesa = pI830->vesa;
- /* This save/restore method doesn't work for 845G BIOS */
/*
- * XXX If it's fixed in production versions, this could be removed.
- *
+ * This save/restore method doesn't work for 845G BIOS, or for some
+ * other platforms. Enable it in all cases.
+ */
+ /*
* KW: This may have been because of the behaviour I've found on my
* board: The 'save' command actually modifies the interrupt
* registers, turning off the irq & breaking the kernel module
* behaviour.
*/
- if (!I845G_VBE_WORKAROUND || !IS_845G(pI830)) {
+ if (!pI830->vbeRestoreWorkaround) {
CARD16 imr = INREG16(IMR);
CARD16 ier = INREG16(IER);
CARD16 hwstam = INREG16(HWSTAM);
@@ -2269,6 +2999,8 @@ SaveHWState(ScrnInfoPtr pScrn)
return FALSE;
}
+ VBEGetDisplayStart(pVbe, &pVesa->x, &pVesa->y);
+
return TRUE;
}
@@ -2350,6 +3082,8 @@ RestoreHWState(ScrnInfoPtr pScrn)
if (pVesa->savedPal)
VBESetGetPaletteData(pVbe, TRUE, 0, 256, pVesa->savedPal, FALSE, TRUE);
+ VBESetDisplayStart(pVbe, pVesa->x, pVesa->y, TRUE);
+
vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
vgaHWLock(hwp);
return TRUE;
@@ -2359,12 +3093,92 @@ RestoreHWState(ScrnInfoPtr pScrn)
#define USE_VBE 1
#endif
+static void I830SetCloneVBERefresh(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block, int refresh)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ DisplayModePtr p = NULL;
+ int RefreshRate;
+ int clock;
+
+ /* Search for our mode and get a refresh to match */
+ for (p = pScrn->monitor->Modes; p != NULL; p = p->next) {
+ if ((p->HDisplay != pI830->CloneHDisplay) ||
+ (p->VDisplay != pI830->CloneVDisplay) ||
+ (p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
+ continue;
+ RefreshRate = ((double)(p->Clock * 1000) /
+ (double)(p->HTotal * p->VTotal)) * 100;
+ /* we could probably do better here that 2Hz boundaries */
+ if (RefreshRate > (refresh - 200) && RefreshRate < (refresh + 200)) {
+ block->HorizontalTotal = p->HTotal;
+ block->HorizontalSyncStart = p->HSyncStart;
+ block->HorizontalSyncEnd = p->HSyncEnd;
+ block->VerticalTotal = p->VTotal;
+ block->VerticalSyncStart = p->VSyncStart;
+ block->VerticalSyncEnd = p->VSyncEnd;
+ block->Flags = ((p->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
+ ((p->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
+ block->PixelClock = p->Clock * 1000;
+ /* XXX May not have this. */
+ clock = VBEGetPixelClock(pI830->pVbe, mode, block->PixelClock);
+#ifdef DEBUG
+ ErrorF("Setting clock %.2fMHz, closest is %.2fMHz\n",
+ (double)data->block->PixelClock / 1000000.0,
+ (double)clock / 1000000.0);
+#endif
+ if (clock)
+ block->PixelClock = clock;
+ block->RefreshRate = ((double)(block->PixelClock) /
+ (double)(p->HTotal * p->VTotal)) * 100;
+ return;
+ }
+ }
+}
+
static Bool
I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block)
{
I830Ptr pI830 = I830PTR(pScrn);
DPRINTF(PFX, "Setting mode 0x%.8x\n", mode);
+
+ if (pI830->Clone && !pI830->preinit) {
+ VbeCRTCInfoBlock newblock;
+ int Mon;
+
+ if (!pI830->pipe)
+ Mon = pI830->MonType2;
+ else
+ Mon = pI830->MonType1;
+
+ SetBIOSPipe(pScrn, !pI830->pipe);
+
+ /* The reason for this code is if we've not got a CRT on this pipe, then
+ * make sure we're using a 60Hz refresh */
+ if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh &&
+ (mode & (1 << 11)) && block) {
+ /* we'll call 5F05 to set the refresh later.... */
+ if (Mon != PIPE_CRT)
+ VBESetVBEMode(pI830->pVbe, mode, NULL);
+ else
+ VBESetVBEMode(pI830->pVbe, mode, block);
+ } else {
+ if (Mon != PIPE_CRT)
+ /* Set clone head to 60Hz because we ain't got a CRT on it */
+ I830SetCloneVBERefresh(pScrn, mode, &newblock, 6000);
+ else
+ /* Set clone head to specified clone refresh rate */
+ I830SetCloneVBERefresh(pScrn, mode, &newblock, pI830->CloneRefresh * 100);
+ if (newblock.RefreshRate == 0)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to setup clone head mode resolution and refresh.\n");
+ else
+ VBESetVBEMode(pI830->pVbe, mode, &newblock);
+ }
+ }
+
+ SetPipeAccess(pScrn);
+
#if USE_VBE
return VBESetVBEMode(pI830->pVbe, mode, block);
#else
@@ -2388,7 +3202,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
{
I830Ptr pI830 = I830PTR(pScrn);
vbeInfoPtr pVbe = pI830->pVbe;
- VbeModeInfoData *data;
+ VbeModeInfoData *data = (VbeModeInfoData *) pMode->Private;
int mode, i;
CARD32 planeA, planeB, temp;
int refresh = 60;
@@ -2398,8 +3212,6 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
DPRINTF(PFX, "I830VESASetMode\n");
- data = (VbeModeInfoData *) pMode->Private;
-
/* Always Enable Linear Addressing */
mode = data->mode | (1 << 15) | (1 << 14);
@@ -2411,6 +3223,26 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
}
#endif
+ /*
+ * Do this early to find out if we can support it or not....
+ * Test if the extendedRefresh BIOS function is supported.
+ */
+ if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh &&
+ (mode & (1 << 11)) && data && data->data && data->block) {
+ SetPipeAccess(pScrn);
+ if (!SetRefreshRate(pScrn, mode, 60)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "BIOS call 0x5f05 not supported, "
+ "setting refresh with VBE 3 method.\n");
+ pI830->useExtendedRefresh = FALSE;
+ }
+ }
+
+ if (pI830->Clone) {
+ pI830->CloneHDisplay = pMode->HDisplay;
+ pI830->CloneVDisplay = pMode->VDisplay;
+ }
+
#ifndef MODESWITCH_RESET_STATE
#define MODESWITCH_RESET_STATE 0
#endif
@@ -2444,37 +3276,58 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
* memory than it's aware of. We check for this later, and set it
* explicitly if necessary.
*/
- if (data->data->XResolution != pScrn->displayWidth)
+ if (data->data->XResolution != pScrn->displayWidth) {
+ if (pI830->Clone) {
+ SetBIOSPipe(pScrn, !pI830->pipe);
+ VBESetLogicalScanline(pVbe, pScrn->displayWidth);
+ }
+ SetPipeAccess(pScrn);
VBESetLogicalScanline(pVbe, pScrn->displayWidth);
+ }
- if (pScrn->bitsPerPixel >= 8 && pI830->vbeInfo->Capabilities[0] & 0x01)
+ if (pScrn->bitsPerPixel >= 8 && pI830->vbeInfo->Capabilities[0] & 0x01) {
+ if (pI830->Clone) {
+ SetBIOSPipe(pScrn, !pI830->pipe);
+ VBESetGetDACPaletteFormat(pVbe, 8);
+ }
+ SetPipeAccess(pScrn);
VBESetGetDACPaletteFormat(pVbe, 8);
+ }
/*
- * XXX This location of this isn't correct.
- *
- * Turn on the configured displays. This has the effect of resetting
- * the default refresh rates to values that the configured displays
- * can handle. This seems to be the safest way to make sure that this
- * happens. When it's safe to set higher values, we do that after this.
- *
- * Note: When a DFP is connected to an 830, this causes the mode setting
- * to be trashed. So, we don't do it on the 830.
- *
- * XXX Need to test an 830 with a LFP.
+ * When it's OK to set better than default refresh rates, set them here.
*/
- if (pI830->enableDisplays) {
- if (!SetDisplayDevices(pScrn, pI830->configuredDevices)) {
+ if (pI830->Clone) {
+ int Mon;
+ if (!pI830->pipe)
+ Mon = pI830->MonType2;
+ else
+ Mon = pI830->MonType1;
+ SetBIOSPipe(pScrn, !pI830->pipe);
+ if (pI830->CloneRefresh && (Mon == PIPE_CRT)) {
+ if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh &&
+ (mode & (1 << 11)) && data && data->data && data->block) {
+ refresh = SetRefreshRate(pScrn, mode, pI830->CloneRefresh);
+ if (!refresh)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to set refresh rate to %dHz on Clone head.\n",
+ pI830->CloneRefresh);
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Set refresh rate to %dHz on Clone head.\n",
+ pI830->CloneRefresh);
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Will use VBE3 method to set refresh on Clone head.\n");
+ } else {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Failed to switch to configured display devices\n");
+ "Not attempting to override default refresh on non-CRT clone head\n");
}
}
- /*
- * When it's OK to set better than default refresh rates, set them here.
- */
if (pI830->useExtendedRefresh && !pI830->vesa->useDefaultRefresh &&
(mode & (1 << 11)) && data && data->data && data->block) {
+ SetPipeAccess(pScrn);
refresh = SetRefreshRate(pScrn, mode, data->block->RefreshRate / 100);
if (!refresh) {
refresh = 60;
@@ -2484,7 +3337,6 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
}
}
-
/* XXX Fix plane A with pipe A, and plane B with pipe B. */
planeA = INREG(DSPACNTR);
planeB = INREG(DSPBCNTR);
@@ -2492,10 +3344,20 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
pI830->planeEnabled[0] = ((planeA & DISPLAY_PLANE_ENABLE) != 0);
pI830->planeEnabled[1] = ((planeB & DISPLAY_PLANE_ENABLE) != 0);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane A is %s.\n",
- pI830->planeEnabled[0] ? "enabled" : "disabled");
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane B is %s.\n",
- pI830->planeEnabled[1] ? "enabled" : "disabled");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane A is %s and connected to %s.\n",
+ pI830->planeEnabled[0] ? "enabled" : "disabled",
+ planeA & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A");
+ if (pI830->availablePipes == 2)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane B is %s and connected to %s.\n",
+ pI830->planeEnabled[1] ? "enabled" : "disabled",
+ planeB & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A");
+
+ if (xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone) {
+ pI830->planeEnabled[0] = 1;
+ pI830->pipeEnabled[0] = 1;
+ pI830->planeEnabled[1] = 1;
+ pI830->pipeEnabled[1] = 1;
+ }
/*
* Sometimes it seems that no display planes are enabled at this point.
@@ -2503,7 +3365,7 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
* For others choose plane A.
*/
if (!pI830->planeEnabled[0] && !pI830->planeEnabled[1]) {
- if (IS_MOBILE(pI830)) {
+ if (pI830->availablePipes == 2) {
if ((pI830->pipeEnabled[0] &&
((planeA & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE_A)) ||
(pI830->pipeEnabled[1] &&
@@ -2519,23 +3381,37 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
} else {
pI830->planeEnabled[0] = TRUE;
}
- if (pI830->planeEnabled[0]) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane A.\n");
- planeA |= DISPLAY_PLANE_ENABLE;
- OUTREG(DSPACNTR, planeA);
- /* flush the change. */
- temp = INREG(DSPABASE);
- OUTREG(DSPABASE, temp);
- }
- if (pI830->planeEnabled[1]) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane B.\n");
- planeB |= DISPLAY_PLANE_ENABLE;
- OUTREG(DSPBCNTR, planeB);
- /* flush the change. */
- temp = INREG(DSPBADDR);
- OUTREG(DSPBADDR, temp);
- }
}
+ if (pI830->planeEnabled[0]) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane A.\n");
+ planeA |= DISPLAY_PLANE_ENABLE;
+ planeA &= ~DISPPLANE_SEL_PIPE_MASK;
+ planeA |= DISPPLANE_SEL_PIPE_A;
+ OUTREG(DSPACNTR, planeA);
+ /* flush the change. */
+ temp = INREG(DSPABASE);
+ OUTREG(DSPABASE, temp);
+ }
+ if (pI830->planeEnabled[1]) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane B.\n");
+ planeB |= DISPLAY_PLANE_ENABLE;
+ planeB &= ~DISPPLANE_SEL_PIPE_MASK;
+ planeB |= DISPPLANE_SEL_PIPE_B;
+ OUTREG(DSPBCNTR, planeB);
+ /* flush the change. */
+ temp = INREG(DSPBADDR);
+ OUTREG(DSPBADDR, temp);
+ }
+
+ planeA = INREG(DSPACNTR);
+ planeB = INREG(DSPBCNTR);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane A is now %s and connected to %s.\n",
+ pI830->planeEnabled[0] ? "enabled" : "disabled",
+ planeA & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A");
+ if (pI830->availablePipes == 2)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane B is now %s and connected to %s.\n",
+ pI830->planeEnabled[1] ? "enabled" : "disabled",
+ planeB & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A");
/* XXX Plane C is ignored for now (overlay). */
@@ -2543,13 +3419,109 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
* Print out the PIPEACONF and PIPEBCONF registers.
*/
temp = INREG(PIPEACONF);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEACONF is 0x%08x\n", temp);
- if (IS_MOBILE(pI830)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEACONF is 0x%08lx\n", temp);
+ if (pI830->availablePipes == 2) {
temp = INREG(PIPEBCONF);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08x\n", temp);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08lx\n", temp);
+ }
+
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ /* Clean this up !! */
+ if (IsPrimary(pScrn)) {
+ CARD32 stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
+ CARD32 basereg = !pI830->pipe ? DSPABASE : DSPBBASE;
+ CARD32 sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE;
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+
+ temp = INREG(stridereg);
+ if (temp / pI8301->cpp != pI830->entityPrivate->pScrn_1->displayWidth) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe),
+ (int)(temp / pI8301->cpp), pI830->entityPrivate->pScrn_1->displayWidth);
+ OUTREG(stridereg, pI830->entityPrivate->pScrn_1->displayWidth * pI8301->cpp);
+ }
+ OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
+ /* Trigger update */
+ temp = INREG(basereg);
+ OUTREG(basereg, temp);
+
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) {
+ I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
+ stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
+ basereg = pI830->pipe ? DSPABASE : DSPBBASE;
+ sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE;
+
+ temp = INREG(stridereg);
+ if (temp / pI8302->cpp != pI830->entityPrivate->pScrn_2->displayWidth) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe),
+ (int)(temp / pI8302->cpp), pI830->entityPrivate->pScrn_2->displayWidth);
+ OUTREG(stridereg, pI830->entityPrivate->pScrn_2->displayWidth * pI8302->cpp);
+ }
+ OUTREG(sizereg, (pI830->entityPrivate->pScrn_2->currentMode->HDisplay - 1) | ((pI830->entityPrivate->pScrn_2->currentMode->VDisplay - 1) << 16));
+ /* Trigger update */
+ temp = INREG(basereg);
+ OUTREG(basereg, temp);
+ }
+ } else {
+ CARD32 stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
+ CARD32 basereg = pI830->pipe ? DSPABASE : DSPBBASE;
+ CARD32 sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE;
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2);
+
+ temp = INREG(stridereg);
+ if (temp / pI8301->cpp != pI830->entityPrivate->pScrn_1->displayWidth) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe),
+ (int)(temp / pI8301->cpp), pI830->entityPrivate->pScrn_1->displayWidth);
+ OUTREG(stridereg, pI830->entityPrivate->pScrn_1->displayWidth * pI8301->cpp);
+ }
+ OUTREG(sizereg, (pI830->entityPrivate->pScrn_1->currentMode->HDisplay - 1) | ((pI830->entityPrivate->pScrn_1->currentMode->VDisplay - 1) << 16));
+ /* Trigger update */
+ temp = INREG(basereg);
+ OUTREG(basereg, temp);
+
+ stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE;
+ basereg = !pI830->pipe ? DSPABASE : DSPBBASE;
+ sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE;
+
+ temp = INREG(stridereg);
+ if (temp / pI8302->cpp != pI830->entityPrivate->pScrn_2->displayWidth) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe),
+ (int)(temp / pI8302->cpp), pI830->entityPrivate->pScrn_2->displayWidth);
+ OUTREG(stridereg, pI830->entityPrivate->pScrn_2->displayWidth * pI8302->cpp);
+ }
+ OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
+ /* Trigger update */
+ temp = INREG(basereg);
+ OUTREG(basereg, temp);
+ }
+ } else {
+ for (i = 0; i < pI830->availablePipes; i++) {
+ CARD32 stridereg = i ? DSPBSTRIDE : DSPASTRIDE;
+ CARD32 basereg = i ? DSPBBASE : DSPABASE;
+ CARD32 sizereg = i ? DSPBSIZE : DSPASIZE;
+
+ if (!pI830->planeEnabled[i])
+ continue;
+
+ temp = INREG(stridereg);
+ if (temp / pI830->cpp != pScrn->displayWidth) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(i),
+ (int)(temp / pI830->cpp), pScrn->displayWidth);
+ OUTREG(stridereg, pScrn->displayWidth * pI830->cpp);
+ }
+ OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16));
+ /* Trigger update */
+ temp = INREG(basereg);
+ OUTREG(basereg, temp);
+ }
}
-#if PRINT_MODE_INFO
+#if 0
/* Print out some CRTC/display information. */
temp = INREG(HTOTAL_A);
ErrorF("Horiz active: %d, Horiz total: %d\n", temp & 0x7ff,
@@ -2578,26 +3550,44 @@ I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
ErrorF("Plane A start offset is %d\n", temp);
temp = INREG(DSPASTRIDE);
ErrorF("Plane A stride is %d bytes (%d pixels)\n", temp, temp / pI830->cpp);
-#endif
-
- for (i = 0; i < MAX_DISPLAY_PIPES; i++) {
- CARD32 stridereg = i ? DSPBSTRIDE : DSPASTRIDE;
- CARD32 basereg = i ? DSPBBASE : DSPABASE;
-
- if (!pI830->planeEnabled[i])
- continue;
+ temp = INREG(DSPAPOS);
+ ErrorF("Plane A position %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16);
+ temp = INREG(DSPASIZE);
+ ErrorF("Plane A size %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16);
- temp = INREG(stridereg);
- if (temp / pI830->cpp != pScrn->displayWidth) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(i),
- temp / pI830->cpp, pScrn->displayWidth);
- OUTREG(stridereg, pScrn->displayWidth * pI830->cpp);
- /* Trigger update */
- temp = INREG(basereg);
- OUTREG(basereg, temp);
- }
- }
+ /* Print out some CRTC/display information. */
+ temp = INREG(HTOTAL_B);
+ ErrorF("Horiz active: %d, Horiz total: %d\n", temp & 0x7ff,
+ (temp >> 16) & 0xfff);
+ temp = INREG(HBLANK_B);
+ ErrorF("Horiz blank start: %d, Horiz blank end: %d\n", temp & 0xfff,
+ (temp >> 16) & 0xfff);
+ temp = INREG(HSYNC_B);
+ ErrorF("Horiz sync start: %d, Horiz sync end: %d\n", temp & 0xfff,
+ (temp >> 16) & 0xfff);
+ temp = INREG(VTOTAL_B);
+ ErrorF("Vert active: %d, Vert total: %d\n", temp & 0x7ff,
+ (temp >> 16) & 0xfff);
+ temp = INREG(VBLANK_B);
+ ErrorF("Vert blank start: %d, Vert blank end: %d\n", temp & 0xfff,
+ (temp >> 16) & 0xfff);
+ temp = INREG(VSYNC_B);
+ ErrorF("Vert sync start: %d, Vert sync end: %d\n", temp & 0xfff,
+ (temp >> 16) & 0xfff);
+ temp = INREG(PIPEBSRC);
+ ErrorF("Image size: %dx%d (%dx%d)\n",
+ (temp >> 16) & 0x7ff, temp & 0x7ff,
+ (((temp >> 16) & 0x7ff) + 1), ((temp & 0x7ff) + 1));
+ ErrorF("Pixel multiply is %d\n", (planeA >> 20) & 0x3);
+ temp = INREG(DSPBBASE);
+ ErrorF("Plane B start offset is %d\n", temp);
+ temp = INREG(DSPBSTRIDE);
+ ErrorF("Plane B stride is %d bytes (%d pixels)\n", temp, temp / pI830->cpp);
+ temp = INREG(DSPBPOS);
+ ErrorF("Plane B position %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16);
+ temp = INREG(DSPBSIZE);
+ ErrorF("Plane B size %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16);
+#endif
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode bandwidth is %d Mpixel/s\n",
pMode->HDisplay * pMode->VDisplay * refresh / 1000000);
@@ -2646,6 +3636,8 @@ InitRegisterRec(ScrnInfoPtr pScrn)
I830RegPtr i830Reg = &pI830->ModeReg;
int i;
+ if (!IsPrimary(pScrn)) return;
+
for (i = 0; i < 8; i++)
i830Reg->Fence[i] = 0;
}
@@ -2874,6 +3866,8 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
vgaHWPtr hwp;
I830Ptr pI830;
VisualPtr visual;
+ I830EntPtr pI830Ent = NULL;
+ I830Ptr pI8301 = NULL;
#ifdef XF86DRI
Bool driDisabled;
#endif
@@ -2882,14 +3876,63 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830 = I830PTR(pScrn);
hwp = VGAHWPTR(pScrn);
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ pI830Ent = pI830->entityPrivate;
+ pI8301 = I830PTR(pI830Ent->pScrn_1);
+
+ /* PreInit failed on the second head, so make sure we turn it off */
+ if (IsPrimary(pScrn) && !pI830->entityPrivate->pScrn_2) {
+ if (pI830->pipe == 0) {
+ pI830->operatingDevices &= 0xFF;
+ } else {
+ pI830->operatingDevices &= 0xFF00;
+ }
+ }
+ }
+
pI830->starting = TRUE;
+ /* Alloc our pointers for the primary head */
+ if (IsPrimary(pScrn)) {
+ if (!pI830->LpRing)
+ pI830->LpRing = xalloc(sizeof(I830RingBuffer));
+ if (!pI830->CursorMem)
+ pI830->CursorMem = xalloc(sizeof(I830MemRange));
+ if (!pI830->CursorMemARGB)
+ pI830->CursorMemARGB = xalloc(sizeof(I830MemRange));
+ if (!pI830->OverlayMem)
+ pI830->OverlayMem = xalloc(sizeof(I830MemRange));
+ if (!pI830->overlayOn)
+ pI830->overlayOn = xalloc(sizeof(Bool));
+ if (!pI830->LpRing || !pI830->CursorMem || !pI830->CursorMemARGB ||
+ !pI830->OverlayMem || !pI830->overlayOn) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not allocate primary data structures.\n");
+ return FALSE;
+ }
+ *pI830->overlayOn = FALSE;
+ if (pI830->entityPrivate)
+ pI830->entityPrivate->XvInUse = -1;
+ }
+
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ /* Make our second head point to the first heads structures */
+ if (!IsPrimary(pScrn)) {
+ pI830->LpRing = pI8301->LpRing;
+ pI830->CursorMem = pI8301->CursorMem;
+ pI830->CursorMemARGB = pI8301->CursorMemARGB;
+ pI830->OverlayMem = pI8301->OverlayMem;
+ pI830->overlayOn = pI8301->overlayOn;
+ }
+ }
+
/*
* If we're changing the BIOS's view of the video memory size, do that
* first, then re-initialise the VBE information.
*/
pI830->pVbe = VBEInit(NULL, pI830->pEnt->index);
- SetBIOSMemSize(pScrn, pI830->newBIOSMemSize);
+ if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize))
+ SetBIOSMemSize(pScrn, pI830->newBIOSMemSize);
if (!pI830->pVbe)
return FALSE;
pI830->vbeInfo = VBEGetVBEInfo(pI830->pVbe);
@@ -2913,6 +3956,12 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#ifdef I830_XV
pI830->XvEnabled = !pI830->XvDisabled;
if (pI830->XvEnabled) {
+ if (!IsPrimary(pScrn)) {
+ if (!pI8301->XvEnabled || pI830->noAccel) {
+ pI830->XvEnabled = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Xv is disabled.\n");
+ }
+ } else
if (pI830->noAccel || pI830->StolenOnly) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Xv is disabled because it "
"needs 2D accel and AGPGART.\n");
@@ -2923,12 +3972,15 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pI830->XvEnabled = FALSE;
#endif
- I830ResetAllocations(pScrn, 0);
+ if (IsPrimary(pScrn)) {
+ I830ResetAllocations(pScrn, 0);
- I830Allocate2DMemory(pScrn, ALLOC_INITIAL);
+ if (!I830Allocate2DMemory(pScrn, ALLOC_INITIAL))
+ return FALSE;
+ }
if (!pI830->noAccel) {
- if (pI830->LpRing.mem.Size == 0) {
+ if (pI830->LpRing->mem.Size == 0) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Disabling acceleration because the ring buffer "
"allocation failed.\n");
@@ -2937,7 +3989,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
}
if (!pI830->SWCursor) {
- if (pI830->CursorMem.Size == 0) {
+ if (pI830->CursorMem->Size == 0) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Disabling HW cursor because the cursor memory "
"allocation failed.\n");
@@ -2952,7 +4004,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
"needs 2D acceleration.\n");
pI830->XvEnabled = FALSE;
}
- if (pI830->OverlayMem.Physical == 0) {
+ if (pI830->OverlayMem->Physical == 0) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Disabling Xv because the overlay register buffer "
"allocation failed.\n");
@@ -2988,9 +4040,13 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (pI830->directRenderingEnabled)
pI830->directRenderingEnabled = I830DRIScreenInit(pScreen);
- if (pI830->directRenderingEnabled)
- if (!(pI830->directRenderingEnabled = I830Allocate3DMemory(pScrn, 0)))
+ if (pI830->directRenderingEnabled) {
+ pI830->directRenderingEnabled =
+ I830Allocate3DMemory(pScrn,
+ pI830->disableTiling ? ALLOC_NO_TILING : 0);
+ if (!pI830->directRenderingEnabled)
I830DRICloseScreen(pScreen);
+ }
#else
pI830->directRenderingEnabled = FALSE;
@@ -3000,15 +4056,17 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
* After the 3D allocations have been done, see if there's any free space
* that can be added to the framebuffer allocation.
*/
- I830Allocate2DMemory(pScrn, 0);
+ if (IsPrimary(pScrn)) {
+ I830Allocate2DMemory(pScrn, 0);
- DPRINTF(PFX, "assert(if(!I830DoPoolAllocation(pScrn, pI830->StolenPool)))\n");
- if (!I830DoPoolAllocation(pScrn, &(pI830->StolenPool)))
- return FALSE;
+ DPRINTF(PFX, "assert(if(!I830DoPoolAllocation(pScrn, pI830->StolenPool)))\n");
+ if (!I830DoPoolAllocation(pScrn, &(pI830->StolenPool)))
+ return FALSE;
- DPRINTF(PFX, "assert( if(!I830FixupOffsets(pScrn)) )\n");
- if (!I830FixupOffsets(pScrn))
- return FALSE;
+ DPRINTF(PFX, "assert( if(!I830FixupOffsets(pScrn)) )\n");
+ if (!I830FixupOffsets(pScrn))
+ return FALSE;
+ }
#ifdef XF86DRI
if (pI830->directRenderingEnabled) {
@@ -3022,7 +4080,13 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
return FALSE;
pScrn->memPhysBase = (unsigned long)pI830->FbBase;
- pScrn->fbOffset = pI830->FrontBuffer.Start;
+
+ if (IsPrimary(pScrn)) {
+ pScrn->fbOffset = pI830->FrontBuffer.Start;
+ } else {
+ I830Ptr pI8301 = I830PTR(pI830Ent->pScrn_1);
+ pScrn->fbOffset = pI8301->FrontBuffer2.Start;
+ }
pI830->xoffset = (pScrn->fbOffset / pI830->cpp) % pScrn->displayWidth;
pI830->yoffset = (pScrn->fbOffset / pI830->cpp) / pScrn->displayWidth;
@@ -3037,6 +4101,7 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
memset(&pI830->SavedReg, 0, sizeof(pI830->SavedReg));
DPRINTF(PFX, "assert( if(!I830BIOSEnterVT(scrnIndex, 0)) )\n");
+
if (!I830BIOSEnterVT(scrnIndex, 0))
return FALSE;
@@ -3066,16 +4131,22 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86SetBlackWhitePixels(pScreen);
-#if 1
I830DGAInit(pScreen);
-#endif
DPRINTF(PFX,
"assert( if(!xf86InitFBManager(pScreen, &(pI830->FbMemBox))) )\n");
- if (!xf86InitFBManager(pScreen, &(pI830->FbMemBox))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ if (IsPrimary(pScrn)) {
+ if (!xf86InitFBManager(pScreen, &(pI830->FbMemBox))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to init memory manager\n");
- return FALSE;
+ return FALSE;
+ }
+ } else {
+ if (!xf86InitFBManager(pScreen, &(pI8301->FbMemBox2))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to init memory manager\n");
+ return FALSE;
+ }
}
if (!pI830->noAccel) {
@@ -3141,14 +4212,16 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pScreen->SaveScreen = I830BIOSSaveScreen;
pI830->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = I830BIOSCloseScreen;
+
+ if (pI830->checkLid)
+ pI830->lidTimer = TimerSet(NULL, 0, 1000, I830LidTimer, pScrn);
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
-#if 0
+
#ifdef I830DEBUG
I830_dump_registers(pScrn);
#endif
-#endif
pI830->starting = FALSE;
pI830->closing = FALSE;
@@ -3170,7 +4243,44 @@ I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags)
DPRINTF(PFX, "I830BIOSAdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
x, pI830->xoffset, y, pI830->yoffset);
- VBESetDisplayStart(pVbe, x + pI830->xoffset, y + pI830->yoffset, TRUE);
+ /* The i830M just happens to have some problems programming offsets via
+ * this VESA BIOS call. Especially in dual head configurations which
+ * have high resolutions which cause the DSP{A,B}BASE registers to be
+ * programmed incorrectly. Thus, it warrants bypassing the BIOS for i830M
+ * and hitting the DSP{A,B}BASE registers directly.
+ *
+ * We could probably do this for other platforms too, but we don't
+ * know what else the Video BIOS may do when calling it. It seems safe
+ * though for i830M during testing......
+ *
+ * Also note, calling the Video BIOS version first and then fixing the
+ * registers fail on i830M and eventually cause a lockup of the hardware
+ * in my testing.
+ */
+
+ if (pI830->Clone) {
+ if (!IS_I830(pI830)) {
+ SetBIOSPipe(pScrn, !pI830->pipe);
+ VBESetDisplayStart(pVbe, x + pI830->xoffset, y + pI830->yoffset, TRUE);
+ } else {
+ if (!pI830->pipe == 0) {
+ OUTREG(DSPABASE, pScrn->fbOffset + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ } else {
+ OUTREG(DSPBBASE, pScrn->fbOffset + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ }
+ }
+ }
+
+ if (!IS_I830(pI830)) {
+ SetPipeAccess(pScrn);
+ VBESetDisplayStart(pVbe, x + pI830->xoffset, y + pI830->yoffset, TRUE);
+ } else {
+ if (pI830->pipe == 0) {
+ OUTREG(DSPABASE, pScrn->fbOffset + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ } else {
+ OUTREG(DSPBBASE, pScrn->fbOffset + ((y * pScrn->displayWidth + x) * pI830->cpp));
+ }
+ }
}
static void
@@ -3217,6 +4327,13 @@ I830BIOSLeaveVT(int scrnIndex, int flags)
DPRINTF(PFX, "Leave VT\n");
+ if (!IsPrimary(pScrn)) {
+ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
+ if (!pI8301->GttBound) {
+ return;
+ }
+ }
+
#ifdef XF86DRI
if (pI830->directRenderingOpen) {
DPRINTF(PFX, "calling dri lock\n");
@@ -3230,10 +4347,22 @@ I830BIOSLeaveVT(int scrnIndex, int flags)
SaveHWOperatingState(pScrn);
#endif
+ if (IsPrimary(pScrn)) {
+ if (!SetDisplayDevices(pScrn, pI830->savedDevices)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to switch back to original display devices (0x%x)\n",
+ pI830->savedDevices);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Successfully set original devices\n");
+ }
+ }
+
ResetState(pScrn, TRUE);
RestoreHWState(pScrn);
RestoreBIOSMemSize(pScrn);
- I830UnbindGARTMemory(pScrn);
+ if (IsPrimary(pScrn))
+ I830UnbindGARTMemory(pScrn);
if (pI830->AccelInfoRec)
pI830->AccelInfoRec->NeedToSync = FALSE;
}
@@ -3246,22 +4375,34 @@ I830BIOSEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
- static int SaveGeneration = -1;
DPRINTF(PFX, "Enter VT\n");
- if (!I830BindGARTMemory(pScrn))
- return FALSE;
+ if (IsPrimary(pScrn)) {
+ if (!SetDisplayDevices(pScrn, pI830->operatingDevices)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to switch to configured display devices\n");
+ return FALSE;
+ }
+ }
+
+ /* Setup for checking lid status */
+ pI830->monitorSwitch = INREG(SWF0) & 0x0000FFFF;
+
+ if (IsPrimary(pScrn))
+ if (!I830BindGARTMemory(pScrn))
+ return FALSE;
CheckInheritedState(pScrn);
- SetBIOSMemSize(pScrn, pI830->newBIOSMemSize);
+ if (!TweakMemorySize(pScrn, pI830->newBIOSMemSize))
+ SetBIOSMemSize(pScrn, pI830->newBIOSMemSize);
/*
* Only save state once per server generation since that's what most
* drivers do. Could change this to save state at each VT enter.
*/
- if (SaveGeneration != serverGeneration) {
- SaveGeneration = serverGeneration;
+ if (pI830->SaveGeneration != serverGeneration) {
+ pI830->SaveGeneration = serverGeneration;
SaveHWState(pScrn);
}
ResetState(pScrn, FALSE);
@@ -3331,7 +4472,8 @@ I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
#define BINDUNBIND 0
#endif
#if BINDUNBIND
- I830UnbindGARTMemory(pScrn);
+ if (IsPrimary(pScrn))
+ I830UnbindGARTMemory(pScrn);
#endif
#ifdef I830_XV
/* Give the video overlay code a chance to see the new mode. */
@@ -3344,7 +4486,8 @@ I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
I830VideoSwitchModeAfter(pScrn, mode);
#endif
#if BINDUNBIND
- I830BindGARTMemory(pScrn);
+ if (IsPrimary(pScrn))
+ I830BindGARTMemory(pScrn);
#endif
return ret;
@@ -3361,7 +4504,7 @@ I830BIOSSaveScreen(ScreenPtr pScreen, int mode)
DPRINTF(PFX, "I830BIOSSaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on));
if (pScrn->vtSema) {
- for (i = 0; i < MAX_DISPLAY_PIPES; i++) {
+ for (i = 0; i < pI830->availablePipes; i++) {
if (i == 0) {
ctrl = DSPACNTR;
base = DSPABASE;
@@ -3401,6 +4544,34 @@ I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
I830Ptr pI830 = I830PTR(pScrn);
vbeInfoPtr pVbe = pI830->pVbe;
+ if (pI830->Clone) {
+ SetBIOSPipe(pScrn, !pI830->pipe);
+ if (xf86LoaderCheckSymbol("VBEDPMSSet")) {
+ VBEDPMSSet(pVbe, PowerManagementMode);
+ } else {
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f10;
+ pVbe->pInt10->bx = 0x01;
+
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ break;
+ case DPMSModeStandby:
+ pVbe->pInt10->bx |= 0x0100;
+ break;
+ case DPMSModeSuspend:
+ pVbe->pInt10->bx |= 0x0200;
+ break;
+ case DPMSModeOff:
+ pVbe->pInt10->bx |= 0x0400;
+ break;
+ }
+ xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);
+ }
+ }
+
+ SetPipeAccess(pScrn);
+
if (xf86LoaderCheckSymbol("VBEDPMSSet")) {
VBEDPMSSet(pVbe, PowerManagementMode);
} else {
@@ -3465,7 +4636,23 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen)
pI830->CursorInfoRec = 0;
}
- xf86GARTCloseScreen(scrnIndex);
+ if (IsPrimary(pScrn)) {
+ xf86GARTCloseScreen(scrnIndex);
+
+ xfree(pI830->LpRing);
+ pI830->LpRing = NULL;
+ xfree(pI830->CursorMem);
+ pI830->CursorMem = NULL;
+ xfree(pI830->CursorMemARGB);
+ pI830->CursorMemARGB = NULL;
+ xfree(pI830->OverlayMem);
+ pI830->OverlayMem = NULL;
+ xfree(pI830->overlayOn);
+ pI830->overlayOn = NULL;
+ }
+
+ if (pI830->lidTimer)
+ TimerCancel(pI830->lidTimer);
pScrn->vtSema = FALSE;
pI830->closing = FALSE;
@@ -3473,7 +4660,7 @@ I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen)
return (*pScreen->CloseScreen) (scrnIndex, pScreen);
}
-static int
+static ModeStatus
I830ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
if (mode->Flags & V_INTERLACE) {
@@ -3546,6 +4733,65 @@ I830PMEvent(int scrnIndex, pmEvent event, Bool undo)
return TRUE;
}
+static CARD32
+I830LidTimer(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ ScrnInfoPtr pScrn = (ScrnInfoPtr) arg;
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (pScrn->vtSema) {
+ /* Check for monitor lid being closed/opened and act accordingly */
+ int temp = INREG(SWF0) & 0x0000FFFF;
+
+ if (pI830->monitorSwitch != temp) {
+ int conf = pI830->operatingDevices;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Detected possible lid operation, fixing up.\n");
+ if ((temp & 0x0808) == 0x0000) {
+ /* LFP (PIPE A or B) GOING OFF - PROBABLE LID CLOSURE */
+ conf = pI830->operatingDevices & 0xF7F7;
+#if 0
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Lid is being closed.\n");
+#endif
+ } else {
+#if 0
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Lid is being opened.\n");
+#endif
+ }
+
+ /* If we've defined our own monitors, then get them and set them
+ * up when switching in single head mode, no effect in dual heads
+ * NOTE: This assumes that the LCD is always on Pipe B..... */
+ conf |= pI830->MonType1;
+ if (IsPrimary(pScrn)) {
+ if (!SetDisplayDevices(pScrn, conf))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to switch "
+ "to configured display devices during lid operation.\n");
+ }
+ pI830->monitorSwitch = conf;
+
+ /* Now, when we're single head, make sure we switch pipes */
+ if (!(xf86IsEntityShared(pScrn->entityList[0]) || pI830->Clone)) {
+ if ((temp & 0xFF00) == 0x0000)
+ pI830->pipe = 0;
+ if ((temp & 0x00FF) == 0x0000)
+ pI830->pipe = 1;
+ }
+ I830BIOSSwitchMode(pScrn->pScreen->myNum, pScrn->currentMode, 0);
+ I830BIOSAdjustFrame(pScrn->pScreen->myNum, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /* Everything should be o.k. now, so make sure the HW cursor is
+ * on the correct pipe */
+ if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
+ pI830->CursorInfoRec->ShowCursor(pScrn);
+ pI830->cursorOn = TRUE;
+ }
+ }
+ }
+
+ return 1000;
+}
+
void
I830InitpScrn(ScrnInfoPtr pScrn)
{
diff --git a/src/i830_memory.c b/src/i830_memory.c
index d3e52501..04e8deee 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_memory.c,v 1.7 2003/06/18 13:14:19 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_memory.c,v 1.9 2003/09/24 03:16:54 dawes Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -46,6 +46,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* Keith Whitwell <keith@tungstengraphics.com>
* David Dawes <dawes@xfree86.org>
*
+ * Updated for Dual Head capabilities:
+ * Alan Hourihane <alanh@tungstengraphics.com>
*/
#include "xf86.h"
@@ -255,8 +257,8 @@ AllocateRingBuffer(ScrnInfoPtr pScrn, int flags)
const char *s = dryrun ? "[dryrun] " : "";
/* Clear ring buffer info */
- memset(&(pI830->LpRing), 0, sizeof(pI830->LpRing));
- pI830->LpRing.mem.Key = -1;
+ memset(pI830->LpRing, 0, sizeof(I830RingBuffer));
+ pI830->LpRing->mem.Key = -1;
if (pI830->noAccel)
return TRUE;
@@ -268,7 +270,7 @@ AllocateRingBuffer(ScrnInfoPtr pScrn, int flags)
else
flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP;
- alloced = I830AllocVidMem(pScrn, &(pI830->LpRing.mem),
+ alloced = I830AllocVidMem(pScrn, &(pI830->LpRing->mem),
&(pI830->StolenPool), size,
GTT_PAGE_SIZE, flags);
if (alloced < size) {
@@ -279,9 +281,9 @@ AllocateRingBuffer(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %d kB for the ring buffer at 0x%x\n", s,
- alloced / 1024, pI830->LpRing.mem.Start);
- pI830->LpRing.tail_mask = pI830->LpRing.mem.Size - 1;
+ "%sAllocated %ld kB for the ring buffer at 0x%lx\n", s,
+ alloced / 1024, pI830->LpRing->mem.Start);
+ pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1;
return TRUE;
}
@@ -299,8 +301,8 @@ AllocateOverlay(ScrnInfoPtr pScrn, int flags)
const char *s = dryrun ? "[dryrun] " : "";
/* Clear overlay info */
- memset(&(pI830->OverlayMem), 0, sizeof(pI830->OverlayMem));
- pI830->OverlayMem.Key = -1;
+ memset(pI830->OverlayMem, 0, sizeof(I830MemRange));
+ pI830->OverlayMem->Key = -1;
if (!pI830->XvEnabled)
return TRUE;
@@ -317,7 +319,7 @@ AllocateOverlay(ScrnInfoPtr pScrn, int flags)
else
flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP | NEED_PHYSICAL_ADDR;
- alloced = I830AllocVidMem(pScrn, &(pI830->OverlayMem),
+ alloced = I830AllocVidMem(pScrn, pI830->OverlayMem,
&(pI830->StolenPool), size, GTT_PAGE_SIZE, flags);
/*
@@ -335,10 +337,10 @@ AllocateOverlay(ScrnInfoPtr pScrn, int flags)
/* This failure isn't fatal. */
} else {
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %d kB for Overlay registers at 0x%x "
- "(0x%08x).\n", s,
- alloced / 1024, pI830->OverlayMem.Start,
- pI830->OverlayMem.Physical);
+ "%sAllocated %ld kB for Overlay registers at 0x%lx "
+ "(0x%08lx).\n", s,
+ alloced / 1024, pI830->OverlayMem->Start,
+ pI830->OverlayMem->Physical);
}
return TRUE;
}
@@ -433,6 +435,97 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
if (pI830->NeedRingBufferLow)
AllocateRingBuffer(pScrn, flags | FORCE_LOW);
+ /* Unfortunately this doesn't run on the DRY_RUN pass because our
+ * second head hasn't been created yet..... */
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) {
+ I830EntPtr pI830Ent = pI830->entityPrivate;
+ I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2);
+
+ /* Clear everything first. */
+ memset(&(pI830->FbMemBox2), 0, sizeof(pI830->FbMemBox2));
+ memset(&(pI830->FrontBuffer2), 0, sizeof(pI830->FrontBuffer2));
+ pI830->FrontBuffer2.Key = -1;
+
+ pI830->FbMemBox2.x1 = 0;
+ pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth;
+ pI830->FbMemBox2.y1 = 0;
+ pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY;
+
+ /*
+ * Calculate how much framebuffer memory to allocate. For the
+ * initial allocation, calculate a reasonable minimum. This is
+ * enough for the virtual screen size, plus some pixmap cache
+ * space.
+ */
+
+ lineSize = pI830Ent->pScrn_2->displayWidth * pI8302->cpp;
+ minspace = lineSize * pI830Ent->pScrn_2->virtualY;
+ avail = pI830Ent->pScrn_2->videoRam * 1024;
+ maxCacheLines = (avail - minspace) / lineSize;
+ /* This shouldn't happen. */
+ if (maxCacheLines < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal Error: "
+ "maxCacheLines < 0 in I830Allocate2DMemory()\n");
+ maxCacheLines = 0;
+ }
+ if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pI830Ent->pScrn_2->virtualY))
+ maxCacheLines = MAX_DISPLAY_HEIGHT - pI830Ent->pScrn_2->virtualY;
+
+ if (pI8302->CacheLines >= 0) {
+ cacheLines = pI8302->CacheLines;
+ } else {
+#if 1
+ /* Make sure there is enough for two DVD sized YUV buffers */
+ cacheLines = (pI830Ent->pScrn_2->depth == 24) ? 256 : 384;
+ if (pI830Ent->pScrn_2->displayWidth <= 1024)
+ cacheLines *= 2;
+#else
+ /*
+ * Make sure there is enough for two DVD sized YUV buffers.
+ * Make that 1.5MB, which is around what was allocated with
+ * the old algorithm
+ */
+ cacheLines = (MB(1) + KB(512)) / pI8302->cpp / pI830Ent->pScrn_2->displayWidth;
+#endif
+ }
+ if (cacheLines > maxCacheLines)
+ cacheLines = maxCacheLines;
+
+ pI830->FbMemBox2.y2 += cacheLines;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sAllocating at least %d scanlines for pixmap cache\n",
+ s, cacheLines);
+
+ tileable = !(flags & ALLOC_NO_TILING) && pI8302->allowPageFlip &&
+ IsTileable(pI830Ent->pScrn_2->displayWidth * pI8302->cpp);
+ if (tileable) {
+ align = KB(512);
+ alignflags = ALIGN_BOTH_ENDS;
+ } else {
+ align = KB(64);
+ alignflags = 0;
+ }
+
+ size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines);
+ size = ROUND_TO_PAGE(size);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sSecondary framebuffer allocation size: %ld kByte\n", s,
+ size / 1024);
+ alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer2),
+ &(pI830->StolenPool), size, align,
+ flags | alignflags |
+ FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
+ if (alloced < size) {
+ if (!dryrun) {
+ xf86DrvMsg(pI830Ent->pScrn_2->scrnIndex, X_ERROR,
+ "Failed to allocate secondary framebuffer.\n");
+ }
+ return FALSE;
+ }
+ }
+
/* Clear everything first. */
memset(&(pI830->FbMemBox), 0, sizeof(pI830->FbMemBox));
memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer));
@@ -503,7 +596,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
size = lineSize * (pScrn->virtualY + cacheLines);
size = ROUND_TO_PAGE(size);
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sInitial framebuffer allocation size: %d kByte\n", s,
+ "%sInitial framebuffer allocation size: %ld kByte\n", s,
size / 1024);
alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer),
&(pI830->StolenPool), size, align,
@@ -511,8 +604,8 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
if (alloced < size) {
if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate framebuffer.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
+ "framebuffer. Is your VideoRAM set too low ??\n");
}
return FALSE;
}
@@ -547,7 +640,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Internal error in I830Allocate2DMemory():\n\t"
"Framebuffer isn't the last allocation at the bottom"
- " of StolenPool\n\t(%x != %x).\n",
+ " of StolenPool\n\t(%lx != %lx).\n",
pI830->FrontBuffer.End,
pI830->StolenPool.Free.Start);
return FALSE;
@@ -564,10 +657,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
pI830->StolenPool.Free.Size += pI830->FrontBuffer.Size;
pI830->StolenPool.Free.Start -= pI830->FrontBuffer.Size;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sUpdated framebuffer allocation size from %d "
- "to %d kByte\n", s, oldsize / 1024, maxFb / 1024);
+ "%sUpdated framebuffer allocation size from %ld "
+ "to %ld kByte\n", s, oldsize / 1024, maxFb / 1024);
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sUpdated pixmap cache from %d scanlines to %d "
+ "%sUpdated pixmap cache from %ld scanlines to %ld "
"scanlines\n", s,
oldsize / lineSize - pScrn->virtualY,
maxFb / lineSize - pScrn->virtualY);
@@ -610,8 +703,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
#endif
/* Clear cursor info */
- memset(&(pI830->CursorMem), 0, sizeof(pI830->CursorMem));
- pI830->CursorMem.Key = -1;
+ memset(pI830->CursorMem, 0, sizeof(I830MemRange));
+ pI830->CursorMem->Key = -1;
+ memset(pI830->CursorMemARGB, 0, sizeof(I830MemRange));
+ pI830->CursorMemARGB->Key = -1;
if (!pI830->SWCursor) {
int cursFlags = 0;
@@ -626,7 +721,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
if (pI830->CursorNeedsPhysical)
cursFlags |= NEED_PHYSICAL_ADDR;
- alloced = I830AllocVidMem(pScrn, &(pI830->CursorMem),
+ alloced = I830AllocVidMem(pScrn, pI830->CursorMem,
&(pI830->StolenPool), size,
GTT_PAGE_SIZE, flags | cursFlags);
if (alloced < size) {
@@ -636,10 +731,32 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
}
} else {
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %d kB for HW cursor at 0x%x", s,
- alloced / 1024, pI830->CursorMem.Start);
+ "%sAllocated %ld kB for HW cursor at 0x%lx", s,
+ alloced / 1024, pI830->CursorMem->Start);
if (pI830->CursorNeedsPhysical)
- xf86ErrorFVerb(verbosity, " (0x%08x)", pI830->CursorMem.Physical);
+ xf86ErrorFVerb(verbosity, " (0x%08lx)", pI830->CursorMem->Physical);
+ xf86ErrorFVerb(verbosity, "\n");
+ }
+
+ size = HWCURSOR_SIZE_ARGB;
+ cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP;
+ if (pI830->CursorNeedsPhysical)
+ cursFlags |= NEED_PHYSICAL_ADDR;
+
+ alloced = I830AllocVidMem(pScrn, pI830->CursorMemARGB,
+ &(pI830->StolenPool), size,
+ GTT_PAGE_SIZE, flags | cursFlags);
+ if (alloced < size) {
+ if (!dryrun) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate HW (ARGB) cursor space.\n");
+ }
+ } else {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sAllocated %ld kB for HW (ARGB) cursor at 0x%lx", s,
+ alloced / 1024, pI830->CursorMemARGB->Start);
+ if (pI830->CursorNeedsPhysical)
+ xf86ErrorFVerb(verbosity, " (0x%08lx)", pI830->CursorMemARGB->Physical);
xf86ErrorFVerb(verbosity, "\n");
}
}
@@ -652,8 +769,10 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
AllocateRingBuffer(pScrn, flags);
/* Clear scratch info */
- memset(&(pI830->Scratch), 0, sizeof(pI830->Scratch));
+ memset(&(pI830->Scratch), 0, sizeof(I830MemRange));
pI830->Scratch.Key = -1;
+ memset(&(pI830->Scratch2), 0, sizeof(I830MemRange));
+ pI830->Scratch2.Key = -1;
if (!pI830->noAccel) {
size = MAX_SCRATCH_BUFFER_SIZE;
@@ -675,8 +794,35 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
return FALSE;
}
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %d kB for the scratch buffer at 0x%x\n", s,
+ "%sAllocated %ld kB for the scratch buffer at 0x%lx\n", s,
alloced / 1024, pI830->Scratch.Start);
+
+ /* Let's allocate another scratch buffer for the second head */
+ /* Again, this code won't execute on the dry run pass */
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) {
+ size = MAX_SCRATCH_BUFFER_SIZE;
+ alloced = I830AllocVidMem(pScrn, &(pI830->Scratch2),
+ &(pI830->StolenPool),
+ size, GTT_PAGE_SIZE,
+ flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
+ if (alloced < size) {
+ size = MIN_SCRATCH_BUFFER_SIZE;
+ alloced = I830AllocVidMem(pScrn, &(pI830->Scratch2),
+ &(pI830->StolenPool), size,
+ GTT_PAGE_SIZE,
+ flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
+ }
+ if (alloced < size) {
+ if (!dryrun) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate second scratch buffer space\n");
+ }
+ return FALSE;
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sAllocated %ld kB for the second scratch buffer at 0x%lx\n", s,
+ alloced / 1024, pI830->Scratch2.Start);
+ }
}
return TRUE;
}
@@ -806,7 +952,7 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
return FALSE;
}
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %d kB for the back buffer at 0x%x.\n", s,
+ "%sAllocated %ld kB for the back buffer at 0x%lx.\n", s,
alloced / 1024, pI830->BackBuffer.Start);
/* Depth Buffer -- same size as the back buffer */
@@ -844,7 +990,7 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
return FALSE;
}
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %d kB for the depth buffer at 0x%x.\n", s,
+ "%sAllocated %ld kB for the depth buffer at 0x%lx.\n", s,
alloced / 1024, pI830->DepthBuffer.Start);
/* Space for logical context. 32k is fine for right now. */
@@ -865,36 +1011,6 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
"%sAllocated %d kB for the logical context at 0x%x.\n", s,
alloced / 1024, pI830->ContextMem.Start);
- /*
- * Space for DMA buffers, only if there's enough free for at least 1MB
- * of texture space.
- */
- memset(&(pI830->BufferMem), 0, sizeof(pI830->BufferMem));
- pI830->BufferMem.Key = -1;
- /* This should already be a page multiple */
- size = I830_DMA_BUF_NR * I830_DMA_BUF_SZ;
- if (dryrun || (GetFreeSpace(pScrn) >= size + MB(1))) {
- alloced = I830AllocVidMem(pScrn, &(pI830->BufferMem),
- &(pI830->StolenPool), size,
- GTT_PAGE_SIZE,
- flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate DMA buffer space.\n");
- }
- return FALSE;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %d kB for the DMA buffers at 0x%x.\n", s,
- alloced / 1024, pI830->BufferMem.Start);
- } else {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Not enough free space for DMA buffers.\n");
- }
- return FALSE;
- }
/* Allocate the remaining space for textures. */
memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem));
@@ -912,7 +1028,8 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
if (size < KB(512)) {
if (!dryrun) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Less than %d kBytes for texture space.\n", size / 1024);
+ "Less than 512 kBytes for texture space (real %ld kBytes).\n",
+ size / 1024);
}
return FALSE;
}
@@ -927,7 +1044,7 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
return FALSE;
}
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %d kB for textures at 0x%x\n", s,
+ "%sAllocated %ld kB for textures at 0x%lx\n", s,
alloced / 1024, pI830->TexMem.Start);
return TRUE;
@@ -1052,7 +1169,7 @@ FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem)
}
#endif
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "%p: Memory at offset 0x%08x, size %d kBytes\n", mem,
+ "%p: Memory at offset 0x%08lx, size %ld kBytes\n", (void *)mem,
mem->Start, mem->Size / 1024);
return TRUE;
}
@@ -1065,13 +1182,18 @@ I830FixupOffsets(ScrnInfoPtr pScrn)
DPRINTF(PFX, "I830FixupOffsets\n");
topOfMem = pI830->StolenPool.Total.End;
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
+ FixOffset(pScrn, &(pI830->FrontBuffer2));
FixOffset(pScrn, &(pI830->FrontBuffer));
- FixOffset(pScrn, &(pI830->CursorMem));
- FixOffset(pScrn, &(pI830->LpRing.mem));
+ FixOffset(pScrn, pI830->CursorMem);
+ FixOffset(pScrn, pI830->CursorMemARGB);
+ FixOffset(pScrn, &(pI830->LpRing->mem));
FixOffset(pScrn, &(pI830->Scratch));
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
+ FixOffset(pScrn, &(pI830->Scratch2));
#ifdef I830_XV
if (pI830->XvEnabled) {
- FixOffset(pScrn, &(pI830->OverlayMem));
+ FixOffset(pScrn, pI830->OverlayMem);
}
#endif
#ifdef XF86DRI
@@ -1079,7 +1201,6 @@ I830FixupOffsets(ScrnInfoPtr pScrn)
FixOffset(pScrn, &(pI830->BackBuffer));
FixOffset(pScrn, &(pI830->DepthBuffer));
FixOffset(pScrn, &(pI830->ContextMem));
- FixOffset(pScrn, &(pI830->BufferMem));
FixOffset(pScrn, &(pI830->TexMem));
}
#endif
@@ -1102,6 +1223,7 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch,
I830RegPtr i830Reg = &pI830->ModeReg;
CARD32 val;
CARD32 fence_mask = 0;
+ unsigned int fence_pitch;
DPRINTF(PFX, "SetFence: %d, 0x%08x, %d, %d kByte\n",
nr, start, pitch, size / 1024);
@@ -1114,12 +1236,15 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch,
i830Reg->Fence[nr] = 0;
- fence_mask = ~I830_FENCE_START_MASK;
+ if (IS_I915G(pI830))
+ fence_mask = ~I915G_FENCE_START_MASK;
+ else
+ fence_mask = ~I830_FENCE_START_MASK;
if (start & fence_mask) {
xf86DrvMsg(X_WARNING, pScrn->scrnIndex,
- "SetFence: %d: start (0x%08x) is not 512k aligned\n",
- nr, start);
+ "SetFence: %d: start (0x%08x) is not %s aligned\n",
+ nr, start, (IS_I915G(pI830)) ? "1MB" : "512k");
return;
}
@@ -1139,38 +1264,73 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch,
val = (start | FENCE_X_MAJOR | FENCE_VALID);
- switch (size) {
- case KB(512):
- val |= FENCE_SIZE_512K;
- break;
- case MB(1):
- val |= FENCE_SIZE_1M;
- break;
- case MB(2):
- val |= FENCE_SIZE_2M;
- break;
- case MB(4):
- val |= FENCE_SIZE_4M;
- break;
- case MB(8):
- val |= FENCE_SIZE_8M;
- break;
- case MB(16):
- val |= FENCE_SIZE_16M;
- break;
- case MB(32):
- val |= FENCE_SIZE_32M;
- break;
- case MB(64):
- val |= FENCE_SIZE_64M;
- break;
- default:
- xf86DrvMsg(X_WARNING, pScrn->scrnIndex,
+ if (IS_I915G(pI830)) {
+ switch (size) {
+ case MB(1):
+ val |= I915G_FENCE_SIZE_1M;
+ break;
+ case MB(2):
+ val |= I915G_FENCE_SIZE_2M;
+ break;
+ case MB(4):
+ val |= I915G_FENCE_SIZE_4M;
+ break;
+ case MB(8):
+ val |= I915G_FENCE_SIZE_8M;
+ break;
+ case MB(16):
+ val |= I915G_FENCE_SIZE_16M;
+ break;
+ case MB(32):
+ val |= I915G_FENCE_SIZE_32M;
+ break;
+ case MB(64):
+ val |= I915G_FENCE_SIZE_64M;
+ break;
+ default:
+ xf86DrvMsg(X_WARNING, pScrn->scrnIndex,
"SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
- return;
+ return;
+ }
+ } else {
+ switch (size) {
+ case KB(512):
+ val |= FENCE_SIZE_512K;
+ break;
+ case MB(1):
+ val |= FENCE_SIZE_1M;
+ break;
+ case MB(2):
+ val |= FENCE_SIZE_2M;
+ break;
+ case MB(4):
+ val |= FENCE_SIZE_4M;
+ break;
+ case MB(8):
+ val |= FENCE_SIZE_8M;
+ break;
+ case MB(16):
+ val |= FENCE_SIZE_16M;
+ break;
+ case MB(32):
+ val |= FENCE_SIZE_32M;
+ break;
+ case MB(64):
+ val |= FENCE_SIZE_64M;
+ break;
+ default:
+ xf86DrvMsg(X_WARNING, pScrn->scrnIndex,
+ "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024);
+ return;
+ }
}
- switch (pitch / 128) {
+ if (IS_I915G(pI830))
+ fence_pitch = pitch / 512;
+ else
+ fence_pitch = pitch / 128;
+
+ switch (fence_pitch) {
case 1:
val |= FENCE_PITCH_1;
break;
@@ -1337,16 +1497,24 @@ I830BindGARTMemory(ScrnInfoPtr pScrn)
if (!BindMemRange(pScrn, &(pI830->StolenPool.Allocated)))
return FALSE;
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
+ if (!BindMemRange(pScrn, &(pI830->FrontBuffer2)))
+ return FALSE;
if (!BindMemRange(pScrn, &(pI830->FrontBuffer)))
return FALSE;
- if (!BindMemRange(pScrn, &(pI830->CursorMem)))
+ if (!BindMemRange(pScrn, pI830->CursorMem))
+ return FALSE;
+ if (!BindMemRange(pScrn, pI830->CursorMemARGB))
return FALSE;
- if (!BindMemRange(pScrn, &(pI830->LpRing.mem)))
+ if (!BindMemRange(pScrn, &(pI830->LpRing->mem)))
return FALSE;
if (!BindMemRange(pScrn, &(pI830->Scratch)))
return FALSE;
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
+ if (!BindMemRange(pScrn, &(pI830->Scratch2)))
+ return FALSE;
#ifdef I830_XV
- if (!BindMemRange(pScrn, &(pI830->OverlayMem)))
+ if (!BindMemRange(pScrn, pI830->OverlayMem))
return FALSE;
#endif
#ifdef XF86DRI
@@ -1357,8 +1525,6 @@ I830BindGARTMemory(ScrnInfoPtr pScrn)
return FALSE;
if (!BindMemRange(pScrn, &(pI830->ContextMem)))
return FALSE;
- if (!BindMemRange(pScrn, &(pI830->BufferMem)))
- return FALSE;
if (!BindMemRange(pScrn, &(pI830->TexMem)))
return FALSE;
}
@@ -1403,16 +1569,24 @@ I830UnbindGARTMemory(ScrnInfoPtr pScrn)
if (!UnbindMemRange(pScrn, &(pI830->StolenPool.Allocated)))
return FALSE;
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
+ if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer2)))
+ return FALSE;
if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer)))
return FALSE;
- if (!UnbindMemRange(pScrn, &(pI830->CursorMem)))
+ if (!UnbindMemRange(pScrn, pI830->CursorMem))
+ return FALSE;
+ if (!UnbindMemRange(pScrn, pI830->CursorMemARGB))
return FALSE;
- if (!UnbindMemRange(pScrn, &(pI830->LpRing.mem)))
+ if (!UnbindMemRange(pScrn, &(pI830->LpRing->mem)))
return FALSE;
if (!UnbindMemRange(pScrn, &(pI830->Scratch)))
return FALSE;
+ if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
+ if (!UnbindMemRange(pScrn, &(pI830->Scratch2)))
+ return FALSE;
#ifdef I830_XV
- if (!UnbindMemRange(pScrn, &(pI830->OverlayMem)))
+ if (!UnbindMemRange(pScrn, pI830->OverlayMem))
return FALSE;
#endif
#ifdef XF86DRI
@@ -1423,8 +1597,6 @@ I830UnbindGARTMemory(ScrnInfoPtr pScrn)
return FALSE;
if (!UnbindMemRange(pScrn, &(pI830->ContextMem)))
return FALSE;
- if (!UnbindMemRange(pScrn, &(pI830->BufferMem)))
- return FALSE;
if (!UnbindMemRange(pScrn, &(pI830->TexMem)))
return FALSE;
}
diff --git a/src/i830_video.c b/src/i830_video.c
index 3d7b0349..31be8a64 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -24,7 +24,7 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c,v 1.8 2003/06/18 13:14:19 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_video.c,v 1.11tsi Exp $ */
/*
* Reformatted with GNU indent (2.2.8), using the following options:
@@ -111,6 +111,7 @@ static void I830BlockHandler(int, pointer, pointer, pointer);
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
static Atom xvBrightness, xvContrast, xvColorKey;
+static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;
#define IMAGE_MAX_WIDTH 1440
#define IMAGE_MAX_HEIGHT 1080
@@ -138,36 +139,36 @@ Edummy(const char *dummy, ...)
BEGIN_LP_RING(6); \
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE); \
OUT_RING(MI_NOOP); \
- if (!pI830->overlayOn) { \
+ if (!*pI830->overlayOn) { \
OUT_RING(MI_NOOP); \
OUT_RING(MI_NOOP); \
OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_ON); \
ErrorF("Overlay goes from off to on\n"); \
- pI830->overlayOn = TRUE; \
+ *pI830->overlayOn = TRUE; \
} else { \
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \
OUT_RING(MI_NOOP); \
OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); \
} \
- OUT_RING(pI830->OverlayMem.Physical | 1); \
+ OUT_RING(pI830->OverlayMem->Physical | 1); \
ADVANCE_LP_RING(); \
ErrorF("OVERLAY_UPDATE\n"); \
} while(0)
#define OVERLAY_OFF \
do { \
- if (pI830->overlayOn) { \
+ if (*pI830->overlayOn) { \
BEGIN_LP_RING(8); \
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE); \
OUT_RING(MI_NOOP); \
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \
OUT_RING(MI_NOOP); \
OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF); \
- OUT_RING(pI830->OverlayMem.Physical); \
+ OUT_RING(pI830->OverlayMem->Physical); \
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \
OUT_RING(MI_NOOP); \
ADVANCE_LP_RING(); \
- pI830->overlayOn = FALSE; \
+ *pI830->overlayOn = FALSE; \
ErrorF("Overlay goes from on to off\n"); \
ErrorF("OVERLAY_OFF\n"); \
} \
@@ -250,12 +251,18 @@ static XF86VideoFormatRec Formats[NUM_FORMATS] = {
{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
};
-#define NUM_ATTRIBUTES 3
+#define NUM_ATTRIBUTES 9
static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = {
{XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
{XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
- {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
+ {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
+ {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA0"},
+ {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA1"},
+ {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA2"},
+ {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA3"},
+ {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA4"},
+ {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA5"}
};
#define NUM_IMAGES 4
@@ -323,15 +330,6 @@ typedef struct {
} I830OverlayRegRec, *I830OverlayRegPtr;
typedef struct {
- CARD32 GAMC5;
- CARD32 GAMC4;
- CARD32 GAMC3;
- CARD32 GAMC2;
- CARD32 GAMC1;
- CARD32 GAMC0;
-} I830OverlayStateRec, *I830OverlayStatePtr;
-
-typedef struct {
CARD32 YBuf0offset;
CARD32 UBuf0offset;
CARD32 VBuf0offset;
@@ -348,20 +346,27 @@ typedef struct {
RegionRec clip;
CARD32 colorKey;
+ CARD32 gamma0;
+ CARD32 gamma1;
+ CARD32 gamma2;
+ CARD32 gamma3;
+ CARD32 gamma4;
+ CARD32 gamma5;
+
CARD32 videoStatus;
Time offTime;
Time freeTime;
FBLinearPtr linear;
- I830OverlayStateRec hwstate;
-
- Bool refreshOK;
- int maxRate;
+ Bool overlayOK;
+ int oneLineMode;
+ int scaleRatio;
} I830PortPrivRec, *I830PortPrivPtr;
#define GET_PORT_PRIVATE(pScrn) \
(I830PortPrivPtr)((I830PTR(pScrn))->adaptor->pPortPrivates[0].ptr)
+#if VIDEO_DEBUG
static void
CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size)
{
@@ -380,6 +385,7 @@ CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size)
if (!bad)
ErrorF("CompareOverlay: no differences\n");
}
+#endif
void
I830InitVideo(ScreenPtr pScreen)
@@ -442,11 +448,10 @@ I830ResetVideo(ScrnInfoPtr pScrn)
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
I830OverlayRegPtr overlay =
- (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem.Start);
- I830OverlayStatePtr hwstate = &(pPriv->hwstate);
+ (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
DPRINTF(PFX, "I830ResetVideo: base: %p, offset: 0x%08x, obase: %p\n",
- pI830->FbBase, pI830->OverlayMem.Start, overlay);
+ pI830->FbBase, pI830->OverlayMem->Start, overlay);
/*
* Default to maximum image size in YV12
*/
@@ -461,7 +466,7 @@ I830ResetVideo(ScrnInfoPtr pScrn)
overlay->SWIDTH = IMAGE_MAX_WIDTH | (IMAGE_MAX_WIDTH << 16);
overlay->SWIDTHSW = (IMAGE_MAX_WIDTH >> 3) | (IMAGE_MAX_WIDTH << 12);
overlay->SHEIGHT = IMAGE_MAX_HEIGHT | (IMAGE_MAX_HEIGHT << 15);
- overlay->OCLRC0 = 0x01000000; /* brightness: 0 contrast: 1.0 */
+ overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
overlay->OCLRC1 = 0x00000080; /* saturation: bypass */
overlay->AWINPOS = 0;
overlay->AWINSZ = 0;
@@ -495,25 +500,16 @@ I830ResetVideo(ScrnInfoPtr pScrn)
overlay->OCONFIG = CC_OUT_8BIT;
/*
- * Select which pipe the overlay is enabled on. Give preference to
- * pipe A.
+ * Select which pipe the overlay is enabled on.
*/
- if (pI830->pipeEnabled[0])
+ overlay->OCONFIG &= ~OVERLAY_PIPE_MASK;
+ if (pI830->pipe == 0)
overlay->OCONFIG |= OVERLAY_PIPE_A;
- else if (pI830->pipeEnabled[1])
+ else
overlay->OCONFIG |= OVERLAY_PIPE_B;
overlay->OCMD = YUV_420;
- /* setup hwstate */
- /* Default gamma correction values. */
- hwstate->GAMC5 = 0xc0c0c0;
- hwstate->GAMC4 = 0x808080;
- hwstate->GAMC3 = 0x404040;
- hwstate->GAMC2 = 0x202020;
- hwstate->GAMC1 = 0x101010;
- hwstate->GAMC0 = 0x080808;
-
#if 0
/*
* XXX DUMP REGISTER CODE !!!
@@ -526,34 +522,56 @@ I830ResetVideo(ScrnInfoPtr pScrn)
ErrorF("0x%x 0x%08x\n", i, INREG(i));
}
#endif
+}
- OUTREG(OGAMC5, hwstate->GAMC5);
- OUTREG(OGAMC4, hwstate->GAMC4);
- OUTREG(OGAMC3, hwstate->GAMC3);
- OUTREG(OGAMC2, hwstate->GAMC2);
- OUTREG(OGAMC1, hwstate->GAMC1);
- OUTREG(OGAMC0, hwstate->GAMC0);
+#define PFIT_CONTROLS 0x61230
+#define PFIT_AUTOVSCALE_MASK 0x200
+#define PFIT_ON_MASK 0x80000000
+#define PFIT_AUTOSCALE_RATIO 0x61238
+#define PFIT_PROGRAMMED_SCALE_RATIO 0x61234
+static void
+I830SetOneLineModeRatio(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+ CARD32 panelFitControl = INREG(PFIT_CONTROLS);
+ int vertScale;
+
+ pPriv->scaleRatio = 0x10000;
+
+ if (panelFitControl & PFIT_ON_MASK) {
+ if (panelFitControl & PFIT_AUTOVSCALE_MASK) {
+ vertScale = INREG(PFIT_AUTOSCALE_RATIO) >> 16;
+ } else {
+ vertScale = INREG(PFIT_PROGRAMMED_SCALE_RATIO) >> 16;
+ }
+
+ if (vertScale != 0)
+ pPriv->scaleRatio = ((double) 0x10000 / (double)vertScale) * 0x10000;
+
+ pPriv->oneLineMode = TRUE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling Xvideo one-line mode\n");
+ }
+
+ if (pPriv->scaleRatio == 0x10000)
+ pPriv->oneLineMode = FALSE;
}
-/*
- * Each chipset has a limit on the pixel rate that the video overlay can
- * be used for. Enabling the overlay above that limit can result in a
- * lockup. These two functions check the pixel rate for the new mode
- * and turn the overlay off before switching to the new mode if it exceeds
- * the limit, or turn it back on if the new mode is below the limit.
- */
+static void
+I830UpdateGamma(ScrnInfoPtr pScrn)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
-/*
- * Approximate pixel rate limits for the video overlay.
- * The rate is calculated based on the mode resolution and refresh rate.
- */
-#define I830_OVERLAY_RATE 79 /* 1024x768@85, 1280x1024@60 */
-#define I845_OVERLAY_RATE 120 /* 1280x1024@85, 1600x1200@60 */
-#define I852_OVERLAY_RATE 79 /* 1024x768@85, 1280x1024@60 */
-#define I855_OVERLAY_RATE 120 /* 1280x1024@85, 1600x1200@60 */
-#define I865_OVERLAY_RATE 170 /* 1600x1200@85, 1920x1440@60 */
-#define DEFAULT_OVERLAY_RATE 120
+ OUTREG(OGAMC5, pPriv->gamma5);
+ OUTREG(OGAMC4, pPriv->gamma4);
+ OUTREG(OGAMC3, pPriv->gamma3);
+ OUTREG(OGAMC2, pPriv->gamma2);
+ OUTREG(OGAMC1, pPriv->gamma1);
+ OUTREG(OGAMC0, pPriv->gamma0);
+}
static XF86VideoAdaptorPtr
I830SetupImageVideo(ScreenPtr pScreen)
@@ -571,7 +589,7 @@ I830SetupImageVideo(ScreenPtr pScreen)
adapt->type = XvWindowMask | XvInputMask | XvImageMask;
adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
- adapt->name = "Intel(R) 830M/845G/852GM/855GM/865G Video Overlay";
+ adapt->name = "Intel(R) 830M/845G/852GM/855GM/865G/915G Video Overlay";
adapt->nEncodings = 1;
adapt->pEncodings = DummyEncoding;
adapt->nFormats = NUM_FORMATS;
@@ -584,7 +602,10 @@ I830SetupImageVideo(ScreenPtr pScreen)
adapt->pPortPrivates[0].ptr = (pointer) (pPriv);
adapt->pAttributes = Attributes;
adapt->nImages = NUM_IMAGES;
- adapt->nAttributes = NUM_ATTRIBUTES;
+ if (IS_I915G(pI830))
+ adapt->nAttributes = 9; /* has gamma */
+ else
+ adapt->nAttributes = 3;
adapt->pImages = Images;
adapt->PutVideo = NULL;
adapt->PutStill = NULL;
@@ -603,39 +624,29 @@ I830SetupImageVideo(ScreenPtr pScreen)
pPriv->contrast = 64;
pPriv->linear = NULL;
pPriv->currentBuf = 0;
-
- switch (pI830->PciInfo->chipType) {
- case PCI_CHIP_I830_M:
- pPriv->maxRate = I830_OVERLAY_RATE;
- break;
- case PCI_CHIP_845_G:
- pPriv->maxRate = I845_OVERLAY_RATE;
- break;
- case PCI_CHIP_I855_GM:
- switch (pI830->variant) {
- case I852_GM:
- case I852_GME:
- pPriv->maxRate = I852_OVERLAY_RATE;
- break;
- default:
- pPriv->maxRate = I855_OVERLAY_RATE;
- break;
- }
- break;
- case PCI_CHIP_I865_G:
- pPriv->maxRate = I865_OVERLAY_RATE;
- break;
- default:
- pPriv->maxRate = DEFAULT_OVERLAY_RATE;
- break;
- }
+ pPriv->gamma5 = 0xc0c0c0;
+ pPriv->gamma4 = 0x808080;
+ pPriv->gamma3 = 0x404040;
+ pPriv->gamma2 = 0x202020;
+ pPriv->gamma1 = 0x101010;
+ pPriv->gamma0 = 0x080808;
/* gotta uninit this someplace */
REGION_INIT(pScreen, &pPriv->clip, NullBox, 0);
pI830->adaptor = adapt;
- /* Initialise pPriv->refreshOK */
+ /* With LFP's we need to detect whether we're in One Line Mode, which
+ * essentially means a resolution greater than 1024x768, and fix up
+ * the scaler accordingly. */
+ pPriv->scaleRatio = 0x10000;
+ pPriv->oneLineMode = FALSE;
+
+ /*
+ * Initialise pPriv->overlayOK. Set it to TRUE here so that a warning will
+ * be generated if I830VideoSwitchModeAfter() sets it to FALSE.
+ */
+ pPriv->overlayOK = TRUE;
I830VideoSwitchModeAfter(pScrn, pScrn->currentMode);
pI830->BlockHandler = pScreen->BlockHandler;
@@ -644,12 +655,50 @@ I830SetupImageVideo(ScreenPtr pScreen)
xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
xvContrast = MAKE_ATOM("XV_CONTRAST");
xvColorKey = MAKE_ATOM("XV_COLORKEY");
+ if (IS_I915G(pI830)) {
+ xvGamma0 = MAKE_ATOM("XV_GAMMA0");
+ xvGamma1 = MAKE_ATOM("XV_GAMMA1");
+ xvGamma2 = MAKE_ATOM("XV_GAMMA2");
+ xvGamma3 = MAKE_ATOM("XV_GAMMA3");
+ xvGamma4 = MAKE_ATOM("XV_GAMMA4");
+ xvGamma5 = MAKE_ATOM("XV_GAMMA5");
+ }
I830ResetVideo(pScrn);
+ I830UpdateGamma(pScrn);
+
return adapt;
}
+static Bool
+RegionsEqual(RegionPtr A, RegionPtr B)
+{
+ int *dataA, *dataB;
+ int num;
+
+ num = REGION_NUM_RECTS(A);
+ if (num != REGION_NUM_RECTS(B))
+ return FALSE;
+
+ if ((A->extents.x1 != B->extents.x1) ||
+ (A->extents.x2 != B->extents.x2) ||
+ (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2))
+ return FALSE;
+
+ dataA = (int *)REGION_RECTS(A);
+ dataB = (int *)REGION_RECTS(B);
+
+ while (num--) {
+ if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+ return FALSE;
+ dataA += 2;
+ dataB += 2;
+ }
+
+ return TRUE;
+}
+
static void
I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
{
@@ -657,7 +706,7 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
I830Ptr pI830 = I830PTR(pScrn);
I830OverlayRegPtr overlay =
- (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem.Start);
+ (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
DPRINTF(PFX, "I830StopVideo\n");
@@ -669,6 +718,9 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
OVERLAY_UPDATE;
OVERLAY_OFF;
+
+ if (pI830->entityPrivate)
+ pI830->entityPrivate->XvInUse = -1;
}
if (pPriv->linear) {
xf86FreeOffscreenLinear(pPriv->linear);
@@ -691,22 +743,66 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
I830Ptr pI830 = I830PTR(pScrn);
I830OverlayRegPtr overlay =
- (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem.Start);
+ (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
if (attribute == xvBrightness) {
if ((value < -128) || (value > 127))
return BadValue;
pPriv->brightness = value;
overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
- if (pPriv->refreshOK)
+ if (pPriv->overlayOK)
OVERLAY_UPDATE;
} else if (attribute == xvContrast) {
if ((value < 0) || (value > 255))
return BadValue;
pPriv->contrast = value;
overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
- if (pPriv->refreshOK)
+ if (pPriv->overlayOK)
OVERLAY_UPDATE;
+ } else if (attribute == xvGamma0 && (IS_I915G(pI830))) {
+ /* Avoid video anomalies, so set gamma registers when overlay is off */
+ /* We also clamp the values if they are outside the ranges */
+ if (!*pI830->overlayOn) {
+ pPriv->gamma0 = value;
+ if (pPriv->gamma1 - pPriv->gamma0 > 0x7d)
+ pPriv->gamma1 = pPriv->gamma0 + 0x7d;
+ } else
+ return BadRequest;
+ } else if (attribute == xvGamma1 && (IS_I915G(pI830))) {
+ if (!*pI830->overlayOn) {
+ pPriv->gamma1 = value;
+ if (pPriv->gamma1 - pPriv->gamma0 > 0x7d)
+ pPriv->gamma0 = pPriv->gamma1 - 0x7d;
+ } else
+ return BadRequest;
+ } else if (attribute == xvGamma2 && (IS_I915G(pI830))) {
+ if (!*pI830->overlayOn) {
+ pPriv->gamma2 = value;
+ if (pPriv->gamma3 - pPriv->gamma2 > 0x7d)
+ pPriv->gamma3 = pPriv->gamma2 + 0x7d;
+ } else
+ return BadRequest;
+ } else if (attribute == xvGamma3 && (IS_I915G(pI830))) {
+ if (!*pI830->overlayOn) {
+ pPriv->gamma3 = value;
+ if (pPriv->gamma3 - pPriv->gamma2 > 0x7d)
+ pPriv->gamma2 = pPriv->gamma3 - 0x7d;
+ } else
+ return BadRequest;
+ } else if (attribute == xvGamma4 && (IS_I915G(pI830))) {
+ if (!*pI830->overlayOn) {
+ pPriv->gamma4 = value;
+ if (pPriv->gamma5 - pPriv->gamma4 > 0x7d)
+ pPriv->gamma5 = pPriv->gamma4 + 0x7d;
+ } else
+ return BadRequest;
+ } else if (attribute == xvGamma5 && (IS_I915G(pI830))) {
+ if (!*pI830->overlayOn) {
+ pPriv->gamma5 = value;
+ if (pPriv->gamma5 - pPriv->gamma4 > 0x7d)
+ pPriv->gamma4 = pPriv->gamma5 - 0x7d;
+ } else
+ return BadRequest;
} else if (attribute == xvColorKey) {
pPriv->colorKey = value;
switch (pScrn->depth) {
@@ -720,12 +816,22 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
overlay->DCLRKV = pPriv->colorKey;
break;
}
- if (pPriv->refreshOK)
+ if (pPriv->overlayOK)
OVERLAY_UPDATE;
REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
} else
return BadMatch;
+ /* We've already confirmed that the overlay is off, ready for updating */
+ if ((attribute == xvGamma0 ||
+ attribute == xvGamma1 ||
+ attribute == xvGamma2 ||
+ attribute == xvGamma3 ||
+ attribute == xvGamma4 ||
+ attribute == xvGamma5) && (IS_I915G(pI830))) {
+ I830UpdateGamma(pScrn);
+ }
+
return Success;
}
@@ -733,12 +839,25 @@ static int
I830GetPortAttribute(ScrnInfoPtr pScrn,
Atom attribute, INT32 * value, pointer data)
{
+ I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
if (attribute == xvBrightness) {
*value = pPriv->brightness;
} else if (attribute == xvContrast) {
*value = pPriv->contrast;
+ } else if (attribute == xvGamma0 && (IS_I915G(pI830))) {
+ *value = pPriv->gamma0;
+ } else if (attribute == xvGamma1 && (IS_I915G(pI830))) {
+ *value = pPriv->gamma1;
+ } else if (attribute == xvGamma2 && (IS_I915G(pI830))) {
+ *value = pPriv->gamma2;
+ } else if (attribute == xvGamma3 && (IS_I915G(pI830))) {
+ *value = pPriv->gamma3;
+ } else if (attribute == xvGamma4 && (IS_I915G(pI830))) {
+ *value = pPriv->gamma4;
+ } else if (attribute == xvGamma5 && (IS_I915G(pI830))) {
+ *value = pPriv->gamma5;
} else if (attribute == xvColorKey) {
*value = pPriv->colorKey;
} else
@@ -985,7 +1104,7 @@ UpdateCoeff(int taps, double fCutoff, Bool isHoriz, Bool isY, coeffPtr pCoeff)
SetCoeffRegs(&coeffs[i][tap2Fix], mantSize + 2, pCoeff, pos);
else
SetCoeffRegs(&coeffs[i][tap2Fix], mantSize, pCoeff, pos);
-
+
sum = 0.0;
for (j = 0; j < taps; j++)
sum += coeffs[i][j];
@@ -1004,16 +1123,22 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
I830OverlayRegPtr overlay =
- (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem.Start);
+ (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
unsigned int swidth;
DPRINTF(PFX, "I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
dstPitch);
- if (!pPriv->refreshOK)
+ if (!pPriv->overlayOK)
return;
+#if VIDEO_DEBUG
CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
+#endif
+
+ /* When in dual head with different bpp setups we need to refresh the
+ * color key, so let's reset the video parameters and refresh here */
+ I830ResetVideo(pScrn);
switch (id) {
case FOURCC_YV12:
@@ -1049,15 +1174,27 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
overlay->SHEIGHT = height | ((height / 2) << 16);
+ if (pPriv->oneLineMode) {
+ /* change the coordinates with panel fitting active */
+ dstBox->y1 = (((dstBox->y1 - 1) * pPriv->scaleRatio) >> 16) + 1;
+ dstBox->y2 = ((dstBox->y2 * pPriv->scaleRatio) >> 16) + 1;
+
+ /* Now, alter the height, so we scale to the correct size */
+ drw_h = dstBox->y2 - dstBox->y1;
+ if (drw_h < height) drw_h = height;
+ }
+
overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1;
+
overlay->DWINSZ = ((dstBox->y2 - dstBox->y1) << 16) |
(dstBox->x2 - dstBox->x1);
/* buffer locations */
overlay->OBUF_0Y = pPriv->YBuf0offset;
- overlay->OBUF_1Y = pPriv->YBuf1offset;
overlay->OBUF_0U = pPriv->UBuf0offset;
overlay->OBUF_0V = pPriv->VBuf0offset;
+
+ overlay->OBUF_1Y = pPriv->YBuf1offset;
overlay->OBUF_1U = pPriv->UBuf1offset;
overlay->OBUF_1V = pPriv->VBuf1offset;
@@ -1147,7 +1284,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
scaleChanged = TRUE;
overlay->YRGBSCALE = newval;
}
-
+
newval = (xscaleIntUV << 16) | ((xscaleFractUV & 0xFFF) << 3) |
((yscaleFractUV & 0xFFF) << 20);
if (newval != overlay->UVSCALE) {
@@ -1162,14 +1299,14 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height,
}
/* Recalculate coefficients if the scaling changed. */
-
+
/*
* Only Horizontal coefficients so far.
*/
if (scaleChanged) {
double fCutoffY;
double fCutoffUV;
-
+
fCutoffY = xscaleFract / 4096.0;
fCutoffUV = xscaleFractUV / 4096.0;
@@ -1248,8 +1385,13 @@ I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
{
ScreenPtr pScreen;
FBLinearPtr new_linear;
+ int bytespp = pScrn->bitsPerPixel >> 3;
DPRINTF(PFX, "I830AllocateMemory\n");
+
+ /* convert size in bytes into number of pixels */
+ size = (size + bytespp - 1) / bytespp;
+
if (linear) {
if (linear->size >= size)
return linear;
@@ -1304,6 +1446,19 @@ I830PutImage(ScrnInfoPtr pScrn,
"width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y,
drw_w, drw_h, width, height);
+ if (pI830->entityPrivate) {
+ if (pI830->entityPrivate->XvInUse != -1 &&
+ pI830->entityPrivate->XvInUse != pI830->pipe) {
+ if (!noPanoramiXExtension) {
+ return Success; /* faked for trying to share it */
+ } else {
+ return BadAlloc;
+ }
+ }
+
+ pI830->entityPrivate->XvInUse = pI830->pipe;
+ }
+
/* Clip */
x1 = src_x;
x2 = src_x + src_w;
@@ -1404,12 +1559,8 @@ I830PutImage(ScrnInfoPtr pScrn,
}
/* update cliplist */
- /*
- * XXX Always draw the key. LinDVD seems to fill the window background
- * with a colour different from the key. This works around that.
- */
- if (1 || !REGION_EQUAL(pScreen, &pPriv->clip, clipBoxes)) {
- REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
+ if (!RegionsEqual(&pPriv->clip, clipBoxes)) {
+ REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes);
}
@@ -1503,7 +1654,7 @@ I830BlockHandler(int i,
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
I830OverlayRegPtr overlay =
- (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem.Start);
+ (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
pScreen->BlockHandler = pI830->BlockHandler;
@@ -1524,6 +1675,9 @@ I830BlockHandler(int i,
pPriv->videoStatus = FREE_TIMER;
pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+
+ if (pI830->entityPrivate)
+ pI830->entityPrivate->XvInUse = -1;
}
} else { /* FREE_TIMER */
if (pPriv->freeTime < currentTime.milliseconds) {
@@ -1614,7 +1768,7 @@ I830StopSurface(XF86SurfacePtr surface)
I830Ptr pI830 = I830PTR(pScrn);
I830OverlayRegPtr overlay =
- (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem.Start);
+ (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start);
overlay->OCMD &= ~OVERLAY_ENABLE;
@@ -1622,6 +1776,9 @@ I830StopSurface(XF86SurfacePtr surface)
OVERLAY_OFF;
+ if (pI830->entityPrivate)
+ pI830->entityPrivate->XvInUse = -1;
+
pPriv->isOn = FALSE;
}
@@ -1668,12 +1825,25 @@ I830DisplaySurface(XF86SurfacePtr surface,
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pI830Priv = GET_PORT_PRIVATE(pScrn);
-
INT32 x1, y1, x2, y2;
INT32 loops = 0;
BoxRec dstBox;
DPRINTF(PFX, "I830DisplaySurface\n");
+
+ if (pI830->entityPrivate) {
+ if (pI830->entityPrivate->XvInUse != -1 &&
+ pI830->entityPrivate->XvInUse != pI830->pipe) {
+ if (!noPanoramiXExtension) {
+ return Success; /* faked for trying to share it */
+ } else {
+ return BadAlloc;
+ }
+ }
+
+ pI830->entityPrivate->XvInUse = pI830->pipe;
+ }
+
x1 = src_x;
x2 = src_x + src_w;
y1 = src_y;
@@ -1718,8 +1888,6 @@ I830DisplaySurface(XF86SurfacePtr surface,
else
pI830Priv->currentBuf = 0;
- I830ResetVideo(pScrn);
-
I830DisplayVideo(pScrn, surface->id, surface->width, surface->height,
surface->pitches[0], x1, y1, x2, y2, &dstBox,
src_w, src_h, drw_w, drw_h);
@@ -1769,7 +1937,6 @@ void
I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
I830PortPrivPtr pPriv;
- int pixrate;
if (!I830PTR(pScrn)->adaptor) {
return;
@@ -1782,31 +1949,72 @@ I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode)
return;
}
- pixrate = mode->HDisplay * mode->VDisplay * mode->VRefresh;
- if (pixrate > pPriv->maxRate && pPriv->refreshOK) {
- I830StopVideo(pScrn, pPriv, TRUE);
- pPriv->refreshOK = FALSE;
- }
+ /* We stop the video when mode switching, just so we don't lockup
+ * the engine. The overlayOK will determine whether we can re-enable
+ * with the current video on completion of the mode switch.
+ */
+ I830StopVideo(pScrn, pPriv, TRUE);
+
+ pPriv->oneLineMode = FALSE;
}
void
I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
+ I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv;
- int pixrate;
+ int size, hsize, vsize, active;
- if (!I830PTR(pScrn)->adaptor) {
+ if (!pI830->adaptor) {
return;
}
pPriv = GET_PORT_PRIVATE(pScrn);
if (!pPriv)
return;
- /* If this isn't initialised, assume 60Hz. */
- if (mode->VRefresh == 0)
- mode->VRefresh = 60;
+ if (pI830->pipe == 0) {
+ if (INREG(PIPEACONF) & PIPEACONF_DOUBLE_WIDE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling XVideo output because Pipe A is in double-wide mode.\n");
+ pPriv->overlayOK = FALSE;
+ } else if (!pPriv->overlayOK) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Re-enabling XVideo output because Pipe A is now in single-wide mode.\n");
+ pPriv->overlayOK = TRUE;
+ }
+ }
- pixrate = (mode->HDisplay * mode->VDisplay * mode->VRefresh) / 1000000;
- pPriv->refreshOK = (pixrate <= pPriv->maxRate);
-}
+ if (pI830->pipe == 1) {
+ if (INREG(PIPEBCONF) & PIPEBCONF_DOUBLE_WIDE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling XVideo output because Pipe B is in double-wide mode.\n");
+ pPriv->overlayOK = FALSE;
+ } else if (!pPriv->overlayOK) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Re-enabling XVideo output because Pipe B is now in single-wide mode.\n");
+ pPriv->overlayOK = TRUE;
+ }
+ }
+ /* Check we are on pipe B and have an LFP connected */
+ if ((pI830->pipe == 1) && (pI830->operatingDevices & (PIPE_LFP << 8))) {
+ size = INREG(PIPEBSRC);
+ hsize = (size >> 16) & 0x7FF;
+ vsize = size & 0x7FF;
+ active = INREG(VTOTAL_B) & 0x7FF;
+
+ if (vsize < active && hsize > 1024)
+ I830SetOneLineModeRatio(pScrn);
+
+ if (pPriv->scaleRatio & 0xFFFE0000) {
+ /* Possible bogus ratio, using in-accurate fallback */
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Bogus panel fit register, Xvideo positioning may not be accurate.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Using fallback ratio - was 0x%x, now 0x%x\n", pPriv->scaleRatio, (int)(((float)active * 65536)/(float)vsize));
+
+
+ pPriv->scaleRatio = (int)(((float)active * 65536) / (float)vsize);
+ }
+ }
+}