Commit 5ed7e6f8 authored by Alan Hourihane's avatar Alan Hourihane

i915 support

Dual Head support for i830, i855, i915.
ARGB cursor support (including i810) for all chipsets.
parent a46e9572
.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810.man,v 1.4 2003/07/29 20:59:06 dawes Exp $
.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810.man,v 1.5 2003/10/18 02:27:07 dawes Exp $
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH I810 __drivermansuffix__ __vendorversion__
......@@ -14,7 +14,7 @@ i810 \- Intel 8xx integrated graphics chipsets
.fi
.SH DESCRIPTION
.B i810
is an XFree86 driver for Intel integrated graphics chipsets.
is an __xservername__ driver for Intel integrated graphics chipsets.
The driver supports depths 8, 15, 16 and 24. All visual types are
supported in depth 8. For the i810/i815 other depths support the
TrueColor and DirectColor visuals. For the 830M and later, only the
......@@ -25,10 +25,10 @@ the 830M and later.
.SH SUPPORTED HARDWARE
.B i810
supports the i810, i810-DC100, i810e, i815, 830M, 845G, 852GM, 855GM,
and 865G chipsets.
865G and 915G chipsets.
.SH CONFIGURATION DETAILS
Please refer to XF86Config(__filemansuffix__) for general configuration
Please refer to __xconfigfile__(__filemansuffix__) for general configuration
details. This section only covers configuration details specific to this
driver.
.PP
......@@ -50,7 +50,8 @@ DRI is enabled. This amount may be changed with the
entry in the config file
.B "Device"
section. It may be set to any reasonable value up to 64MB for older
chipsets or 128MB for newer chipets. It is advisable to check the XFree86
chipsets or 128MB for newer chipets. It is advisable to check the
__xservername__
log file to check if any features have been disabled because of insufficient
video memory. In particular, DRI support or tiling mode may be disabled
with insufficient video memory. Either of these being disabled will
......@@ -72,7 +73,8 @@ Disable or enable acceleration. Default: acceleration is enabled.
.TP
.BI "Option \*qSWCursor\*q \*q" boolean \*q
Disable or enable software cursor. Default: software cursor is disable
and a hardware cursor is used.
and a hardware cursor is used for configurations where the hardware cursor
is available.
.TP
.BI "Option \*qColorKey\*q \*q" integer \*q
This sets the default pixel value for the YUV video overlay key.
......@@ -86,7 +88,7 @@ textures. Increasing it can improve 2D performance at the expense of
Default: depends on the resolution, depth, and available video memory. The
driver attempts to allocate at least enough to hold two DVD-sized YUV buffers
by default. The default used for a specific configuration can be found
by examining the XFree86 log file.
by examining the __xservername__ log file.
.TP
.BI "Option \*qDRI\*q \*q" boolean \*q
Disable or enable DRI support.
......@@ -115,6 +117,13 @@ The following driver
.B Options
are supported for the 830M and later chipsets:
.TP
.BI "Option \*qVBERestore\*q \*q" boolean \*q
Enable or disable the use of VBE save/restore for saving and restoring
the initial text mode. This is disabled by default because it causes
lockups on some platforms. However, there are some cases where it must
enabled for the correct restoration of the initial video mode. If you are
having a problem with that, try enabling this option. Default: Disabled.
.TP
.BI "Option \*qVideoKey\*q \*q" integer \*q
This is the same as the
.B \*qColorKey\*q
......@@ -124,12 +133,71 @@ other drivers.
.BI "Option \*qXVideo\*q \*q" boolean \*q
Disable or enable XVideo support.
Default: XVideo is enabled for configurations where it is supported.
.TP
.BI "Option \*qMonitorLayout\*q \*q" anystr \*q
Allow different monitor configurations. e.g. \*qCRT,LFP\*q will
configure a CRT on Pipe A and an LFP on Pipe B. Regardless of the
primary heads' pipe it is always configured as \*q<PIPEA>,<PIPEB>\*q.
Additionally you can add different configurations such as
\*qCRT+DFP,LFP\*q which would put a digital flat panel and a CRT
on pipe A, and a local flat panel on pipe B.
For single pipe configurations you can just specify the monitors types
on Pipe A, such as \*qCRT+DFP\*q which will enable the CRT and DFP
on Pipe A.
Valid monitors are CRT, LFP, DFP, TV, CRT2, LFP2, DFP2, TV2 and NONE.
NOTE: Some configurations of monitor types may fail, this depends on
the Video BIOS and system configuration.
Default: Not configured, and will use the current head's pipe and monitor.
.TP
.BI "Option \*qClone\*q \*q" boolean \*q
Enable Clone mode on pipe B. This will setup the second head as a complete
mirror of the monitor attached to pipe A.
NOTE: Video overlay functions will not work on the second head in this mode.
If you require this, then use the MonitorLayout above and do (as an example)
\*qCRT+DFP,NONE\*q to configure both a CRT and DFP on Pipe A to achieve
local mirroring and disable the use of this option.
Default: Clone mode on pipe B is disabled.
.TP
.BI "Option \*qCloneRefresh\*q \*q" integer \*q
When the Clone option is specified we can drive the second monitor at a
different refresh rate than the primary.
Default: 60Hz.
.TP
.BI "Option \*qCheckLid\*q \*q" boolean \*q
On mobile platforms it's desirable to monitor the lid status and switch
the outputs accordingly when the lid is opened or closed. By default this
option is on, but may incur a very minor performance penalty as we need
to poll a register on the card to check for this activity. It can be
turned off using this option. This only works with the 830M, 852GM and 855GM
systems.
Default: enabled.
.TP
.BI "Option \*qFlipPrimary\*q \*q" boolean \*q
When using a dual pipe system, it may be preferable to switch the primary
screen to the alternate pipe to display on the other monitor connection.
NOTE: Using this option may cause text mode to be restored incorrectly,
and thus should be used with caution.
Default: disabled.
.TP
.BI "Option \*qDisplayInfo\*q \*q" boolean \*q
It has been found that a certain BIOS call can lockup the Xserver because
of a problem in the Video BIOS. The log file will identify if you are
suffering from this problem and tell you to turn this option off.
Default: enabled
.TP
.BI "Option \*qDevicePresence\*q \*q" boolean \*q
Tell the driver to perform an active detect of the currently connected
monitors. This option is useful if the monitor was not connected when
the machine has booted, but unfortunately it doesn't always work and
is extremely dependent upon the Video BIOS.
Default: disabled
.SH "SEE ALSO"
XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__)
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
.SH AUTHORS
Authors include: Keith Whitwell, and also Jonathan Bian, Matthew J Sottek,
Jeff Hartmann, Mark Vojkovich, Alan Hourihane, H. J. Lu. 830M and 845G
support reworked for XFree86 4.3 by David Dawes and Keith Whitwell.
852GM, 855GM, and 865G support added by David Dawes and Keith Whitwell.
915G support added by Alan Hourihane and Keith Whitwell.
Dual Head, Clone and lid status support added by Alan Hourihane.
......@@ -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 */
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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;
}
......@@ -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