summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgareth <gareth>2000-10-09 01:55:32 +0000
committergareth <gareth>2000-10-09 01:55:32 +0000
commit6e6b109b1708692c6e1cf98c76a531cddbcdb037 (patch)
tree63d29416148c2afca9306376babc3cb6cc940f20
parent2548e4c111964730cc0e021d22763b538580e240 (diff)
Checking in latest development work - I need to merge the trunk intoati-4-1-1-20001009-freeze
this branch so I can work on my Mobility 128 laptop. This code is probably broken, and may not even compile properly until after the merge is done.
-rw-r--r--xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h32
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/Imakefile4
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h40
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c94
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c415
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h79
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c692
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h18
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h2
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h22
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_bufs.c2
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c897
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h36
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c18
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h299
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c279
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c168
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h22
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h52
19 files changed, 1831 insertions, 1340 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h b/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h
index 060c4ef7d..c58bd5073 100644
--- a/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h
+++ b/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h,v 1.67 2000/08/11 21:12:48 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h,v 1.72 2000/09/13 15:47:31 martin Exp $ */
/*
* PCI Probe
*
@@ -86,7 +86,6 @@
#define PCI_VENDOR_PICOP 0x1066
#define PCI_VENDOR_MYLEX 0x1069
#define PCI_VENDOR_APPLE 0x106B
-/* Yahama is a guess based on chipset */
#define PCI_VENDOR_YAMAHA 0x1073
#define PCI_VENDOR_NEXGEN 0x1074
#define PCI_VENDOR_QLOGIC 0x1077
@@ -98,6 +97,7 @@
#define PCI_VENDOR_SUN 0x108E
#define PCI_VENDOR_DIAMOND 0x1092
#define PCI_VENDOR_CMD 0x1095
+#define PCI_VENDOR_APPIAN 0x1097
#define PCI_VENDOR_VISION 0x1098
#define PCI_VENDOR_BROOKTREE 0x109E
#define PCI_VENDOR_SIERRA 0x10A8
@@ -229,6 +229,8 @@
#define PCI_CHIP_MACH64LP 0x4C50
#define PCI_CHIP_MACH64LR 0x4C52
#define PCI_CHIP_MACH64LS 0x4C53
+#define PCI_CHIP_RAGE128MF 0x4D46
+#define PCI_CHIP_RAGE128ML 0x4D4C
#define PCI_CHIP_RAGE128PF 0x5046
#define PCI_CHIP_RAGE128PR 0x5052
#define PCI_CHIP_RAGE128RE 0x5245
@@ -472,7 +474,7 @@
#define PCI_CHIP_QUADRO2MXR 0x0113
#define PCI_CHIP_GEFORCE2GTS 0x0150
#define PCI_CHIP_GEFORCE2GTS_1 0x0151
-#define PCI_CHIP_GEFORCE2GTS_2 0x0152
+#define PCI_CHIP_GEFORCE2ULTRA 0x0152
#define PCI_CHIP_QUADRO2PRO 0x0153
/* NVIDIA & SGS */
@@ -550,6 +552,7 @@
#define PCI_CHIP_NM2097 0x0083
#define PCI_CHIP_NM2160 0x0004
#define PCI_CHIP_NM2200 0x0005
+#define PCI_CHIP_NM2230 0x0025
#define PCI_CHIP_NM2360 0x0006
#define PCI_CHIP_NM2380 0x0016
@@ -630,6 +633,7 @@ static SymTabRec xf86PCIVendorNameInfoData[] = {
{PCI_VENDOR_SUN, "Sun"},
{PCI_VENDOR_DIAMOND, "Diamond"},
{PCI_VENDOR_CMD, "CMD"},
+ {PCI_VENDOR_APPIAN, "Appian Graphics"},
{PCI_VENDOR_VISION, "Vision"},
{PCI_VENDOR_BROOKTREE, "BrookTree"},
{PCI_VENDOR_SIERRA, "Sierra"},
@@ -766,8 +770,8 @@ static pciVendorDeviceInfo xf86PCIVendorInfoData[] = {
{PCI_CHIP_MACH64GZ, "Mach64 GZ",0},
{PCI_CHIP_MACH64LB, "Mach64 LB",0},
{PCI_CHIP_MACH64LD, "Mach64 LD",0},
- {PCI_CHIP_RAGE128LE, "Rage 128 Mobility LE",0},
- {PCI_CHIP_RAGE128LF, "Rage 128 Mobility LF",0},
+ {PCI_CHIP_RAGE128LE, "Rage 128 Mobility LE",0},
+ {PCI_CHIP_RAGE128LF, "Rage 128 Mobility LF",0},
{PCI_CHIP_MACH64LG, "Mach64 LG",0},
{PCI_CHIP_MACH64LI, "Mach64 LI",0},
{PCI_CHIP_MACH64LM, "Mach64 LM",0},
@@ -775,8 +779,10 @@ static pciVendorDeviceInfo xf86PCIVendorInfoData[] = {
{PCI_CHIP_MACH64LP, "Mach64 LP",0},
{PCI_CHIP_MACH64LR, "Mach64 LR",0},
{PCI_CHIP_MACH64LS, "Mach64 LS",0},
- {PCI_CHIP_RAGE128PF, "Rage 128 Pro PF",0},
- {PCI_CHIP_RAGE128PR, "Rage 128 Pro PR",0},
+ {PCI_CHIP_RAGE128MF, "Rage 128 Mobility MF",0},
+ {PCI_CHIP_RAGE128ML, "Rage 128 Mobility ML",0},
+ {PCI_CHIP_RAGE128PF, "Rage 128 Pro PF",0},
+ {PCI_CHIP_RAGE128PR, "Rage 128 Pro PR",0},
{PCI_CHIP_RAGE128RE, "Rage 128 RE",0},
{PCI_CHIP_RAGE128RF, "Rage 128 RF",0},
{PCI_CHIP_RAGE128RK, "Rage 128 RK",0},
@@ -970,6 +976,7 @@ static pciVendorDeviceInfo xf86PCIVendorInfoData[] = {
{PCI_CHIP_TI_PERMEDIA2, "Permedia 2",0},
{PCI_CHIP_PCI_1130, "PCI 1130",0},
{PCI_CHIP_PCI_1131, "PCI 1131",0},
+ {0x8019, "TSB12LV23 IEEE1394/FireWire",0},
{0x0000, NULL,0}}},
#ifdef VENDOR_INCLUDE_NONVIDEO
{PCI_VENDOR_SONY, {
@@ -1024,6 +1031,9 @@ static pciVendorDeviceInfo xf86PCIVendorInfoData[] = {
{0x0001, "Bandit",0 },
{0x0002, "Grand Central",0 },
{0x000E, "Hydra",0 },
+ {0x0019, "Keylargo USB",0 },
+ {0x0020, "Uni-North AGP",0 },
+ {0x0022, "Keylargo I/O",0 },
{0x0000, NULL,0}}},
#ifdef INCLUDE_EMPTY_LISTS
{PCI_VENDOR_NEXGEN, {
@@ -1076,6 +1086,11 @@ static pciVendorDeviceInfo xf86PCIVendorInfoData[] = {
{0x0646, "646",0 },
{0x0670, "670",0 },
{0x0000, NULL,0}}},
+#endif
+ {PCI_VENDOR_APPIAN, {
+ {0x3D32, "Jeronimo 2000 AGP",0 },
+ {0x0000, NULL,0}}},
+#ifdef VENDOR_INCLUDE_NONVIDEO
{PCI_VENDOR_VISION, {
{0x0001, "QD 8500",0 },
{0x0002, "QD 8580",0 },
@@ -1144,6 +1159,7 @@ static pciVendorDeviceInfo xf86PCIVendorInfoData[] = {
{PCI_CHIP_NM2093, "NM2093",0},
{PCI_CHIP_NM2160, "NM2160",0},
{PCI_CHIP_NM2200, "NM2200",0},
+ {PCI_CHIP_NM2230, "NM2230 MagicMedia 256AV+",0},
{PCI_CHIP_NM2360, "NM2360",0},
{PCI_CHIP_NM2380, "NM2380",0},
#ifdef VENDOR_INCLUDE_NONVIDEO
@@ -1177,7 +1193,7 @@ static pciVendorDeviceInfo xf86PCIVendorInfoData[] = {
{PCI_CHIP_QUADRO2MXR, "GeForce2 MXR",0},
{PCI_CHIP_GEFORCE2GTS, "GeForce2 GTS",0},
{PCI_CHIP_GEFORCE2GTS_1,"GeForce2 GTS (rev 1)",0},
- {PCI_CHIP_GEFORCE2GTS_2,"GeForce2 GTS (rev 2)",0},
+ {PCI_CHIP_GEFORCE2ULTRA,"GeForce2 ultra",0},
{PCI_CHIP_QUADRO2PRO, "Quadro 2 Pro",0},
{0x0000, NULL,0}}},
#ifdef VENDOR_INCLUDE_NONVIDEO
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/r128/Imakefile
index 06dd69865..23fa7504d 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/Imakefile
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/Imakefile
@@ -1,4 +1,4 @@
-XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/Imakefile,v 1.8 2000/06/17 00:03:21 martin Exp $
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/Imakefile,v 1.9 2000/09/20 00:09:26 keithp Exp $
XCOMM
XCOMM This is the Imakefile for the ATI Rage 128 (r128) driver.
XCOMM
@@ -30,7 +30,7 @@ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
-I$(XF86SRC)/int10 -I$(SERVERSRC)/Xext \
-I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
-I$(EXTINCSRC) -I$(XF86SRC)/xf24_32bpp \
- $(DRIINCLUDES)
+ $(DRIINCLUDES) -I$(SERVERSRC)/render
#endif
DEFINES = $(DRIDEFINES)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h
index 7adb19523..a525ca26a 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h,v 1.11 2000/08/04 16:13:32 eich Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128.h,v 1.12 2000/09/13 15:47:32 martin Exp $ */
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
@@ -40,6 +40,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_TIMEOUT 2000000 /* Fall out of wait loops after this count */
#define R128_MMIOSIZE 0x80000
+#define R128_VBIOS_SIZE 0x00010000
+
/* R128_NAME is used for the server-side
ddx driver, the client-side DRI driver,
and the kernel-level DRM driver. */
@@ -67,7 +69,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
#define R128PTR(pScrn) ((R128InfoPtr)(pScrn)->driverPrivate)
-typedef struct { /* All values in XCLKS */
+typedef struct { /* All values in XCLKS */
int ML; /* Memory Read Latency */
int MB; /* Memory Burst Length */
int Trcd; /* RAS to CAS delay */
@@ -140,7 +142,7 @@ typedef struct {
CARD32 ppll_ref_div;
CARD32 ppll_div_3;
CARD32 htotal_cntl;
-
+
/* DDA register */
CARD32 dda_config;
CARD32 dda_on_off;
@@ -175,10 +177,11 @@ typedef struct {
Bool Primary;
Bool FBDev;
-
+
unsigned long LinearAddr; /* Frame buffer physical address */
unsigned long MMIOAddr; /* MMIO region physical address */
unsigned long BIOSAddr; /* BIOS physical address */
+ Bool BIOSFromPCI; /* BIOS is read from PCI space */
unsigned char *MMIO; /* Map of MMIO region */
unsigned char *FB; /* Map of frame buffer */
@@ -187,20 +190,16 @@ typedef struct {
CARD32 BusCntl;
unsigned long FbMapSize; /* Size of frame buffer, in bytes */
int Flags; /* Saved copy of mode flags */
-
- Bool EnableFP; /* Enable use of FP registers */
- Bool CRTOnly; /* Only use External CRT instead of FP */
+
Bool HasPanelRegs; /* Current chip can connect to a FP */
+ Bool CRTOnly; /* Only use External CRT instead of FP */
+ CARD8 *VBIOS; /* Video BIOS for mode validation on FPs */
+ int FPBIOSstart; /* Start of the flat panel info */
/* Computed values for FPs */
int PanelXRes;
int PanelYRes;
- int PanelHNonVis;
- int PanelHOverPlus;
- int PanelHSyncWidth;
- int PanelVNonVis;
- int PanelVOverPlus;
- int PanelVSyncWidth;
+ int PanelPwrDly;
R128PLLRec pll;
R128RAMPtr ram;
@@ -227,6 +226,13 @@ typedef struct {
int datatype;
CARD32 dp_gui_master_cntl;
+ /* Saved scissor values */
+ CARD32 sc_left;
+ CARD32 sc_right;
+ CARD32 sc_top;
+ CARD32 sc_bottom;
+ CARD32 aux_sc_cntl;
+
/* Saved values for ScreenToScreenCopy */
int xdir;
int ydir;
@@ -260,9 +266,9 @@ typedef struct {
drmSize registerSize;
drmHandle registerHandle;
-
+
Bool IsPCI; /* Current card is a PCI card */
-
+
drmSize agpSize;
drmHandle agpMemHandle; /* Handle from drmAgpAlloc */
unsigned long agpOffset;
@@ -355,10 +361,6 @@ extern int R128MinBits(int val);
extern Bool R128DRIScreenInit(ScreenPtr pScreen);
extern void R128DRICloseScreen(ScreenPtr pScreen);
extern Bool R128DRIFinishScreenInit(ScreenPtr pScreen);
-extern void R128CCEStart(ScrnInfoPtr pScrn);
-extern void R128CCEStop(ScrnInfoPtr pScrn);
-extern void R128CCEResetRing(ScrnInfoPtr pScrn);
-extern void R128CCEWaitForIdle(ScrnInfoPtr pScrn);
#endif
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c
index 7a1ce0ed1..090bc90c0 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c
@@ -1,8 +1,8 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c,v 1.13 2000/06/26 05:41:32 martin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128_accel.c,v 1.14 2000/08/24 22:20:17 tsi Exp $ */ /* -*- c-basic-offset: 4 -*- */
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
- Cedar Park, Texas.
+ Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
@@ -138,11 +138,12 @@ static struct {
void R128EngineFlush(ScrnInfoPtr pScrn)
{
int i;
+ unsigned int j;
R128MMIO_VARS();
-
+
OUTREGP(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, ~R128_PC_FLUSH_ALL);
for (i = 0; i < R128_TIMEOUT; i++) {
- if (!(INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) break;
+ if (!((j=INREG(R128_PC_NGUI_CTLSTAT)) & R128_PC_BUSY)) break;
}
}
@@ -153,10 +154,11 @@ void R128EngineReset(ScrnInfoPtr pScrn)
CARD32 clock_cntl_index;
CARD32 mclk_cntl;
CARD32 gen_reset_cntl;
+ unsigned int j;
R128MMIO_VARS();
-
+
R128EngineFlush(pScrn);
-
+
clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX);
mclk_cntl = INPLL(pScrn, R128_MCLK_CNTL);
@@ -165,16 +167,18 @@ void R128EngineReset(ScrnInfoPtr pScrn)
gen_reset_cntl = INREG(R128_GEN_RESET_CNTL);
OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI);
- INREG(R128_GEN_RESET_CNTL);
+ j = INREG(R128_GEN_RESET_CNTL);
OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI);
- INREG(R128_GEN_RESET_CNTL);
+ j = INREG(R128_GEN_RESET_CNTL);
OUTPLL(R128_MCLK_CNTL, mclk_cntl);
OUTREG(R128_CLOCK_CNTL_INDEX, clock_cntl_index);
OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl);
#ifdef XF86DRI
- if (R128CCE_USE_RING_BUFFER(info->CCEMode)) R128CCEResetRing(pScrn);
+ if (R128CCE_USE_RING_BUFFER(info->CCEMode)) {
+ drmR128ResetCCE(info->drmFD);
+ }
#endif
}
@@ -184,22 +188,26 @@ void R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries)
{
R128InfoPtr info = R128PTR(pScrn);
int i;
+ unsigned int j;
R128MMIO_VARS();
for (;;) {
for (i = 0; i < R128_TIMEOUT; i++) {
- info->fifo_slots = INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK;
+ j = INREG(R128_GUI_STAT);
+ info->fifo_slots = j & R128_GUI_FIFOCNT_MASK;
if (info->fifo_slots >= entries) return;
}
R128TRACE(("FIFO timed out: %d entries, stat=0x%08x, probe=0x%08x\n",
- INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK,
- INREG(R128_GUI_STAT),
+ j & R128_GUI_FIFOCNT_MASK,
+ j,
INREG(R128_GUI_PROBE)));
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"FIFO timed out, resetting engine...\n");
R128EngineReset(pScrn);
#ifdef XF86DRI
- if (info->CCE2D) R128CCEStart(pScrn);
+ if (info->CCE2D) {
+ drmR128StartCCE(info->drmFD);
+ }
#endif
}
}
@@ -211,30 +219,44 @@ void R128WaitForIdle(ScrnInfoPtr pScrn)
{
R128InfoPtr info = R128PTR(pScrn);
int i;
+ unsigned int j;
R128MMIO_VARS();
+
R128WaitForFifoFunction(pScrn, 64);
for (;;) {
for (i = 0; i < R128_TIMEOUT; i++) {
- if (!(INREG(R128_GUI_STAT) & R128_GUI_ACTIVE)) {
+ if (!((j=INREG(R128_GUI_STAT)) & R128_GUI_ACTIVE)) {
R128EngineFlush(pScrn);
return;
}
}
R128TRACE(("Idle timed out: %d entries, stat=0x%08x, probe=0x%08x\n",
- INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK,
- INREG(R128_GUI_STAT),
+ j & R128_GUI_FIFOCNT_MASK,
+ j,
INREG(R128_GUI_PROBE)));
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Idle timed out, resetting engine...\n");
R128EngineReset(pScrn);
#ifdef XF86DRI
- if (info->CCE2D) R128CCEStart(pScrn);
+ if (info->CCE2D) {
+ drmR128StartCCE(info->drmFD);
+ }
#endif
}
}
+/* Wait until the CCE is completely idle: the FIFO has drained and the
+ * CCE is idle.
+ */
+static void R128CCEWaitForIdle(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+
+ drmR128WaitForIdleCCE(info->drmFD);
+}
+
/* Setup for XAA SolidFill. */
static void R128SetupForSolidFill(ScrnInfoPtr pScrn,
int color, int rop, unsigned int planemask)
@@ -269,7 +291,7 @@ static void R128SubsequentSolidFillRect(ScrnInfoPtr pScrn,
}
/* Setup for XAA solid lines. */
-static void R128SetupForSolidLine(ScrnInfoPtr pScrn,
+static void R128SetupForSolidLine(ScrnInfoPtr pScrn,
int color, int rop, unsigned int planemask)
{
R128InfoPtr info = R128PTR(pScrn);
@@ -288,7 +310,7 @@ static void R128SetupForSolidLine(ScrnInfoPtr pScrn,
/* Subsequent XAA solid Bresenham line.
Tests: xtest CH06/drwln, ico, Mark Vojkovich's linetest program
-
+
[See http://www.xfree86.org/devel/archives/devel/1999-Jun/0102.shtml for
Mark Vojkovich's linetest program, posted 2Jun99 to devel@xfree86.org.]
@@ -310,7 +332,7 @@ static void R128SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
if (octant & YMAJOR) flags |= R128_DST_Y_MAJOR;
if (!(octant & XDECREASING)) flags |= R128_DST_X_DIR_LEFT_TO_RIGHT;
if (!(octant & YDECREASING)) flags |= R128_DST_Y_DIR_TOP_TO_BOTTOM;
-
+
R128WaitForFifo(pScrn, 6);
OUTREG(R128_DP_CNTL_XDIR_YDIR_YMAJOR, flags);
OUTREG(R128_DST_Y_X, (y << 16) | x);
@@ -351,7 +373,7 @@ static void R128SubsequentSolidHorVertLine(ScrnInfoPtr pScrn,
NOTE: Since we can only accelerate lines with power-of-2 patterns of
length <= 32, these x11perf numbers are not representative of the
speed-up on appropriately-sized patterns.
-
+
1024x768@76Hz 8bpp
Without With
x11perf -dseg100 218000.0/sec 222000.0/sec
@@ -373,7 +395,7 @@ static void R128SetupForDashedLine(ScrnInfoPtr pScrn,
case 8: pat |= pat << 8; /* fall through */
case 16: pat |= pat << 16;
}
-
+
R128WaitForFifo(pScrn, 5);
OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl
| (bg == -1
@@ -423,7 +445,7 @@ static void R128SubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
XAA wants. */
/* Subsequent XAA SolidFillTrap. XAA always passes data that assumes we
fill from top to bottom, so dyL and dyR are always non-negative. */
-static void R128SubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
+static void R128SubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
int left, int dxL, int dyL, int eL,
int right, int dxR, int dyR, int eR)
{
@@ -479,7 +501,7 @@ static void R128SubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
These x11perf data show why we don't use clipping for lines. Clipping
can improve performance for other functions.
-
+
1024x768@76 8bpp
Without With
x11perf -seg100c1 241000.0/sec 185000.0/sec
@@ -509,7 +531,7 @@ static void R128DisableClipping (ScrnInfoPtr pScrn)
{
R128InfoPtr info = R128PTR(pScrn);
R128MMIO_VARS();
-
+
R128WaitForFifo(pScrn, 2);
OUTREG(R128_SC_TOP_LEFT, 0);
OUTREG(R128_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX
@@ -565,7 +587,7 @@ static void R128SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
if (info->xdir < 0) x1 += w - 1, x2 += w - 1;
if (info->ydir < 0) y1 += h - 1, y2 += h - 1;
-
+
R128WaitForFifo(pScrn, 3);
OUTREG(R128_SRC_Y_X, (y1 << 16) | x1);
OUTREG(R128_DST_Y_X, (y2 << 16) | x2);
@@ -635,7 +657,7 @@ static void R128SetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
R128MMIO_VARS();
R128TRACE(("Color8x8 %d %d %d\n", trans_color, patx, paty));
-
+
R128WaitForFifo(pScrn, 2);
OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl
| R128_GMC_BRUSH_8x8_COLOR
@@ -643,7 +665,7 @@ static void R128SetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
| R128_ROP[rop].rop
| R128_DP_SRC_SOURCE_MEMORY));
OUTREG(R128_DP_WRITE_MASK, planemask);
-
+
if (trans_color != -1) {
/* Set up for transparency */
R128WaitForFifo(pScrn, 3);
@@ -667,7 +689,7 @@ static void R128SubsequentColor8x8PatternFillRect( ScrnInfoPtr pScrn,
OUTREG(R128_DST_Y_X, (y << 16) | x);
OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | w);
}
-#endif
+#endif
/* Setup for XAA indirect CPU-to-screen color expansion (indirect).
Because of how the scratch buffer is initialized, this is really a
@@ -690,7 +712,7 @@ static void R128SubsequentColor8x8PatternFillRect( ScrnInfoPtr pScrn,
1024x768@76 8bpp
Indirect Hybrid
- x11perf -oddsrect10 50100.0/sec 71700.0/sec
+ x11perf -oddsrect10 50100.0/sec 71700.0/sec
x11perf -oddsrect100 4240.0/sec 6660.0/sec
x11perf -bigsrect10 50300.0/sec 71100.0/sec
x11perf -bigsrect100 4190.0/sec 6800.0/sec
@@ -701,7 +723,7 @@ static void R128SubsequentColor8x8PatternFillRect( ScrnInfoPtr pScrn,
x11perf -copyplane100 4400.0/sec 6710.0/sec
x11perf -putimagexy10 5090.0/sec 6670.0/sec
x11perf -putimagexy100 424.0/sec 575.0/sec
-
+
1024x768@76 -depth 24 -fbbpp 32
Indirect Hybrid
x11perf -oddsrect100 4240.0/sec 6670.0/sec
@@ -787,14 +809,14 @@ static void R128SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
return;
}
}
-
+
R128WaitForFifo(pScrn, 2);
OUTREG(R128_DST_Y_X, ((info->scanline_y++ << 16)
| info->scanline_x));
OUTREG(R128_DST_HEIGHT_WIDTH, info->scanline_h_w);
if (info->scanline_direct) return;
-
+
while (left) {
if (left <= 9) {
R128WaitForFifo(pScrn, left);
@@ -841,7 +863,7 @@ static void R128SetupForScanlineImageWrite(ScrnInfoPtr pScrn,
| R128_GMC_BYTE_LSB_TO_MSB
| R128_DP_SRC_SOURCE_HOST_DATA));
OUTREG(R128_DP_WRITE_MASK, planemask);
-
+
if (trans_color != -1) {
/* Set up for transparency */
R128WaitForFifo(pScrn, 3);
@@ -904,14 +926,14 @@ static void R128SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
return;
}
}
-
+
R128WaitForFifo(pScrn, 2);
OUTREG(R128_DST_Y_X, ((info->scanline_y++ << 16)
| info->scanline_x));
OUTREG(R128_DST_HEIGHT_WIDTH, info->scanline_h_w);
if (info->scanline_direct) return;
-
+
while (left) {
if (left <= 9) {
R128WaitForFifo(pScrn, left);
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c
index 52f3704ec..11e4d2bec 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c,v 1.4 2000/06/26 05:41:32 martin Exp $ */ /* -*- mode: c; c-basic-offset: 4 -*- */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.c,v 1.5 2000/08/25 13:42:37 dawes Exp $ */ /* -*- c-basic-offset: 4 -*- */
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
@@ -87,142 +87,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r128.h"
#include "r128_reg.h"
-#define R128_WATERMARK_L 16
-#define R128_WATERMARK_M 8
-#define R128_WATERMARK_N 8
-#define R128_WATERMARK_K 128
-
-static int CCEFifoSlots = 0;
-
-#define R128CCEWaitForFifo(pScrn, entries) \
-do { \
- if (CCEFifoSlots < entries) R128WaitForFifoFunction(pScrn, entries); \
- CCEFifoSlots -= entries; \
-} while (0)
-
-/* Wait for at least `entries' slots are free. The actual number of
- slots available is stored in info->CCEFifoSize. */
-static void R128CCEWaitForFifoFunction(ScrnInfoPtr pScrn, int entries)
-{
- R128InfoPtr info = R128PTR(pScrn);
- unsigned char *R128MMIO = info->MMIO;
- int i;
-
- for (;;) {
- for (i = 0; i < R128_TIMEOUT; i++) {
- CCEFifoSlots = INREG(R128_PM4_STAT) & R128_PM4_FIFOCNT_MASK;
- if (CCEFifoSlots >= entries) return;
- }
- R128EngineReset(pScrn);
- if (info->CCE2D) R128CCEStart(pScrn);
- }
-}
-
-/* Wait until the CCE is completely idle: the FIFO has drained and the
- CCE is idle. */
-void R128CCEWaitForIdle(ScrnInfoPtr pScrn)
-{
- R128InfoPtr info = R128PTR(pScrn);
- unsigned char *R128MMIO = info->MMIO;
- int i;
-
- if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return;
-
- if (R128CCE_USE_RING_BUFFER(info->CCEMode)) {
- volatile CARD32 *r128RingReadPtr =
- (volatile CARD32 *)(info->ringReadPtr);
- R128SAREAPrivPtr pSAREAPriv;
-
- OUTREGP(R128_PM4_BUFFER_DL_WPTR,
- R128_PM4_BUFFER_DL_DONE, ~R128_PM4_BUFFER_DL_DONE);
-
- pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScrn->pScreen);
-
- for (;;) {
- for (i = 0; i < R128_TIMEOUT; i++) {
- if (*r128RingReadPtr == pSAREAPriv->ringWrite) {
- int pm4stat = INREG(R128_PM4_STAT);
- if ((pm4stat & R128_PM4_FIFOCNT_MASK) >= info->CCEFifoSize
- && !(pm4stat & (R128_PM4_BUSY|R128_PM4_GUI_ACTIVE))) {
- R128EngineFlush(pScrn);
- return;
- }
- }
- }
- R128EngineReset(pScrn);
- if (info->CCE2D) R128CCEStart(pScrn);
- }
- } else {
- R128CCEWaitForFifoFunction(pScrn, info->CCEFifoSize);
-
- for (;;) {
- for (i = 0; i < R128_TIMEOUT; i++) {
- if (!(INREG(R128_PM4_STAT)
- & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) {
- R128EngineFlush(pScrn);
- return;
- }
- }
- R128EngineReset(pScrn);
- if (info->CCE2D) R128CCEStart(pScrn);
- }
- }
-}
-
-/* Reset the ring buffer status, if the engine was reset */
-void R128CCEResetRing(ScrnInfoPtr pScrn)
-{
- R128InfoPtr info = R128PTR(pScrn);
- unsigned char *R128MMIO = info->MMIO;
- R128SAREAPrivPtr pSAREAPriv;
- volatile CARD32 *r128RingReadPtr;
-
- if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return;
-
- r128RingReadPtr = (volatile CARD32 *)(info->ringReadPtr);
- pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScrn->pScreen);
-
- OUTREG(R128_PM4_BUFFER_DL_WPTR, 0);
- OUTREG(R128_PM4_BUFFER_DL_RPTR, 0);
- pSAREAPriv->ringWrite = 0;
- *r128RingReadPtr = 0;
-
- /* Resetting the ring turns off the CCE */
- info->CCEInUse = FALSE;
-}
-
-/* Start the CCE, but only if it is not already in use and the requested
- mode is a CCE mode. The mode is stored in info->CCEMode. */
-void R128CCEStart(ScrnInfoPtr pScrn)
-{
- R128InfoPtr info = R128PTR(pScrn);
- unsigned char *R128MMIO = info->MMIO;
-
- if (info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return;
-
- R128WaitForIdle(pScrn);
- OUTREG(R128_PM4_BUFFER_CNTL, info->CCEMode | info->ringSizeLog2QW);
- (void)INREG(R128_PM4_BUFFER_ADDR); /* as per the sample code */
- OUTREG(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN);
- info->CCEInUse = TRUE;
-}
-
-/* Stop the CCE, but only if it is in use and the requested mode is not
- the non-CCE mode. This function also flushes any outstanding
- requests before switching modes.*/
-void R128CCEStop(ScrnInfoPtr pScrn)
-{
- R128InfoPtr info = R128PTR(pScrn);
- unsigned char *R128MMIO = info->MMIO;
-
- if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return;
-
- R128CCEWaitForIdle(pScrn);
- OUTREG(R128_PM4_MICRO_CNTL, 0);
- OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4);
- R128EngineReset(pScrn);
- info->CCEInUse = FALSE;
-}
/* Initialize the visual configs that are supported by the hardware.
These are combined with the visual configs that the indirect
@@ -432,20 +296,22 @@ static void R128EnterServer(ScreenPtr pScreen)
if (info->accel) info->accel->NeedToSync = TRUE;
-#if 1
- if (!info->CCE2D) R128CCEStop(pScrn);
-#else
- if (info->CCE2D) R128CCEWaitForIdle(pScrn);
- else R128CCEStop(pScrn);
-#endif
+ if (!info->CCE2D) {
+ drmR128StopCCE(info->drmFD);
- /* Disable all hardware scissors */
- R128WaitForFifo(pScrn, 3);
- OUTREG(R128_AUX_SC_CNTL, 0);
- OUTREG(R128_SC_TOP_LEFT, (R128_SC_LEFT_DEFAULT |
- R128_SC_TOP_DEFAULT));
- OUTREG(R128_SC_BOTTOM_RIGHT, (R128_SC_RIGHT_DEFAULT |
- R128_SC_BOTTOM_DEFAULT));
+ /* Restore all hardware scissors */
+
+ /* FIXME: This is an evil macro. It requires the 'info'
+ * variable above.
+ */
+ R128WaitForFifo(pScrn, 5);
+
+ OUTREG(R128_SC_LEFT, info->sc_left);
+ OUTREG(R128_SC_RIGHT, info->sc_right);
+ OUTREG(R128_SC_TOP, info->sc_top);
+ OUTREG(R128_SC_BOTTOM, info->sc_bottom);
+ OUTREG(R128_AUX_SC_CNTL, info->aux_sc_cntl);
+ }
}
/* Called when the X server goes to sleep to allow the X server's
@@ -457,14 +323,19 @@ static void R128EnterServer(ScreenPtr pScreen)
static void R128LeaveServer(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr pR128 = R128PTR(pScrn);
+ R128InfoPtr info = R128PTR(pScrn);
+ R128MMIO_VARS();
-#if 1
- if (!pR128->CCE2D) R128CCEStart(pScrn);
-#else
- if (pR128->CCE2D) R128CCEWaitForIdle(pScrn);
- else R128CCEStart(pScrn);
-#endif
+ if (!info->CCE2D) {
+ drmR128StartCCE(info->drmFD);
+
+ /* Save all hardware scissors */
+ info->sc_left = INREG(R128_SC_LEFT);
+ info->sc_right = INREG(R128_SC_RIGHT);
+ info->sc_top = INREG(R128_SC_TOP);
+ info->sc_bottom = INREG(R128_SC_BOTTOM);
+ info->aux_sc_cntl = INREG(R128_SC_BOTTOM);
+ }
}
/* Contexts can be swapped by the X server if necessary. This callback
@@ -796,69 +667,62 @@ static Bool R128DRIMapInit(R128InfoPtr pR128, ScreenPtr pScreen)
return TRUE;
}
-/* Initialize the ring buffer state for use in the X server and any
- DRI-based clients. */
-static void R128DRICCEInitRingBuffer(ScrnInfoPtr pScrn)
-{
- R128InfoPtr info = R128PTR(pScrn);
- unsigned char *R128MMIO = info->MMIO;
- unsigned long addr;
-
- /* FIXME: When we use the CCE for the X server, we should move this
- function (and the support functions above) to r128_accel.c */
-
- /* The manual (p. 2) says this address is
- in "VM space". This means it's an
- offset from the start of AGP space. */
- OUTREG(R128_PM4_BUFFER_OFFSET, info->ringStart | 0x02000000);
-
- OUTREG(R128_PM4_BUFFER_DL_WPTR, 0);
- OUTREG(R128_PM4_BUFFER_DL_RPTR, 0);
-
- /* DL_RPTR_ADDR is a physical address.
- This should be in the SAREA. */
- *(volatile long unsigned *)(info->ringReadPtr) = 0;
- OUTREG(R128_PM4_BUFFER_DL_RPTR_ADDR, (info->ringReadPtrHandle));
-
- /* Set watermark control */
- OUTREG(R128_PM4_BUFFER_WM_CNTL,
- ((R128_WATERMARK_L/4) << R128_WMA_SHIFT)
- | ((R128_WATERMARK_M/4) << R128_WMB_SHIFT)
- | ((R128_WATERMARK_N/4) << R128_WMC_SHIFT)
- | ((R128_WATERMARK_K/64) << R128_WB_WM_SHIFT));
-
- addr = INREG(R128_PM4_BUFFER_ADDR); /* Force read. Why? Because it's
- in the examples... */
-
-#if 0
- R128CCEWaitForIdle(pScrn);
-#endif
-
- /* Turn on bus mastering */
- info->BusCntl &= ~R128_BUS_MASTER_DIS;
- OUTREGP(R128_BUS_CNTL, 0, ~R128_BUS_MASTER_DIS);
-}
-
/* Initialize the kernel data structures. */
static int R128DRIKernelInit(R128InfoPtr pR128, ScreenPtr pScreen)
{
- drmR128Init drmInfo;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ drmR128Init drmInfo;
+ int pitch = pScrn->virtualX;
+ int cpp = pR128->CurrentLayout.pixel_bytes;
+
drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec);
drmInfo.is_pci = pR128->IsPCI;
drmInfo.cce_mode = pR128->CCEMode;
- drmInfo.cce_fifo_size = pR128->CCEFifoSize;
drmInfo.cce_secure = pR128->CCESecure;
drmInfo.ring_size = pR128->ringSize*1024*1024;
drmInfo.usec_timeout = pR128->CCEusecTimeout;
- drmInfo.fb_offset = pR128->LinearAddr;
- drmInfo.agp_ring_offset = pR128->ringHandle;
- drmInfo.agp_read_ptr_offset = pR128->ringReadPtrHandle;
- drmInfo.agp_vertbufs_offset = pR128->vbHandle;
- drmInfo.agp_indbufs_offset = pR128->indHandle;
- drmInfo.agp_textures_offset = pR128->agpTexHandle;
- drmInfo.mmio_offset = pR128->registerHandle;
+ drmInfo.fb_bpp = pR128->CurrentLayout.pixel_code;
+ drmInfo.depth_bpp = pR128->CurrentLayout.pixel_code;
+
+ drmInfo.front_offset = (pR128->fbY * pitch * cpp +
+ pR128->fbX * cpp);
+ drmInfo.front_pitch = pitch;
+ drmInfo.front_x = pR128->fbX;
+ drmInfo.front_y = pR128->fbY;
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] front offset=%d pitch=%d x=%d y=%d\n",
+ drmInfo.front_offset, drmInfo.front_pitch,
+ drmInfo.front_x, drmInfo.front_y );
+
+ drmInfo.back_offset = (pR128->backY * pitch * cpp +
+ pR128->backX * cpp);
+ drmInfo.back_pitch = pitch;
+ drmInfo.back_x = pR128->backX;
+ drmInfo.back_y = pR128->backY;
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] back offset=%d pitch=%d x=%d y=%d\n",
+ drmInfo.back_offset, drmInfo.back_pitch,
+ drmInfo.back_x, drmInfo.back_y );
+
+ drmInfo.depth_offset = (pR128->depthY * pitch * cpp +
+ pR128->depthX * cpp);
+ drmInfo.depth_pitch = pitch;
+ drmInfo.depth_x = pR128->depthX;
+ drmInfo.depth_y = pR128->depthY;
+ xf86DrvMsg( pScreen->myNum, X_INFO,
+ "[drm] depth offset=%d pitch=%d x=%d y=%d\n",
+ drmInfo.depth_offset, drmInfo.depth_pitch,
+ drmInfo.depth_x, drmInfo.depth_y );
+
+ drmInfo.fb_offset = pR128->LinearAddr;
+ drmInfo.mmio_offset = pR128->registerHandle;
+ drmInfo.ring_offset = pR128->ringHandle;
+ drmInfo.ring_rptr_offset = pR128->ringReadPtrHandle;
+ drmInfo.vertex_buffers_offset = pR128->vbHandle;
+ drmInfo.indirect_buffers_offset = pR128->indHandle;
+ drmInfo.agp_textures_offset = pR128->agpTexHandle;
if (drmR128InitCCE(pR128->drmFD, &drmInfo) < 0) return FALSE;
@@ -901,66 +765,15 @@ static Bool R128DRIBufInit(R128InfoPtr pR128, ScreenPtr pScreen)
return TRUE;
}
-/* Load the microcode for the CCE */
-static void R128DRILoadMicrocode(ScrnInfoPtr pScrn)
-{
- unsigned char *R128MMIO = R128PTR(pScrn)->MMIO;
- int i;
- unsigned long R128Microcode[] = {
- /* CCE microcode (from ATI) */
- 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, 1617039951,
- 0, 774592877, 0, 1987540286, 0, 2307490946U, 0, 599558925, 0, 589505315, 0,
- 596487092, 0, 589505315, 1, 11544576, 1, 206848, 1, 311296, 1, 198656, 2,
- 912273422, 11, 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12,
- 28, 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9, 30, 1,
- 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656, 1, 15630, 1, 51200,
- 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1, 15717, 1, 15718, 2, 43, 1,
- 15936948, 1, 570480831, 1, 14715071, 12, 322123831, 1, 33953125, 12, 55, 1,
- 33559908, 1, 15718, 2, 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1,
- 509952, 1, 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1,
- 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1, 15975928, 1,
- 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2, 268449859, 2, 10307, 12,
- 176, 1, 15734, 1, 15735, 1, 15630, 1, 15631, 1, 5253120, 6, 3145810, 16,
- 2150645232U, 1, 15864, 2, 82, 1, 343310, 1, 1064207, 2, 3145813, 1, 15728,
- 1, 7817, 1, 15729, 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002,
- 1, 16008, 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0,
- 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1, 180224, 1,
- 103824738, 2, 112, 2, 3145839, 0, 536885440, 1, 114880, 14, 125, 12,
- 206975, 1, 33559995, 12, 198784, 0, 33570236, 1, 15803, 0, 15804, 3,
- 294912, 1, 294912, 3, 442370, 1, 11544576, 0, 811612160, 1, 12593152, 1,
- 11536384, 1, 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1,
- 14793, 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1,
- 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1, 114880, 14,
- 159, 12, 198784, 1, 1109409213, 12, 198783, 1, 1107312059, 12, 198784, 1,
- 1109409212, 2, 162, 1, 1075854781, 1, 1073757627, 1, 1075854780, 1, 540672,
- 1, 10485760, 6, 3145894, 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0,
- 0, 0, 256, 14, 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858,
- 1, 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1, 33560360, 1,
- 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1, 409611, 9, 188, 0,
- 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0
- };
-
- R128WaitForIdle(pScrn);
-
- OUTREG(R128_PM4_MICROCODE_ADDR, 0);
- for (i = 0; i < 256; i += 1) {
- OUTREG(R128_PM4_MICROCODE_DATAH, R128Microcode[i*2]);
- OUTREG(R128_PM4_MICROCODE_DATAL, R128Microcode[i*2 + 1]);
- }
-}
-
/* Initialize the CCE state, and start the CCE (if used by the X server) */
static void R128DRICCEInit(ScrnInfoPtr pScrn)
{
- R128InfoPtr info = R128PTR(pScrn);
- unsigned char *R128MMIO = info->MMIO;
+ R128InfoPtr info = R128PTR(pScrn);
+
+ /* Mark bus mastering as on */
+ info->BusCntl &= ~R128_BUS_MASTER_DIS;
- /* CCEMode is initialized in r128_driver.c */
+ /* CCEMode is initialized in r128_driver.c */
switch (info->CCEMode) {
case R128_PM4_NONPM4: info->CCEFifoSize = 0; break;
case R128_PM4_192PIO: info->CCEFifoSize = 192; break;
@@ -975,12 +788,11 @@ static void R128DRICCEInit(ScrnInfoPtr pScrn)
}
if (info->CCE2D) {
- /* Make sure the CCE is on for the X server */
- R128CCEStart(pScrn);
+ /* Make sure the CCE is on for the X server */
+ drmR128StartCCE(info->drmFD);
} else {
- /* Make sure the CCE is off for the X server */
- OUTREG(R128_PM4_MICRO_CNTL, 0);
- OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4);
+ /* Make sure the CCE is off for the X server */
+ drmR128StopCCE(info->drmFD);
}
}
@@ -1097,6 +909,8 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
pDRIInfo->devPrivate = NULL;
DRIDestroyInfoRec(pDRIInfo);
pDRIInfo = NULL;
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "Failed to initialize the DRI!\n");
return FALSE;
}
@@ -1126,8 +940,9 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
R128DRICloseScreen(pScreen);
return FALSE;
}
- /* Initialize PCI */
+
#if 0
+ /* Initialize PCI */
if (pR128->IsPCI && !R128DRIPciInit(pR128, pScreen)) {
R128DRICloseScreen(pScreen);
return FALSE;
@@ -1142,7 +957,6 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
return FALSE;
}
#endif
-
/* DRIScreenInit doesn't add all the
common mappings. Add additional
mappings here. */
@@ -1150,22 +964,6 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
R128DRICloseScreen(pScreen);
return FALSE;
}
-
- /* Initialize the ring buffer */
- if (!pR128->IsPCI) R128DRICCEInitRingBuffer(pScrn);
-
- /* Initialize the kernel data structures */
- if (!R128DRIKernelInit(pR128, pScreen)) {
- R128DRICloseScreen(pScreen);
- return FALSE;
- }
-
- /* Initialize vertex buffers list */
- if (!pR128->IsPCI && !R128DRIBufInit(pR128, pScreen)) {
- R128DRICloseScreen(pScreen);
- return FALSE;
- }
-
/* FIXME: When are these mappings unmapped? */
if (!R128InitVisualConfigs(pScreen)) {
@@ -1174,12 +972,6 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Visual configs initialized\n");
- /* Load the CCE Microcode */
- R128DRILoadMicrocode(pScrn);
-
- /* Reset the Graphics Engine */
- R128EngineReset(pScrn);
-
return TRUE;
}
@@ -1193,7 +985,19 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen)
R128SAREAPrivPtr pSAREAPriv;
R128DRIPtr pR128DRI;
- /* Init and start the CCE */
+ /* Initialize the kernel data structures */
+ if (!R128DRIKernelInit(pR128, pScreen)) {
+ R128DRICloseScreen(pScreen);
+ return FALSE;
+ }
+
+ /* Initialize the vertex buffers list */
+ if (!pR128->IsPCI && !R128DRIBufInit(pR128, pScreen)) {
+ R128DRICloseScreen(pScreen);
+ return FALSE;
+ }
+
+ /* Initialize and start the CCE if required */
R128DRICCEInit(pScrn);
pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScreen);
@@ -1245,25 +1049,6 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen)
pR128DRI->IsPCI = pR128->IsPCI;
- switch (pR128->Chipset) {
- case PCI_CHIP_RAGE128RE:
- case PCI_CHIP_RAGE128RF:
- case PCI_CHIP_RAGE128RK:
- case PCI_CHIP_RAGE128RL:
- pR128DRI->chipset = R128_CARD_TYPE_R128;
- break;
- case PCI_CHIP_RAGE128PF:
- pR128DRI->chipset = R128_CARD_TYPE_R128_PRO;
- break;
- case PCI_CHIP_RAGE128LE:
- case PCI_CHIP_RAGE128LF:
- pR128DRI->chipset = R128_CARD_TYPE_R128_MOBILITY;
- break;
- default:
- pR128DRI->chipset = R128_CARD_TYPE_R128;
- break;
- }
-
pR128DRI->CCEMode = pR128->CCEMode;
pR128DRI->CCEFifoSize = pR128->CCEFifoSize;
@@ -1280,7 +1065,7 @@ void R128DRICloseScreen(ScreenPtr pScreen)
R128InfoPtr pR128 = R128PTR(pScrn);
/* Stop the CCE if it is still in use */
- if (pR128->CCE2D) R128CCEStop(pScrn);
+ if (pR128->CCE2D) drmR128StopCCE(pR128->drmFD);
/* De-allocate vertex buffers */
if (pR128->vbBufs) {
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h
index 3078f1623..b10c74bfd 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_dri.h
@@ -43,7 +43,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_DEFAULT_CCE_PIO_MODE R128_PM4_64PIO_64VCBM_64INDBM
#define R128_DEFAULT_CCE_BM_MODE R128_PM4_64BM_64VCBM_64INDBM
#define R128_DEFAULT_AGP_MODE 2
-#define R128_DEFAULT_AGP_SIZE 8 /* MB (must be power of two, >= 4) */
+#define R128_DEFAULT_AGP_SIZE 8 /* MB (must be power of 2, >= 4MB) */
#define R128_DEFAULT_RING_SIZE 1 /* MB (must be page aligned) */
#define R128_DEFAULT_VB_SIZE 1 /* MB (must be page aligned) */
#define R128_DEFAULT_IND_SIZE 1 /* MB (must be page aligned) */
@@ -66,57 +66,56 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
typedef struct {
/* MMIO register data */
- drmHandle registerHandle;
- drmSize registerSize;
+ drmHandle registerHandle;
+ drmSize registerSize;
/* CCE ring buffer data */
- drmHandle ringHandle;
- drmSize ringMapSize;
- int ringSize;
+ drmHandle ringHandle;
+ drmSize ringMapSize;
+ int ringSize;
/* CCE ring read pointer data */
- drmHandle ringReadPtrHandle;
- drmSize ringReadMapSize;
+ drmHandle ringReadPtrHandle;
+ drmSize ringReadMapSize;
/* CCE vertex buffer data */
- drmHandle vbHandle;
- drmSize vbMapSize;
- int vbOffset;
- int vbBufSize;
+ drmHandle vbHandle;
+ drmSize vbMapSize;
+ int vbOffset;
+ int vbBufSize;
/* CCE indirect buffer data */
- drmHandle indHandle;
- drmSize indMapSize;
+ drmHandle indHandle;
+ drmSize indMapSize;
/* CCE AGP Texture data */
- drmHandle agpTexHandle;
- drmSize agpTexMapSize;
- int log2AGPTexGran;
- int agpTexOffset;
+ drmHandle agpTexHandle;
+ drmSize agpTexMapSize;
+ int log2AGPTexGran;
+ int agpTexOffset;
/* DRI screen private data */
- int deviceID; /* PCI device ID */
- int width; /* Width in pixels of display */
- int height; /* Height in scanlines of display */
- int depth; /* Depth of display (8, 15, 16, 24) */
- int bpp; /* Bit depth of display (8, 16, 24, 32) */
-
- int fbX; /* Start of frame buffer */
- int fbY;
- int backX; /* Start of shared back buffer */
- int backY;
- int depthX; /* Start of shared depth buffer */
- int depthY;
- int textureX; /* Start of texture data in frame buffer */
- int textureY;
- int textureSize;
- int log2TexGran;
-
- int chipset;
- int IsPCI; /* Current card is a PCI card */
-
- int CCEMode; /* CCE mode that server/clients use */
- int CCEFifoSize; /* Size of the CCE command FIFO */
+ int deviceID; /* PCI device ID */
+ int width; /* Width in pixels of display */
+ int height; /* Height in scanlines of display */
+ int depth; /* Depth of display (8, 15, 16, 24) */
+ int bpp; /* Bit depth of display (8, 16, 24, 32) */
+
+ int fbX; /* Start of frame buffer */
+ int fbY;
+ int backX; /* Start of shared back buffer */
+ int backY;
+ int depthX; /* Start of shared depth buffer */
+ int depthY;
+ int textureX; /* Start of texture data in frame buffer */
+ int textureY;
+ int textureSize;
+ int log2TexGran;
+
+ int IsPCI; /* Current card is a PCI card */
+
+ int CCEMode; /* CCE mode that server/clients use */
+ int CCEFifoSize; /* Size of the CCE command FIFO */
} R128DRIRec, *R128DRIPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c
index b4706e310..ad6df8900 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c,v 1.40 2000/08/04 16:13:32 eich Exp $ */ /* -*- mode: c; c-basic-offset: 4 -*- */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128_driver.c,v 1.46 2000/09/20 00:09:26 keithp Exp $ */ /* -*- c-basic-offset: 4 -*- */
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
@@ -120,6 +120,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r128_sarea.h"
#endif
+#ifdef RENDER
+#include "picturestr.h"
+#endif
/* Driver data structures */
#include "r128.h"
#include "r128_reg.h"
@@ -171,6 +174,8 @@ static SymTabRec R128Chipsets[] = {
{ PCI_CHIP_RAGE128PF, "ATI Rage 128 Pro PF (AGP)" },
{ PCI_CHIP_RAGE128LE, "ATI Rage 128 Mobility LE (PCI)" },
{ PCI_CHIP_RAGE128LF, "ATI Rage 128 Mobility LF (AGP)" },
+ { PCI_CHIP_RAGE128MF, "ATI Rage 128 Mobility MF (AGP)" },
+ { PCI_CHIP_RAGE128ML, "ATI Rage 128 Mobility ML (AGP)" },
{ -1, NULL }
};
@@ -182,6 +187,8 @@ static PciChipsets R128PciChipsets[] = {
{ PCI_CHIP_RAGE128PF, PCI_CHIP_RAGE128PF, RES_SHARED_VGA },
{ PCI_CHIP_RAGE128LE, PCI_CHIP_RAGE128LE, RES_SHARED_VGA },
{ PCI_CHIP_RAGE128LF, PCI_CHIP_RAGE128LF, RES_SHARED_VGA },
+ { PCI_CHIP_RAGE128MF, PCI_CHIP_RAGE128MF, RES_SHARED_VGA },
+ { PCI_CHIP_RAGE128ML, PCI_CHIP_RAGE128ML, RES_SHARED_VGA },
{ -1, -1, RES_UNDEFINED }
};
@@ -203,8 +210,12 @@ typedef enum {
OPTION_VBUF_SIZE,
OPTION_USE_CCE_2D,
#endif
- OPTION_ENABLE_FP,
+#if 0
+ /* FIXME: Disable CRTOnly until it is tested */
OPTION_CRT,
+#endif
+ OPTION_PANEL_WIDTH,
+ OPTION_PANEL_HEIGHT,
OPTION_FBDEV
} R128Opts;
@@ -226,8 +237,12 @@ static OptionInfoRec R128Options[] = {
{ OPTION_VBUF_SIZE, "VBSize", OPTV_INTEGER, {0}, FALSE },
{ OPTION_USE_CCE_2D, "UseCCEfor2D", OPTV_BOOLEAN, {0}, FALSE },
#endif
- { OPTION_ENABLE_FP, "EnableFP", OPTV_BOOLEAN, {0}, FALSE },
+#if 0
+ /* FIXME: Disable CRTOnly until it is tested */
{ OPTION_CRT, "CRTOnly", OPTV_BOOLEAN, {0}, FALSE },
+#endif
+ { OPTION_PANEL_WIDTH, "PanelWidth", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_PANEL_HEIGHT, "PanelHeight", OPTV_INTEGER, {0}, FALSE },
{ OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -280,14 +295,6 @@ static const char *fbdevHWSymbols[] = {
NULL
};
-static const char *vbeSymbols[] = {
- "VBEInit",
- "vbeDoEDID",
- NULL
-};
-
-#if 0
- /* Not used until DDC is supported. */
static const char *ddcSymbols[] = {
"xf86PrintEDID",
"xf86DoEDID_DDC1",
@@ -295,6 +302,7 @@ static const char *ddcSymbols[] = {
NULL
};
+#if 0
static const char *i2cSymbols[] = {
"xf86CreateI2CBusRec",
"xf86I2CBusInit",
@@ -303,9 +311,18 @@ static const char *i2cSymbols[] = {
#endif
#ifdef XFree86LOADER
+static const char *vbeSymbols[] = {
+ "VBEInit",
+ "vbeDoEDID",
+ NULL
+};
+
#ifdef USE_FB
static const char *fbSymbols[] = {
"fbScreenInit",
+#ifdef RENDER
+ "fbPictureInit",
+#endif
NULL
};
#else
@@ -431,9 +448,11 @@ static pointer R128Setup(pointer module, pointer opts, int *errmaj,
#endif
fbdevHWSymbols,
vbeSymbols,
- 0 /* ddcsymbols */,
- 0 /* i2csymbols */,
- 0 /* shadowSymbols */,
+#if 0
+ NULL /* ddcsymbols */,
+ NULL /* i2csymbols */,
+ NULL /* shadowSymbols */,
+#endif
NULL);
/*
@@ -492,9 +511,9 @@ static Bool R128UnmapMMIO(ScrnInfoPtr pScrn)
{
R128InfoPtr info = R128PTR(pScrn);
- if (info->FBDev)
+ if (info->FBDev) {
fbdevHWUnmapMMIO(pScrn);
- else {
+ } else {
xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, R128_MMIOSIZE);
}
info->MMIO = NULL;
@@ -525,7 +544,7 @@ static Bool R128UnmapFB(ScrnInfoPtr pScrn)
{
R128InfoPtr info = R128PTR(pScrn);
- if(info->FBDev)
+ if (info->FBDev)
fbdevHWUnmapVidmem(pScrn);
else
xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);
@@ -576,10 +595,12 @@ void R128WaitForVerticalSync(ScrnInfoPtr pScrn)
{
int i;
R128MMIO_VARS();
+ unsigned int j;
OUTREG(R128_GEN_INT_STATUS, R128_VSYNC_INT_AK);
for (i = 0; i < R128_TIMEOUT; i++) {
- if (INREG(R128_GEN_INT_STATUS) & R128_VSYNC_INT) break;
+ j = INREG(R128_GEN_INT_STATUS);
+ if (j & R128_VSYNC_INT) break;
}
}
@@ -615,34 +636,128 @@ static int R128Div(int n, int d)
return (n + (d / 2)) / d;
}
-/* Read PLL parameters from BIOS block. Default to typical values if there
- is no BIOS. */
-static Bool R128GetPLLParameters(ScrnInfoPtr pScrn)
+/* Read the Video BIOS block and the FP registers (if applicable). */
+static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn)
{
- R128InfoPtr info = R128PTR(pScrn);
- R128PLLPtr pll = &info->pll;
- CARD16 bios_header;
- CARD16 pll_info_block;
- CARD8 tmp[64];
- Bool BIOSFromPCI = TRUE;
+ R128InfoPtr info = R128PTR(pScrn);
+ int i;
+ int FPHeader = 0;
-#define R128ReadBIOS(offset, buffer, length) \
- (BIOSFromPCI ? \
- xf86ReadPciBIOS(offset, info->PciTag, 0, buffer, length) : \
- xf86ReadBIOS(info->BIOSAddr, offset, buffer, length))
+#define R128ReadBIOS(offset, buffer, length) \
+ (info->BIOSFromPCI ? \
+ xf86ReadPciBIOS(offset, info->PciTag, 0, buffer, length) : \
+ xf86ReadBIOS(info->BIOSAddr, offset, buffer, length))
- R128ReadBIOS(0, tmp, sizeof(tmp));
- if (tmp[0] != 0x55 || tmp[1] != 0xaa)
- {
+#define R128_BIOS8(v) (*((CARD8 *)(info->VBIOS + (v))))
+#define R128_BIOS16(v) (*((CARD16 *)(info->VBIOS + (v))))
+#define R128_BIOS32(v) (*((CARD32 *)(info->VBIOS + (v))))
+
+ if (!(info->VBIOS = xalloc(R128_VBIOS_SIZE))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Cannot allocate space for hold Video BIOS!\n");
+ return FALSE;
+ }
+
+ info->BIOSFromPCI = TRUE;
+ R128ReadBIOS(0x0000, info->VBIOS, R128_VBIOS_SIZE);
+ if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Video BIOS not detected in PCI space!\n");
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Attempting to read Video BIOS from legacy ISA space!\n");
- BIOSFromPCI = FALSE;
+ info->BIOSFromPCI = FALSE;
info->BIOSAddr = 0x000c0000;
- R128ReadBIOS(0, tmp, sizeof(tmp));
+ R128ReadBIOS(0x0000, info->VBIOS, R128_VBIOS_SIZE);
+ }
+ if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) {
+ info->BIOSAddr = 0x00000000;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Video BIOS not found!\n");
+ }
+
+ if (info->HasPanelRegs) {
+ info->FPBIOSstart = 0;
+
+ /* FIXME: There should be direct access to the start of the FP info
+ tables, but until we find out where that offset is stored, we
+ must search for the ATI signature string: "M3 ". */
+ for (i = 4; i < R128_VBIOS_SIZE-8; i++) {
+ if (R128_BIOS8(i) == 'M' &&
+ R128_BIOS8(i+1) == '3' &&
+ R128_BIOS8(i+2) == ' ' &&
+ R128_BIOS8(i+3) == ' ' &&
+ R128_BIOS8(i+4) == ' ' &&
+ R128_BIOS8(i+5) == ' ' &&
+ R128_BIOS8(i+6) == ' ' &&
+ R128_BIOS8(i+7) == ' ') {
+ FPHeader = i-2;
+ break;
+ }
+ }
+
+ if (!FPHeader) return TRUE;
+
+ /* Assume that only one panel is attached and supported */
+ for (i = FPHeader+20; i < FPHeader+84; i += 2) {
+ if (R128_BIOS16(i) != 0) {
+ info->FPBIOSstart = R128_BIOS16(i);
+ break;
+ }
+ }
+ if (!info->FPBIOSstart) return TRUE;
+
+ if (!info->PanelXRes)
+ info->PanelXRes = R128_BIOS16(info->FPBIOSstart+25);
+ if (!info->PanelYRes)
+ info->PanelYRes = R128_BIOS16(info->FPBIOSstart+27);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n",
+ info->PanelXRes, info->PanelYRes);
+
+ info->PanelPwrDly = R128_BIOS8(info->FPBIOSstart+56);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: ");
+ for (i = 1; i <= 24; i++)
+ ErrorF("%c", R128_BIOS8(info->FPBIOSstart+i));
+ ErrorF("\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: ");
+ i = R128_BIOS16(info->FPBIOSstart+29);
+ if (i & 1) ErrorF("Color, ");
+ else ErrorF("Monochrome, ");
+ if (i & 2) ErrorF("Dual(split), ");
+ else ErrorF("Single, ");
+ switch ((i >> 2) & 0x3f) {
+ case 0: ErrorF("STN"); break;
+ case 1: ErrorF("TFT"); break;
+ case 2: ErrorF("Active STN"); break;
+ case 3: ErrorF("EL"); break;
+ case 4: ErrorF("Plasma"); break;
+ default: ErrorF("UNKNOWN"); break;
+ }
+ ErrorF("\n");
+ if (R128_BIOS8(info->FPBIOSstart+61) & 1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n");
+ } else {
+ /* FIXME: Add Non-LVDS flat pael support */
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Non-LVDS panel interface detected! "
+ "This support is untested and may not "
+ "function properly\n");
+ }
}
- if (tmp[0] != 0x55 || tmp[1] != 0xaa) {
+
+ return TRUE;
+}
+
+/* Read PLL parameters from BIOS block. Default to typical values if there
+ is no BIOS. */
+static Bool R128GetPLLParameters(ScrnInfoPtr pScrn)
+{
+ R128InfoPtr info = R128PTR(pScrn);
+ R128PLLPtr pll = &info->pll;
+ CARD16 bios_header;
+ CARD16 pll_info_block;
+
+ if (!info->VBIOS) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Video BIOS not detected, using default PLL parameters!\n");
/* These probably aren't going to work for
@@ -655,27 +770,16 @@ static Bool R128GetPLLParameters(ScrnInfoPtr pScrn)
pll->max_pll_freq = 25000;
pll->xclk = 10300;
} else {
- R128ReadBIOS(0x48,
- (CARD8 *)&bios_header, sizeof(bios_header));
- R128ReadBIOS(bios_header + 0x30,
- (CARD8 *)&pll_info_block, sizeof(pll_info_block));
+ bios_header = R128_BIOS16(0x48);
+ pll_info_block = R128_BIOS16(bios_header + 0x30);
R128TRACE(("Header at 0x%04x; PLL Information at 0x%04x\n",
bios_header, pll_info_block));
- R128ReadBIOS(pll_info_block + 0x0e,
- (CARD8 *)&pll->reference_freq,
- sizeof(pll->reference_freq));
- R128ReadBIOS(pll_info_block + 0x10,
- (CARD8 *)&pll->reference_div,
- sizeof(pll->reference_div));
- R128ReadBIOS(pll_info_block + 0x12,
- (CARD8 *)&pll->min_pll_freq,
- sizeof(pll->min_pll_freq));
- R128ReadBIOS(pll_info_block + 0x16,
- (CARD8 *)&pll->max_pll_freq,
- sizeof(pll->max_pll_freq));
- R128ReadBIOS(pll_info_block + 0x08,
- (CARD8 *)&pll->xclk, sizeof(pll->xclk));
+ pll->reference_freq = R128_BIOS16(pll_info_block + 0x0e);
+ pll->reference_div = R128_BIOS16(pll_info_block + 0x10);
+ pll->min_pll_freq = R128_BIOS32(pll_info_block + 0x12);
+ pll->max_pll_freq = R128_BIOS32(pll_info_block + 0x16);
+ pll->xclk = R128_BIOS16(pll_info_block + 0x08);
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -863,9 +967,6 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
int offset = 0; /* RAM Type */
MessageType from;
unsigned char *R128MMIO;
- CARD32 fp_horz_stretch = 0, fp_vert_stretch = 0;
- CARD32 crtc_h_total_disp = 0, crtc_v_total_disp = 0;
- CARD32 crtc_h_sync_strt_wid = 0, crtc_v_sync_strt_wid = 0;
/* Chipset */
from = X_PROBED;
@@ -953,7 +1054,9 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
/* FIXME: Make this an option */
switch (info->Chipset) {
case PCI_CHIP_RAGE128LE:
- case PCI_CHIP_RAGE128LF: info->HasPanelRegs = TRUE; break;
+ case PCI_CHIP_RAGE128LF:
+ case PCI_CHIP_RAGE128MF:
+ case PCI_CHIP_RAGE128ML: info->HasPanelRegs = TRUE; break;
case PCI_CHIP_RAGE128RE:
case PCI_CHIP_RAGE128RF:
case PCI_CHIP_RAGE128RK:
@@ -972,14 +1075,6 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
pScrn->videoRam = INREG(R128_CONFIG_MEMSIZE) / 1024;
info->MemCntl = INREG(R128_MEM_CNTL);
info->BusCntl = INREG(R128_BUS_CNTL);
- if (info->HasPanelRegs) {
- fp_horz_stretch = INREG(R128_FP_HORZ_STRETCH);
- fp_vert_stretch = INREG(R128_FP_VERT_STRETCH);
- crtc_h_total_disp = INREG(R128_CRTC_H_TOTAL_DISP);
- crtc_v_total_disp = INREG(R128_CRTC_V_TOTAL_DISP);
- crtc_h_sync_strt_wid = INREG(R128_CRTC_H_SYNC_STRT_WID);
- crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID);
- }
R128MMIO = NULL;
R128UnmapMMIO(pScrn);
@@ -989,6 +1084,8 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
switch (info->Chipset) {
case PCI_CHIP_RAGE128LE:
case PCI_CHIP_RAGE128LF:
+ case PCI_CHIP_RAGE128MF:
+ case PCI_CHIP_RAGE128ML:
case PCI_CHIP_RAGE128RE:
case PCI_CHIP_RAGE128RF: offset = 0; break; /* 128-bit SDR SGRAM 1:1 */
case PCI_CHIP_RAGE128RK:
@@ -1016,10 +1113,12 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
"VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name);
/* Flat panel (part 2) */
- if ((info->EnableFP = xf86ReturnOptValBool(R128Options,
- OPTION_ENABLE_FP, FALSE))) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Enabling use of flat panel registers\n");
+ if (info->HasPanelRegs) {
+#if 1
+ info->CRTOnly = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using flat panel for display\n");
+#else
if ((info->CRTOnly = xf86ReturnOptValBool(R128Options,
OPTION_CRT, FALSE))) {
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
@@ -1029,57 +1128,24 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Using flat panel for display\n");
}
+#endif
+ } else {
+ info->CRTOnly = FALSE;
}
if (info->HasPanelRegs) {
- int tmp;
-
- info->PanelXRes =
- (fp_horz_stretch & R128_HORZ_PANEL_SIZE) >> R128_HORZ_PANEL_SHIFT;
- info->PanelXRes = (info->PanelXRes + 1) * 8;
- info->PanelYRes =
- (fp_vert_stretch & R128_VERT_PANEL_SIZE) >> R128_VERT_PANEL_SHIFT;
- info->PanelYRes += 1;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel dimensions: %dx%d\n",
- info->PanelXRes, info->PanelYRes);
-
- info->PanelHNonVis =
- (crtc_h_total_disp & R128_CRTC_H_TOTAL) >> R128_CRTC_H_TOTAL_SHIFT;
- info->PanelHNonVis += 4; /* Add 4 since we are in VGA mode */
- tmp =
- (crtc_h_total_disp & R128_CRTC_H_DISP) >> R128_CRTC_H_DISP_SHIFT;
- info->PanelHNonVis -= tmp;
- info->PanelHOverPlus =
- (crtc_h_sync_strt_wid & R128_CRTC_H_SYNC_STRT_CHAR)
- >> R128_CRTC_H_SYNC_STRT_CHAR_SHIFT;
- info->PanelHOverPlus -= tmp;
- switch (info->CurrentLayout.pixel_code) {
- /* Adjustments are from ATI */
- case 8: info->PanelHOverPlus += 2; break;
- case 15:
- case 16: info->PanelHOverPlus += 1; break;
- case 24:
- case 32: info->PanelHOverPlus += 0; break;
+ info->PanelXRes = 0;
+ info->PanelYRes = 0;
+ if (xf86GetOptValInteger(R128Options,
+ OPTION_PANEL_WIDTH, &(info->PanelXRes))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Flat panel width: %d\n", info->PanelXRes);
+ }
+ if (xf86GetOptValInteger(R128Options,
+ OPTION_PANEL_HEIGHT, &(info->PanelYRes))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Flat panel height: %d\n", info->PanelYRes);
}
- info->PanelHSyncWidth =
- (crtc_h_sync_strt_wid & R128_CRTC_H_SYNC_WID)
- >> R128_CRTC_H_SYNC_WID_SHIFT;
- info->PanelHSyncWidth += 14; /* ??? */
-
- info->PanelVNonVis =
- (crtc_v_total_disp & R128_CRTC_V_TOTAL) >> R128_CRTC_V_TOTAL_SHIFT;
- info->PanelVNonVis += 1; /* Add 1 since we are in VGA mode */
- tmp =
- (crtc_v_total_disp & R128_CRTC_V_DISP) >> R128_CRTC_V_DISP_SHIFT;
- info->PanelVNonVis -= tmp;
- info->PanelVOverPlus =
- (crtc_v_sync_strt_wid & R128_CRTC_V_SYNC_STRT)
- >> R128_CRTC_V_SYNC_STRT_SHIFT;
- info->PanelVOverPlus -= tmp + 1;
- info->PanelVSyncWidth =
- (crtc_v_sync_strt_wid & R128_CRTC_V_SYNC_WID)
- >> R128_CRTC_V_SYNC_WID_SHIFT;
- info->PanelVSyncWidth -= 2; /* ??? */
}
#ifdef XF86DRI
@@ -1093,6 +1159,8 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
case PCI_CHIP_RAGE128RE:
case PCI_CHIP_RAGE128RK: info->IsPCI = TRUE; break;
case PCI_CHIP_RAGE128LF:
+ case PCI_CHIP_RAGE128MF:
+ case PCI_CHIP_RAGE128ML:
case PCI_CHIP_RAGE128RF:
case PCI_CHIP_RAGE128RL:
case PCI_CHIP_RAGE128PF:
@@ -1106,33 +1174,19 @@ static Bool R128PreInitConfig(ScrnInfoPtr pScrn)
static Bool R128PreInitDDC(ScrnInfoPtr pScrn)
{
- /* FIXME: DDC support goes here. */
-#if 0
- /* Using the GPIO_MONID register for DDC2
- does not appear to work as expected.
- Hence, the implementation of DDC is
- deferred. */
R128InfoPtr info = R128PTR(pScrn);
- Bool ret = TRUE;
+ vbeInfoPtr pVbe;
if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE;
xf86LoaderReqSymLists(ddcSymbols, NULL);
- if (!xf86LoadSubModule(pScrn, "i2c")) return FALSE;
- xf86LoaderReqSymLists(i2cSymbols, NULL);
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ pVbe = VBEInit(NULL,info->pEnt->index);
+ if (!pVbe) return NULL;
- R128MapMMIO(pScrn);
- if (!R128I2CInit(pScrn)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I2C initialization failed\n");
- ret = FALSE;
- } else {
- xf86SetDDCProperties(pScrn,xf86PrintEDID(
- xf86DoEDID_DDC2(pScrn->scrnIndex, info->i2c)));
- }
- R128UnmapMMIO(pScrn);
- return ret;
-#else
- return TRUE;
-#endif
+ xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL)));
+ return TRUE;
+ } else
+ return FALSE;
}
/* This is called by R128PreInit to initialize gamma correction. */
@@ -1155,14 +1209,19 @@ static Bool R128PreInitModes(ScrnInfoPtr pScrn)
const char *Sym = NULL;
/* Get mode information */
- pScrn->progClock = TRUE;
- clockRanges = xnfcalloc(sizeof(*clockRanges), 1);
- clockRanges->next = NULL;
- clockRanges->minClock = info->pll.min_pll_freq;
- clockRanges->maxClock = info->pll.max_pll_freq * 10;
- clockRanges->clockIndex = -1;
- clockRanges->interlaceAllowed = TRUE;
- clockRanges->doubleScanAllowed = TRUE;
+ pScrn->progClock = TRUE;
+ clockRanges = xnfcalloc(sizeof(*clockRanges), 1);
+ clockRanges->next = NULL;
+ clockRanges->minClock = info->pll.min_pll_freq;
+ clockRanges->maxClock = info->pll.max_pll_freq * 10;
+ clockRanges->clockIndex = -1;
+ if (info->HasPanelRegs) {
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = FALSE;
+ } else {
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE;
+ }
modesFound = xf86ValidateModes(pScrn,
pScrn->monitor->Modes,
@@ -1218,6 +1277,11 @@ static Bool R128PreInitModes(ScrnInfoPtr pScrn)
#endif
if (mod && !xf86LoadSubModule(pScrn, mod)) return FALSE;
xf86LoaderReqSymbols(Sym, NULL);
+#ifdef USE_FB
+#ifdef RENDER
+ xf86LoaderReqSymbols("fbPictureInit", NULL);
+#endif
+#endif
info->CurrentLayout.displayWidth = pScrn->displayWidth;
info->CurrentLayout.mode = pScrn->currentMode;
@@ -1263,13 +1327,11 @@ static Bool R128PreInitDRI(ScrnInfoPtr pScrn)
R128InfoPtr info = R128PTR(pScrn);
if (info->IsPCI) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "CCE in PIO mode\n");
info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;
} else if (xf86ReturnOptValBool(R128Options, OPTION_CCE_PIO, FALSE)) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "CCE in PIO mode\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CCE into PIO mode\n");
info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;
} else {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "CCE in BM mode\n");
info->CCEMode = R128_DEFAULT_CCE_BM_MODE;
}
@@ -1366,46 +1428,8 @@ static Bool R128PreInitDRI(ScrnInfoPtr pScrn)
"Buffers are too big for requested AGP space\n");
return FALSE;
}
-
- info->agpTexSize = info->agpSize - (info->ringSize +
- info->vbSize +
- info->indSize);
-
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using %d MB AGP aperture\n", info->agpSize);
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using %d MB for AGP textures\n", info->agpTexSize);
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using %d MB for the ring buffer\n", info->ringSize);
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using %d MB for indirect buffers\n", info->indSize);
- } else {
- if (xf86GetOptValInteger(R128Options,
- OPTION_VERT_SIZE, &(info->vbSize))) {
- if (info->vbSize < 1) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Illegal vertex buffers list size: %d MB\n",
- info->vbSize);
- return FALSE;
- }
- }
-
- if (xf86GetOptValInteger(R128Options,
- OPTION_VBUF_SIZE, &(info->vbBufSize))) {
- if (info->vbBufSize < 1024) { /* FIXME: 1024 is arbitrary */
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Illegal individual vertex buffer size: %d bytes\n",
- info->vbBufSize);
- return FALSE;
- }
- }
}
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using %d MB for vertex buffers\n", info->vbSize);
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Using %d byte vertex buffers\n", info->vbBufSize);
-
if (xf86GetOptValInteger(R128Options, OPTION_USEC_TIMEOUT,
&(info->CCEusecTimeout))) {
/* This option checked by the R128 DRM kernel module */
@@ -1496,30 +1520,45 @@ static Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
}
if (!info->FBDev)
- if (!R128PreInitInt10(pScrn)) goto fail;
+ if (!R128PreInitInt10(pScrn)) goto fail;
- if (!R128PreInitConfig(pScrn)) goto fail;
+ if (!R128PreInitConfig(pScrn)) goto fail;
- if (!R128GetPLLParameters(pScrn)) goto fail;
+ if (!R128GetBIOSParameters(pScrn)) goto fail;
- if (!R128PreInitDDC(pScrn)) goto fail;
+ if (!R128GetPLLParameters(pScrn)) goto fail;
- if (!R128PreInitGamma(pScrn)) goto fail;
+ if (!R128PreInitDDC(pScrn)) goto fail;
- if (!R128PreInitModes(pScrn)) goto fail;
+ if (!R128PreInitGamma(pScrn)) goto fail;
- if (!R128PreInitCursor(pScrn)) goto fail;
+ if (!R128PreInitModes(pScrn)) goto fail;
- if (!R128PreInitAccel(pScrn)) goto fail;
+ if (!R128PreInitCursor(pScrn)) goto fail;
+
+ if (!R128PreInitAccel(pScrn)) goto fail;
#ifdef XF86DRI
- if (!R128PreInitDRI(pScrn)) goto fail;
+ if (!R128PreInitDRI(pScrn)) goto fail;
#endif
+ /* Free the video bios (if applicable) */
+ if (info->VBIOS) {
+ xfree(info->VBIOS);
+ info->VBIOS = NULL;
+ }
+
return TRUE;
fail:
/* Pre-init failed. */
+
+ /* Free the video bios (if applicable) */
+ if (info->VBIOS) {
+ xfree(info->VBIOS);
+ info->VBIOS = NULL;
+ }
+
vgaHWFreeHWRec(pScrn);
R128FreeRec(pScrn);
return FALSE;
@@ -1616,6 +1655,7 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
miGetDefaultVisualMask(pScrn->depth),
pScrn->rgbBits,
pScrn->defaultVisual)) return FALSE;
+ miSetPixmapDepths ();
#ifdef XF86DRI
/* Setup DRI after visuals have been
@@ -1623,10 +1663,31 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
called. cfbScreenInit will eventually
call the driver's InitGLXVisuals call
back. */
- if (!xf86ReturnOptValBool(R128Options, OPTION_NOACCEL, FALSE))
- info->directRenderingEnabled = R128DRIScreenInit(pScreen);
- else
- info->directRenderingEnabled = FALSE;
+ {
+ /* FIXME: When we move to dynamic allocation of back and depth
+ buffers, we will want to revisit the following check for 3
+ times the virtual size of the screen below. */
+ int width_bytes = (pScrn->displayWidth *
+ info->CurrentLayout.pixel_bytes);
+ int maxy = info->FbMapSize / width_bytes;
+
+ if (!xf86ReturnOptValBool(R128Options, OPTION_NOACCEL, FALSE) &&
+ (maxy > pScrn->virtualY * 3)
+#if 0
+ /* FIXME: Disable 3D support for FPs until it is tested */
+ && !info->HasPanelRegs
+#endif
+ ) {
+ info->directRenderingEnabled = R128DRIScreenInit(pScreen);
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Static buffer allocation failed -- "
+ "need at least %d kB video memory\n",
+ (pScrn->displayWidth * pScrn->virtualY *
+ info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024);
+ info->directRenderingEnabled = FALSE;
+ }
+ }
#endif
#ifdef USE_FB
@@ -1635,6 +1696,9 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
pScrn->bitsPerPixel))
return FALSE;
+#ifdef RENDER
+ fbPictureInit (pScreen, 0, 0);
+#endif
#else
switch (pScrn->bitsPerPixel) {
case 8:
@@ -1749,6 +1813,31 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
int maxy = info->FbMapSize / width_bytes;
int l;
+ switch (info->CCEMode) {
+ case R128_DEFAULT_CCE_PIO_MODE:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n");
+ break;
+ case R128_DEFAULT_CCE_BM_MODE:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n");
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n");
+ break;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB AGP aperture\n", info->agpSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB for the ring buffer\n", info->ringSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB for vertex buffers\n", info->vbSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB for indirect buffers\n", info->indSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB for AGP textures\n", info->agpTexSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d byte vertex buffers\n", info->vbBufSize);
+
/* Allocate the shared back buffer */
if ((fbarea = xf86AllocateOffscreenArea(pScreen,
pScrn->virtualX,
@@ -1895,7 +1984,8 @@ static Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
/* DPMS setup */
#ifdef DPMSExtension
- xf86DPMSInit(pScreen, R128DisplayPowerManagementSet, 0);
+ if (!info->HasPanelRegs || info->CRTOnly)
+ xf86DPMSInit(pScreen, R128DisplayPowerManagementSet, 0);
#endif
/* Xv setup */
@@ -1983,6 +2073,7 @@ static void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
/* Write flat panel registers */
static void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
{
+ CARD32 tmp;
R128MMIO_VARS();
OUTREG(R128_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
@@ -1994,8 +2085,23 @@ static void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl);
OUTREG(R128_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid);
OUTREG(R128_FP_VERT_STRETCH, restore->fp_vert_stretch);
- OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
OUTREG(R128_TMDS_CRC, restore->tmds_crc);
+
+ tmp = INREG(R128_LVDS_GEN_CNTL);
+ if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) ==
+ (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) {
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
+ } else {
+ if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) {
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl & ~R128_LVDS_BLON);
+ usleep(R128PTR(pScrn)->PanelPwrDly * 1000);
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
+ } else {
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON);
+ usleep(R128PTR(pScrn)->PanelPwrDly * 1000);
+ OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
+ }
+ }
}
static void R128PLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn)
@@ -2082,12 +2188,15 @@ static void R128RestorePalette(ScrnInfoPtr pScrn, R128SavePtr restore)
/* Write out state to define a new video mode. */
static void R128RestoreMode(ScrnInfoPtr pScrn, R128SavePtr restore)
{
+ R128InfoPtr info = R128PTR(pScrn);
+
R128TRACE(("R128RestoreMode(%p)\n", restore));
R128RestoreCommonRegisters(pScrn, restore);
R128RestoreCrtcRegisters(pScrn, restore);
- if (R128PTR(pScrn)->HasPanelRegs && R128PTR(pScrn)->EnableFP)
+ if (info->HasPanelRegs)
R128RestoreFPRegisters(pScrn, restore);
- R128RestorePLLRegisters(pScrn, restore);
+ if (!info->HasPanelRegs || info->CRTOnly)
+ R128RestorePLLRegisters(pScrn, restore);
R128RestoreDDARegisters(pScrn, restore);
R128RestorePalette(pScrn, restore);
}
@@ -2195,7 +2304,7 @@ static void R128SaveMode(ScrnInfoPtr pScrn, R128SavePtr save)
R128SaveCommonRegisters(pScrn, save);
R128SaveCrtcRegisters(pScrn, save);
- if (R128PTR(pScrn)->HasPanelRegs && R128PTR(pScrn)->EnableFP)
+ if (R128PTR(pScrn)->HasPanelRegs)
R128SaveFPRegisters(pScrn, save);
R128SavePLLRegisters(pScrn, save);
R128SaveDDARegisters(pScrn, save);
@@ -2294,14 +2403,17 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
int hsync_fudge;
int vsync_wid;
int bytpp;
+ int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 };
+ int hsync_fudge_fp[] = { 0x12, 0x11, 0x09, 0x09, 0x05, 0x05 };
+ int hsync_fudge_fp_crt[] = { 0x12, 0x10, 0x08, 0x08, 0x04, 0x04 };
switch (info->CurrentLayout.pixel_code) {
- case 4: format = 1; bytpp = 0; hsync_fudge = 0; break;
- case 8: format = 2; bytpp = 1; hsync_fudge = 18; break;
- case 15: format = 3; bytpp = 2; hsync_fudge = 9; break; /* 555 */
- case 16: format = 4; bytpp = 2; hsync_fudge = 9; break; /* 565 */
- case 24: format = 5; bytpp = 3; hsync_fudge = 6; break; /* RGB */
- case 32: format = 6; bytpp = 4; hsync_fudge = 5; break; /* xRGB */
+ case 4: format = 1; bytpp = 0; break;
+ case 8: format = 2; bytpp = 1; break;
+ case 15: format = 3; bytpp = 2; break; /* 555 */
+ case 16: format = 4; bytpp = 2; break; /* 565 */
+ case 24: format = 5; bytpp = 3; break; /* RGB */
+ case 32: format = 6; bytpp = 4; break; /* xRGB */
default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Unsupported pixel depth (%d)\n", info->CurrentLayout.bitsPerPixel);
@@ -2309,6 +2421,10 @@ static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
}
R128TRACE(("Format = %d (%d bytes per pixel)\n", format, bytpp));
+ if (info->HasPanelRegs)
+ if (info->CRTOnly) hsync_fudge = hsync_fudge_fp_crt[format-1];
+ else hsync_fudge = hsync_fudge_fp[format-1];
+ else hsync_fudge = hsync_fudge_default[format-1];
save->crtc_gen_cntl = (R128_CRTC_EXT_DISP_EN
| R128_CRTC_EN
@@ -2379,7 +2495,6 @@ static void R128InitFPRegisters(ScrnInfoPtr pScrn, R128SavePtr orig,
int xres = mode->CrtcHDisplay;
int yres = mode->CrtcVDisplay;
float Hratio, Vratio;
- int disp_end;
if (info->CRTOnly) {
save->crtc_ext_cntl |= R128_CRTC_CRT_ON;
@@ -2393,7 +2508,8 @@ static void R128InitFPRegisters(ScrnInfoPtr pScrn, R128SavePtr orig,
save->fp_gen_cntl |= (R128_FP_SEL_CRTC2 |
R128_FP_CRTC_DONT_SHADOW_VPAR);
save->fp_panel_cntl = orig->fp_panel_cntl & ~R128_FP_DIGON;
- save->lvds_gen_cntl = orig->lvds_gen_cntl & ~R128_LVDS_ON;
+ save->lvds_gen_cntl = orig->lvds_gen_cntl & ~(R128_LVDS_ON |
+ R128_LVDS_BLON);
return;
}
@@ -2404,35 +2520,39 @@ static void R128InitFPRegisters(ScrnInfoPtr pScrn, R128SavePtr orig,
Vratio = (float)yres/(float)info->PanelYRes;
save->fp_horz_stretch =
- (((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX))
+ (((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5))
& R128_HORZ_STRETCH_RATIO_MASK) << R128_HORZ_STRETCH_RATIO_SHIFT) |
(orig->fp_horz_stretch & (R128_HORZ_PANEL_SIZE |
R128_HORZ_FP_LOOP_STRETCH |
R128_HORZ_STRETCH_RESERVED)));
- if (Hratio != 1.0) save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND |
- R128_HORZ_STRETCH_ENABLE);
+ save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN;
+ if (Hratio == 1.0) save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND |
+ R128_HORZ_STRETCH_ENABLE);
+ else save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND |
+ R128_HORZ_STRETCH_ENABLE);
save->fp_vert_stretch =
- (((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX))
+ (((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX + 0.5))
& R128_VERT_STRETCH_RATIO_MASK) << R128_VERT_STRETCH_RATIO_SHIFT) |
(orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE |
- R128_VERT_STRETCH_RESERVED |
- R128_VERT_STRETCH_BLEND)));
- if (Vratio == 1.0) save->fp_vert_stretch &= ~R128_VERT_STRETCH_ENABLE;
- else save->fp_vert_stretch |= R128_VERT_STRETCH_ENABLE;
-
- save->fp_gen_cntl = ((orig->fp_gen_cntl & ~(R128_FP_SEL_CRTC2 |
- R128_FP_CRTC_USE_SHADOW_VEND |
- R128_FP_CRTC_HORZ_DIV2_EN |
- R128_FP_CRTC_HOR_CRT_DIV2_DIS |
- R128_FP_USE_SHADOW_EN)) |
- R128_FP_CRTC_DONT_SHADOW_VPAR |
- R128_FP_TDMS_EN);
+ R128_VERT_STRETCH_RESERVED)));
+ save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN;
+ if (Vratio == 1.0) save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE |
+ R128_VERT_STRETCH_BLEND);
+ else save->fp_vert_stretch |= (R128_VERT_STRETCH_ENABLE |
+ R128_VERT_STRETCH_BLEND);
+
+ save->fp_gen_cntl = (orig->fp_gen_cntl & ~(R128_FP_SEL_CRTC2 |
+ R128_FP_CRTC_USE_SHADOW_VEND |
+ R128_FP_CRTC_HORZ_DIV2_EN |
+ R128_FP_CRTC_HOR_CRT_DIV2_DIS |
+ R128_FP_USE_SHADOW_EN));
+ if (orig->fp_gen_cntl & R128_FP_DETECT_SENSE) {
+ save->fp_gen_cntl |= (R128_FP_CRTC_DONT_SHADOW_VPAR |
+ R128_FP_TDMS_EN);
+ }
+
save->fp_panel_cntl = orig->fp_panel_cntl;
- save->fp_crtc_h_total_disp = orig->fp_crtc_h_total_disp;
- save->fp_crtc_v_total_disp = orig->fp_crtc_v_total_disp;
- save->fp_h_sync_strt_wid = orig->fp_h_sync_strt_wid;
- save->fp_v_sync_strt_wid = orig->fp_v_sync_strt_wid;
save->lvds_gen_cntl = orig->lvds_gen_cntl;
save->tmds_crc = orig->tmds_crc;
@@ -2446,51 +2566,18 @@ static void R128InitFPRegisters(ScrnInfoPtr pScrn, R128SavePtr orig,
save->dac_cntl |= R128_DAC_CRT_SEL_CRTC2;
save->crtc2_gen_cntl = 0;
+ /* WARNING: Be careful about turning on the flat panel */
+#if 1
+ save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON);
+#else
save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON);
save->fp_gen_cntl |= (R128_FP_FPON);
+#endif
- save->crtc_gen_cntl &= ~(R128_CRTC_DBL_SCAN_EN |
- R128_CRTC_INTERLACE_EN |
- R128_CRTC_CSYNC_EN |
- R128_CRTC_CUR_EN |
- R128_CRTC_CUR_MODE_MASK |
- R128_CRTC_ICON_EN |
- R128_CRTC_EXT_DISP_EN |
- R128_CRTC_EN |
- R128_CRTC_DISP_REQ_EN_B);
- save->crtc_gen_cntl |= R128_CRTC_EXT_DISP_EN | R128_CRTC_EN;
-
- disp_end = xres/8 - 1;
- save->crtc_h_total_disp = ((disp_end << R128_CRTC_H_DISP_SHIFT) |
- (disp_end + info->PanelHNonVis));
-
- save->crtc_h_sync_strt_wid &= ~(R128_CRTC_H_SYNC_STRT_PIX |
- R128_CRTC_H_SYNC_STRT_CHAR |
- R128_CRTC_H_SYNC_WID);
- save->crtc_h_sync_strt_wid |=
- (disp_end + info->PanelHOverPlus) << R128_CRTC_H_SYNC_STRT_CHAR_SHIFT;
- switch (info->CurrentLayout.pixel_code) {
- /* Adjustments are from ATI */
- case 8: save->crtc_h_sync_strt_wid |= 2; break;
- case 15:
- case 16: save->crtc_h_sync_strt_wid |= 1; break;
- case 24: save->crtc_h_sync_strt_wid |= 6; break;
- case 32: save->crtc_h_sync_strt_wid |= 5; break;
- }
- save->crtc_h_sync_strt_wid |=
- info->PanelHSyncWidth << R128_CRTC_H_SYNC_WID_SHIFT;
- save->crtc_h_sync_strt_wid |= R128_CRTC_H_SYNC_POL;
-
- disp_end = yres - 1;
- save->crtc_v_total_disp = ((disp_end << R128_CRTC_V_DISP_SHIFT) |
- (disp_end + info->PanelVNonVis));
-
- save->crtc_v_sync_strt_wid &= ~(R128_CRTC_V_SYNC_STRT |
- R128_CRTC_V_SYNC_WID);
- save->crtc_v_sync_strt_wid |= (disp_end + info->PanelVOverPlus);
- save->crtc_v_sync_strt_wid |=
- info->PanelVSyncWidth << R128_CRTC_V_SYNC_WID_SHIFT;
- save->crtc_v_sync_strt_wid |= R128_CRTC_V_SYNC_POL;
+ save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
+ save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
+ save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
+ save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
}
/* Define PLL registers for requested video mode. */
@@ -2674,7 +2761,7 @@ static Bool R128Init(ScrnInfoPtr pScrn, DisplayModePtr mode, R128SavePtr save)
R128InitCommonRegisters(save, mode, info);
if (!R128InitCrtcRegisters(pScrn, save, mode, info)) return FALSE;
- if (info->HasPanelRegs && info->EnableFP)
+ if (info->HasPanelRegs)
R128InitFPRegisters(pScrn, &info->SavedReg, save, mode, info);
R128InitPLLRegisters(pScrn, save, mode, &info->pll, dot_clock);
if (!R128InitDDARegisters(pScrn, save, mode, &info->pll, info))
@@ -2729,6 +2816,51 @@ Bool R128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
static int R128ValidMode(int scrnIndex, DisplayModePtr mode,
Bool verbose, int flag)
{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ R128InfoPtr info = R128PTR(pScrn);
+
+ if (info->HasPanelRegs) {
+ if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE;
+ if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN;
+ }
+
+ if (info->HasPanelRegs && !info->CRTOnly && info->VBIOS) {
+ int i;
+ for (i = info->FPBIOSstart+64; R128_BIOS16(i) != 0; i += 2) {
+ int j = R128_BIOS16(i);
+
+ if (mode->CrtcHDisplay == R128_BIOS16(j) &&
+ mode->CrtcVDisplay == R128_BIOS16(j+2)) {
+ /* Assume we are using expanded mode */
+ if (R128_BIOS16(j+5)) j = R128_BIOS16(j+5);
+ else j += 9;
+
+ mode->Clock = (CARD32)R128_BIOS16(j) * 10;
+
+ mode->HDisplay = mode->CrtcHDisplay =
+ ((R128_BIOS16(j+10) & 0x01ff)+1)*8;
+ mode->HSyncStart = mode->CrtcHSyncStart =
+ ((R128_BIOS16(j+12) & 0x01ff)+1)*8;
+ mode->HSyncEnd = mode->CrtcHSyncEnd =
+ mode->CrtcHSyncStart + (R128_BIOS8(j+14) & 0x1f);
+ mode->HTotal = mode->CrtcHTotal =
+ ((R128_BIOS16(j+8) & 0x01ff)+1)*8;
+
+ mode->VDisplay = mode->CrtcVDisplay =
+ (R128_BIOS16(j+17) & 0x07ff)+1;
+ mode->VSyncStart = mode->CrtcVSyncStart =
+ (R128_BIOS16(j+19) & 0x07ff)+1;
+ mode->VSyncEnd = mode->CrtcVSyncEnd =
+ mode->CrtcVSyncStart + ((R128_BIOS16(j+19) >> 11) & 0x1f);
+ mode->VTotal = mode->CrtcVTotal =
+ (R128_BIOS16(j+15) & 0x07ff)+1;
+
+ return MODE_OK;
+ }
+ }
+ return MODE_NOMODE;
+ }
+
return MODE_OK;
}
@@ -2768,7 +2900,7 @@ static Bool R128EnterVT(int scrnIndex, int flags)
R128TRACE(("R128EnterVT\n"));
#ifdef XF86DRI
if (R128PTR(pScrn)->directRenderingEnabled) {
- R128CCEStart(pScrn);
+ drmR128StartCCE(info->drmFD);
DRIUnlock(pScrn->pScreen);
}
#endif
@@ -2794,7 +2926,7 @@ static void R128LeaveVT(int scrnIndex, int flags)
#ifdef XF86DRI
if (R128PTR(pScrn)->directRenderingEnabled) {
DRILock(pScrn->pScreen, 0);
- R128CCEStop(pScrn);
+ drmR128StopCCE(info->drmFD);
}
#endif
R128SavePalette(pScrn, save);
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h
index 788646e0c..efdbec119 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h,v 1.11 2000/07/01 01:40:46 martin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/r128/r128_reg.h,v 1.13 2000/09/13 15:47:32 martin Exp $ */
/**************************************************************************
Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
@@ -538,6 +538,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_FP_GEN_CNTL 0x0284
# define R128_FP_FPON (1 << 0)
# define R128_FP_TDMS_EN (1 << 2)
+# define R128_FP_DETECT_SENSE (1 << 8)
# define R128_FP_SEL_CRTC2 (1 << 13)
# define R128_FP_CRTC_DONT_SHADOW_VPAR (1 << 16)
# define R128_FP_CRTC_USE_SHADOW_VEND (1 << 18)
@@ -555,7 +556,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R128_HORZ_STRETCH_BLEND (1 << 25)
# define R128_HORZ_STRETCH_ENABLE (1 << 26)
# define R128_HORZ_FP_LOOP_STRETCH (0x7 << 27)
-# define R128_HORZ_STRETCH_RESERVED 0xc0000000
+# define R128_HORZ_STRETCH_RESERVED (1 << 30)
+# define R128_HORZ_AUTO_RATIO_FIX_EN (1 << 31)
#define R128_FP_PANEL_CNTL 0x0288
# define R128_FP_DIGON (1 << 0)
@@ -570,6 +572,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R128_VERT_STRETCH_ENABLE (1 << 24)
# define R128_VERT_STRETCH_LINEREP (0 << 25)
# define R128_VERT_STRETCH_BLEND (1 << 25)
+# define R128_VERT_AUTO_RATIO_EN (1 << 26)
# define R128_VERT_STRETCH_RESERVED 0xf8e00000
#define R128_GEN_INT_CNTL 0x0040
@@ -654,8 +657,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_LEAD_BRES_LNTH 0x161c
#define R128_LEAD_BRES_LNTH_SUB 0x1624
#define R128_LVDS_GEN_CNTL 0x02d0
-# define R128_LVDS_ON (1 << 0)
-# define R128_LVDS_SEL_CRTC2 (1 << 23)
+# define R128_LVDS_ON (1 << 0)
+# define R128_LVDS_BLON (1 << 19)
+# define R128_LVDS_SEL_CRTC2 (1 << 23)
+# define R128_HSYNC_DELAY_SHIFT 28
+# define R128_HSYNC_DELAY_MASK (0xf << 28)
#define R128_MAX_LATENCY 0x0f3f /* PCI */
#define R128_MCLK_CNTL 0x000f /* PLL */
@@ -734,15 +740,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R128_SC_BOTTOM 0x164c
#define R128_SC_BOTTOM_RIGHT 0x16f0
#define R128_SC_BOTTOM_RIGHT_C 0x1c8c
-# define R128_SC_RIGHT_DEFAULT (0x1fff << 0)
-# define R128_SC_BOTTOM_DEFAULT (0x1fff << 16)
#define R128_SC_LEFT 0x1640
#define R128_SC_RIGHT 0x1644
#define R128_SC_TOP 0x1648
#define R128_SC_TOP_LEFT 0x16ec
#define R128_SC_TOP_LEFT_C 0x1c88
-# define R128_SC_LEFT_DEFAULT (0x0 << 0)
-# define R128_SC_TOP_DEFAULT (0x0 << 16)
#define R128_SEQ8_DATA 0x03c5 /* VGA */
#define R128_SEQ8_IDX 0x03c4 /* VGA */
#define R128_SNAPSHOT_F_COUNT 0x0244
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h
index 6863ff93e..ccd9afb1b 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/r128/r128_sarea.h
@@ -160,8 +160,6 @@ typedef struct {
int texAge[R128_NR_TEX_HEAPS];
int ctxOwner; /* last context to upload state */
-
- int ringWrite; /* current ring buffer write index */
} R128SAREAPriv, *R128SAREAPrivPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
index 5a979e1cb..7bf24afef 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
@@ -11,11 +11,11 @@
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -23,7 +23,7 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
- *
+ *
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
*
@@ -357,11 +357,15 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_I810_DOCOPY DRM_IO ( 0x48)
/* Rage 128 specific ioctls */
-#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
-#define DRM_IOCTL_R128_RESET DRM_IO( 0x41)
-#define DRM_IOCTL_R128_FLUSH DRM_IO( 0x42)
-#define DRM_IOCTL_R128_IDLE DRM_IO( 0x43)
-#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x44, drm_r128_packet_t)
-#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x45, drm_r128_vertex_t)
+#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
+#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
+#define DRM_IOCTL_R128_CCE_STOP DRM_IO( 0x42)
+#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
+#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
+#define DRM_IOCTL_R128_RESET DRM_IO( 0x45)
+#define DRM_IOCTL_R128_SWAP DRM_IO( 0x46)
+#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x47, drm_r128_clear_t)
+#define DRM_IOCTL_R128_VERTEX DRM_IOWR(0x48, drm_r128_vertex_t)
+#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x49, drm_r128_packet_t)
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_bufs.c
index 0053c0feb..bf3dff7fb 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_bufs.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_bufs.c
@@ -235,7 +235,7 @@ int r128_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
if (dma->flags & _DRM_DMA_USE_AGP) {
drm_map_t *map;
- map = dev_priv->agp_vertbufs;
+ map = dev_priv->vertex_buffers;
if (!map) {
retcode = -EINVAL;
goto done;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c
index d9f988ed1..60a0fef8e 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c
@@ -1,4 +1,4 @@
-/* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*-
+/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*-
* Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
*
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
@@ -39,6 +39,51 @@
/* FIXME: Temporary CCE packet buffer */
u32 r128_cce_buffer[(1 << 14)] __attribute__ ((aligned (32)));
+/* CCE microcode (from ATI) */
+static u32 r128_cce_microcode[] = {
+ 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0,
+ 1617039951, 0, 774592877, 0, 1987540286, 0, 2307490946U, 0,
+ 599558925, 0, 589505315, 0, 596487092, 0, 589505315, 1,
+ 11544576, 1, 206848, 1, 311296, 1, 198656, 2, 912273422, 11,
+ 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, 28,
+ 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9,
+ 30, 1, 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656,
+ 1, 15630, 1, 51200, 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1,
+ 15717, 1, 15718, 2, 43, 1, 15936948, 1, 570480831, 1, 14715071,
+ 12, 322123831, 1, 33953125, 12, 55, 1, 33559908, 1, 15718, 2,
+ 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, 509952, 1,
+ 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1,
+ 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1,
+ 15975928, 1, 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2,
+ 268449859, 2, 10307, 12, 176, 1, 15734, 1, 15735, 1, 15630, 1,
+ 15631, 1, 5253120, 6, 3145810, 16, 2150645232U, 1, 15864, 2, 82,
+ 1, 343310, 1, 1064207, 2, 3145813, 1, 15728, 1, 7817, 1, 15729,
+ 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, 1, 16008,
+ 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0,
+ 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1,
+ 180224, 1, 103824738, 2, 112, 2, 3145839, 0, 536885440, 1,
+ 114880, 14, 125, 12, 206975, 1, 33559995, 12, 198784, 0,
+ 33570236, 1, 15803, 0, 15804, 3, 294912, 1, 294912, 3, 442370,
+ 1, 11544576, 0, 811612160, 1, 12593152, 1, 11536384, 1,
+ 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, 14793,
+ 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1,
+ 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1,
+ 114880, 14, 159, 12, 198784, 1, 1109409213, 12, 198783, 1,
+ 1107312059, 12, 198784, 1, 1109409212, 2, 162, 1, 1075854781, 1,
+ 1073757627, 1, 1075854780, 1, 540672, 1, 10485760, 6, 3145894,
+ 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, 0, 0, 256, 14,
+ 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, 1,
+ 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1,
+ 33560360, 1, 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1,
+ 409611, 9, 188, 0, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
#define DO_REMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size)
@@ -68,9 +113,6 @@ int R128_READ_PLL(drm_device_t *dev, int addr)
return R128_READ(R128_CLOCK_CNTL_DATA);
}
-/* GH: This should really use my PIII mb() patch */
-#define r128_flush_write_combine() mb()
-
static void r128_status(drm_device_t *dev)
{
@@ -86,194 +128,15 @@ static void r128_status(drm_device_t *dev)
(unsigned int)R128_READ(R128_PM4_BUFFER_DL_RPTR));
}
-static int r128_do_cleanup_cce(drm_device_t *dev)
-{
- if (dev->dev_private) {
- drm_r128_private_t *dev_priv = dev->dev_private;
-
- if (!dev_priv->is_pci) {
- DO_REMAPFREE(dev_priv->agp_ring);
- DO_REMAPFREE(dev_priv->agp_read_ptr);
- DO_REMAPFREE(dev_priv->agp_vertbufs);
- DO_REMAPFREE(dev_priv->agp_indbufs);
- DO_REMAPFREE(dev_priv->agp_textures);
- }
-
- drm_free(dev->dev_private, sizeof(drm_r128_private_t),
- DRM_MEM_DRIVER);
- dev->dev_private = NULL;
- }
-
- return 0;
-}
-
-static int r128_do_init_cce(drm_device_t *dev, drm_r128_init_t *init)
-{
- drm_r128_private_t *dev_priv;
- int i;
-
- dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER);
- if (dev_priv == NULL) return -ENOMEM;
- dev->dev_private = (void *)dev_priv;
-
- memset(dev_priv, 0, sizeof(drm_r128_private_t));
-
- dev_priv->is_pci = init->is_pci;
-
- dev_priv->usec_timeout = init->usec_timeout;
- if (dev_priv->usec_timeout < 1 ||
- dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT) {
- drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
- dev->dev_private = NULL;
- return -EINVAL;
- }
-
- dev_priv->cce_mode = init->cce_mode;
- dev_priv->cce_fifo_size = init->cce_fifo_size;
- dev_priv->cce_is_bm_mode =
- ((init->cce_mode == R128_PM4_192BM) ||
- (init->cce_mode == R128_PM4_128BM_64INDBM) ||
- (init->cce_mode == R128_PM4_64BM_128INDBM) ||
- (init->cce_mode == R128_PM4_64BM_64VCBM_64INDBM));
- dev_priv->cce_secure = init->cce_secure;
-
- dev_priv->cce_buffer = r128_cce_buffer;
-
- if (dev_priv->cce_is_bm_mode && dev_priv->is_pci) {
- drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
- dev->dev_private = NULL;
- return -EINVAL;
- }
-
- for (i = 0; i < dev->map_count; i++) {
- if (dev->maplist[i]->type == _DRM_SHM) {
- dev_priv->sarea = dev->maplist[i];
- break;
- }
- }
-
- DO_FIND_MAP(dev_priv->fb, init->fb_offset);
- if (!dev_priv->is_pci) {
- DO_FIND_MAP(dev_priv->agp_ring, init->agp_ring_offset);
- DO_FIND_MAP(dev_priv->agp_read_ptr, init->agp_read_ptr_offset);
- DO_FIND_MAP(dev_priv->agp_vertbufs, init->agp_vertbufs_offset);
- DO_FIND_MAP(dev_priv->agp_indbufs, init->agp_indbufs_offset);
- DO_FIND_MAP(dev_priv->agp_textures, init->agp_textures_offset);
- }
- DO_FIND_MAP(dev_priv->mmio, init->mmio_offset);
-
- dev_priv->sarea_priv =
- (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
- init->sarea_priv_offset);
-
- if (!dev_priv->is_pci) {
- DO_REMAP(dev_priv->agp_ring);
- DO_REMAP(dev_priv->agp_read_ptr);
- DO_REMAP(dev_priv->agp_vertbufs);
-#if 0
- DO_REMAP(dev_priv->agp_indirectbufs);
- DO_REMAP(dev_priv->agp_textures);
-#endif
-
- dev_priv->ring_size = init->ring_size;
- dev_priv->ring_sizel2qw = drm_order(init->ring_size/8);
- dev_priv->ring_entries = init->ring_size/sizeof(u32);
- dev_priv->ring_read_ptr = ((__volatile__ u32 *)
- dev_priv->agp_read_ptr->handle);
- dev_priv->ring_start = (u32 *)dev_priv->agp_ring->handle;
- dev_priv->ring_end = ((u32 *)dev_priv->agp_ring->handle
- + dev_priv->ring_entries);
- }
-
- dev_priv->submit_age = 0;
- R128_WRITE(R128_VB_AGE_REG, dev_priv->submit_age);
-
- return 0;
-}
-
-
/* ================================================================
* GH: Done from here down
*/
-int r128_init_cce( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_r128_init_t init;
-
- if ( copy_from_user( &init, (drm_r128_init_t *)arg, sizeof(init) ) )
- return -EFAULT;
-
- switch ( init.func ) {
- case R128_INIT_CCE:
- return r128_do_init_cce( dev, &init );
- case R128_CLEANUP_CCE:
- return r128_do_cleanup_cce( dev );
- }
-
- return -EINVAL;
-}
/* ================================================================
- * Freelist management
- */
-
-void r128_freelist_reset( drm_device_t *dev )
-{
- drm_device_dma_t *dma = dev->dma;
- int i;
-
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
- drm_buf_t *buf = dma->buflist[i];
- drm_r128_buf_priv_t *buf_priv = buf->dev_private;
- buf_priv->age = 0;
- }
-}
-
-drm_buf_t *r128_freelist_get( drm_device_t *dev )
-{
- drm_device_dma_t *dma = dev->dma;
- drm_r128_private_t *dev_priv = dev->dev_private;
- drm_r128_buf_priv_t *buf_priv;
- drm_buf_t *buf;
- int i, t;
-
- /* FIXME: Optimize -- use freelist code */
-
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
- buf = dma->buflist[i];
- buf_priv = buf->dev_private;
- if ( buf->pid == 0 ) return buf;
- }
-
- for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
- u32 done_age = R128_READ( R128_VB_AGE_REG );
-
- for ( i = 0 ; i < dma->buf_count ; i++ ) {
- buf = dma->buflist[i];
- buf_priv = buf->dev_private;
- if ( buf->pending && buf_priv->age <= done_age ) {
- /* The buffer has been processed, so it
- * can now be used.
- */
- buf->pending = 0;
- return buf;
- }
- }
- udelay( 1 );
- }
-
- r128_status( dev );
- return NULL;
-}
-
-
-/* ================================================================
- * Engine control
+ * Engine, FIFO control
*/
static int r128_do_pixcache_flush( drm_r128_private_t *dev_priv )
@@ -306,7 +169,7 @@ static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries )
return -EBUSY;
}
-int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
+static int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
{
int i, ret;
@@ -323,6 +186,97 @@ int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
return -EBUSY;
}
+
+/* ================================================================
+ * CCE control, initialization
+ */
+
+/* Load the microcode for the CCE */
+static void r128_cce_load_microcode( drm_r128_private_t *dev_priv )
+{
+ int i;
+
+ r128_do_wait_for_idle( dev_priv );
+
+ R128_WRITE( R128_PM4_MICROCODE_ADDR, 0 );
+ for ( i = 0 ; i < 256 ; i++ ) {
+ R128_WRITE( R128_PM4_MICROCODE_DATAH,
+ r128_cce_microcode[i * 2] );
+ R128_WRITE( R128_PM4_MICROCODE_DATAL,
+ r128_cce_microcode[i * 2 + 1] );
+ }
+}
+
+/* Flush any pending commands to the CCE. This should only be used just
+ * prior to a wait for idle, as it informs the engine that the command
+ * stream is ending.
+ */
+static void r128_do_cce_flush( drm_r128_private_t *dev_priv )
+{
+ u32 tmp;
+
+ tmp = R128_READ( R128_PM4_BUFFER_DL_WPTR ) | R128_PM4_BUFFER_DL_DONE;
+ R128_WRITE( R128_PM4_BUFFER_DL_WPTR, tmp );
+}
+
+/* Wait for the CCE to go idle.
+ */
+static int r128_do_cce_idle( drm_r128_private_t *dev_priv )
+{
+ int i;
+
+ for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+ if ( *dev_priv->ring.head == dev_priv->ring.tail ) {
+ int pm4stat = R128_READ( R128_PM4_STAT );
+ if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >=
+ dev_priv->cce_fifo_size ) &&
+ !(pm4stat & (R128_PM4_BUSY |
+ R128_PM4_GUI_ACTIVE)) ) {
+ return r128_do_pixcache_flush( dev_priv );
+ }
+ }
+ udelay( 1 );
+ }
+
+ return -EBUSY;
+}
+
+/* Start the Concurrent Command Engine.
+ */
+static void r128_do_cce_start( drm_r128_private_t *dev_priv )
+{
+ r128_do_wait_for_idle( dev_priv );
+
+ R128_WRITE( R128_PM4_BUFFER_CNTL,
+ dev_priv->cce_mode | dev_priv->ring.size_l2qw );
+ R128_READ( R128_PM4_BUFFER_ADDR ); /* as per the sample code */
+ R128_WRITE( R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN );
+}
+
+/* Reset the Concurrent Command Engine. This will not flush any pending
+ * commangs, so you must wait for the CCE command stream to complete
+ * before calling this routine.
+ */
+static void r128_do_cce_reset( drm_r128_private_t *dev_priv )
+{
+ R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
+ R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
+ *dev_priv->ring.head = 0;
+ dev_priv->ring.tail = 0;
+}
+
+/* Stop the Concurrent Command Engine. This will not flush any pending
+ * commangs, so you must flush the command stream and wait for the CCE
+ * to go idle before calling this routine.
+ */
+static void r128_do_cce_stop( drm_r128_private_t *dev_priv )
+{
+ R128_WRITE( R128_PM4_MICRO_CNTL, 0 );
+ R128_WRITE( R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4 );
+}
+
+/* Reset the engine, and the CCE if it is currently running.
+ */
static int r128_do_engine_reset( drm_device_t *dev )
{
drm_r128_private_t *dev_priv = dev->dev_private;
@@ -350,146 +304,413 @@ static int r128_do_engine_reset( drm_device_t *dev )
R128_WRITE( R128_CLOCK_CNTL_INDEX, clock_cntl_index );
R128_WRITE( R128_GEN_RESET_CNTL, gen_reset_cntl );
- /* For CCE ring buffer only */
- if ( dev_priv->cce_is_bm_mode ) {
- R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
- R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
- *dev_priv->ring_read_ptr = 0;
- dev_priv->sarea_priv->ring_write = 0;
- }
+ /* Reset the CCE ring */
+ r128_do_cce_reset( dev_priv );
- /* Reset the CCE mode */
- r128_do_wait_for_idle( dev_priv );
- R128_WRITE( R128_PM4_BUFFER_CNTL,
- dev_priv->cce_mode | dev_priv->ring_sizel2qw );
- R128_READ( R128_PM4_BUFFER_ADDR ); /* as per the sample code */
- R128_WRITE( R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN );
+ if ( dev_priv->cce_running ) {
+ /* Start the CCE again */
+ r128_do_cce_start( dev_priv );
+ }
+ /* Reset any pending vertex, indirect buffers */
r128_freelist_reset( dev );
+
return 0;
}
-int r128_eng_reset( struct inode *inode, struct file *filp,
+static void r128_cce_init_ring_buffer( drm_device_t *dev )
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ u32 ring_start;
+ u32 tmp;
+
+ /* The manual (p. 2) says this address is in "VM space". This
+ * means it's an offset from the start of AGP space.
+ */
+ ring_start = dev_priv->cce_ring->offset - dev->agp->base;
+ R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET );
+
+ R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
+ R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
+
+ /* DL_RPTR_ADDR is a physical address in AGP space. */
+ *dev_priv->ring.head = 0;
+ R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
+ dev_priv->ring_rptr->offset );
+
+ /* Set watermark control */
+ R128_WRITE( R128_PM4_BUFFER_WM_CNTL,
+ ((R128_WATERMARK_L/4) << R128_WMA_SHIFT)
+ | ((R128_WATERMARK_M/4) << R128_WMB_SHIFT)
+ | ((R128_WATERMARK_N/4) << R128_WMC_SHIFT)
+ | ((R128_WATERMARK_K/64) << R128_WB_WM_SHIFT) );
+
+ /* Force read. Why? Because it's in the examples... */
+ R128_READ( R128_PM4_BUFFER_ADDR );
+
+ /* Turn on bus mastering */
+ tmp = R128_READ( R128_BUS_CNTL ) & ~R128_BUS_MASTER_DIS;
+ R128_WRITE( R128_BUS_CNTL, tmp );
+}
+
+static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
+{
+ drm_r128_private_t *dev_priv;
+ int i;
+
+ dev_priv = drm_alloc( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
+ if ( dev_priv == NULL )
+ return -ENOMEM;
+ dev->dev_private = (void *)dev_priv;
+
+ memset( dev_priv, 0, sizeof(drm_r128_private_t) );
+
+ dev_priv->is_pci = init->is_pci;
+
+ /* GH: We don't support PCI cards until PCI GART is implemented.
+ * Fail here so we can remove all checks for PCI cards around
+ * the CCE ring code.
+ */
+ if ( dev_priv->is_pci ) {
+ drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
+ dev->dev_private = NULL;
+ return -EINVAL;
+ }
+
+ dev_priv->usec_timeout = init->usec_timeout;
+ if ( dev_priv->usec_timeout < 1 ||
+ dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT ) {
+ drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
+ dev->dev_private = NULL;
+ return -EINVAL;
+ }
+
+ dev_priv->cce_mode = init->cce_mode;
+ dev_priv->cce_secure = init->cce_secure;
+
+ /* We don't support anything other than bus-mastering ring mode,
+ * but the ring can be in either AGP or PCI space for the ring
+ * read pointer.
+ */
+ if ( ( init->cce_mode != R128_PM4_192BM ) &&
+ ( init->cce_mode != R128_PM4_128BM_64INDBM ) &&
+ ( init->cce_mode != R128_PM4_64BM_128INDBM ) &&
+ ( init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM ) ) {
+ drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
+ dev->dev_private = NULL;
+ return -EINVAL;
+ }
+
+ switch ( init->cce_mode ) {
+ case R128_PM4_NONPM4:
+ dev_priv->cce_fifo_size = 0;
+ break;
+ case R128_PM4_192PIO:
+ case R128_PM4_192BM:
+ dev_priv->cce_fifo_size = 192;
+ break;
+ case R128_PM4_128PIO_64INDBM:
+ case R128_PM4_128BM_64INDBM:
+ dev_priv->cce_fifo_size = 128;
+ break;
+ case R128_PM4_64PIO_128INDBM:
+ case R128_PM4_64BM_128INDBM:
+ case R128_PM4_64PIO_64VCBM_64INDBM:
+ case R128_PM4_64BM_64VCBM_64INDBM:
+ case R128_PM4_64PIO_64VCPIO_64INDPIO:
+ dev_priv->cce_fifo_size = 64;
+ break;
+ }
+
+ dev_priv->fb_bpp = init->fb_bpp;
+ dev_priv->front_offset = init->front_offset;
+ dev_priv->front_pitch = init->front_pitch;
+ dev_priv->front_x = init->front_x;
+ dev_priv->front_y = init->front_y;
+ dev_priv->back_offset = init->back_offset;
+ dev_priv->back_pitch = init->back_pitch;
+ dev_priv->back_x = init->back_x;
+ dev_priv->back_y = init->back_y;
+
+ dev_priv->depth_bpp = init->depth_bpp;
+ dev_priv->back_offset = init->depth_offset;
+ dev_priv->back_pitch = init->depth_pitch;
+ dev_priv->back_x = init->depth_x;
+ dev_priv->back_y = init->depth_y;
+
+ /* FIXME: We want multiple shared areas, including one shared
+ * only by the X Server and kernel module.
+ */
+ for ( i = 0 ; i < dev->map_count ; i++ ) {
+ if ( dev->maplist[i]->type == _DRM_SHM ) {
+ dev_priv->sarea = dev->maplist[i];
+ break;
+ }
+ }
+
+ DO_FIND_MAP( dev_priv->fb, init->fb_offset );
+ DO_FIND_MAP( dev_priv->mmio, init->mmio_offset );
+
+ DO_FIND_MAP( dev_priv->cce_ring, init->ring_offset );
+ DO_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );
+
+ DO_FIND_MAP( dev_priv->vertex_buffers,
+ init->vertex_buffers_offset );
+ DO_FIND_MAP( dev_priv->indirect_buffers,
+ init->indirect_buffers_offset );
+
+ if ( !dev_priv->is_pci ) {
+ DO_FIND_MAP( dev_priv->agp_textures,
+ init->agp_textures_offset );
+ }
+
+ dev_priv->sarea_priv =
+ (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
+ init->sarea_priv_offset);
+
+ DO_REMAP( dev_priv->cce_ring );
+ DO_REMAP( dev_priv->ring_rptr );
+ DO_REMAP( dev_priv->vertex_buffers );
+ DO_REMAP( dev_priv->indirect_buffers );
+#if 0
+ if ( !dev_priv->is_pci ) {
+ DO_REMAP( dev_priv->agp_textures );
+ }
+#endif
+
+ dev_priv->ring.head = ((__volatile__ u32 *)
+ dev_priv->ring_rptr->handle);
+
+ dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle;
+ dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle
+ + init->ring_size / sizeof(u32));
+ dev_priv->ring.size = init->ring_size;
+ dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
+
+ dev_priv->ring.tail_mask =
+ (dev_priv->ring.size / sizeof(u32)) - 1;
+
+ dev_priv->submit_age = 0;
+ R128_WRITE( R128_VB_AGE_REG, dev_priv->submit_age );
+
+ DRM_INFO( "agp=0x%08x ring=0x%08x rtpr=0x%08x\n",
+ dev->agp->base,
+ dev_priv->cce_ring->offset,
+ dev_priv->ring_rptr->offset
+ );
+
+
+ r128_cce_init_ring_buffer( dev );
+ r128_cce_load_microcode( dev_priv );
+ r128_do_engine_reset( dev );
+
+ return 0;
+}
+
+static int r128_do_cleanup_cce( drm_device_t *dev )
+{
+ if ( dev->dev_private ) {
+ drm_r128_private_t *dev_priv = dev->dev_private;
+
+ DO_REMAPFREE( dev_priv->cce_ring );
+ DO_REMAPFREE( dev_priv->ring_rptr );
+ DO_REMAPFREE( dev_priv->vertex_buffers );
+ DO_REMAPFREE( dev_priv->indirect_buffers );
+#if 0
+ if ( !dev_priv->is_pci ) {
+ DO_REMAPFREE( dev_priv->agp_textures );
+ }
+#endif
+
+ drm_free( dev->dev_private, sizeof(drm_r128_private_t),
+ DRM_MEM_DRIVER );
+ dev->dev_private = NULL;
+ }
+
+ return 0;
+}
+
+int r128_cce_init( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_init_t init;
+
+ if ( copy_from_user( &init, (drm_r128_init_t *)arg, sizeof(init) ) )
+ return -EFAULT;
+
+ switch ( init.func ) {
+ case R128_INIT_CCE:
+ return r128_do_init_cce( dev, &init );
+ case R128_CLEANUP_CCE:
+ return r128_do_cleanup_cce( dev );
+ }
+
+ return -EINVAL;
+}
+
+int r128_cce_start( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
+ drm_r128_private_t *dev_priv = dev->dev_private;
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
dev->lock.pid != current->pid ) {
- DRM_ERROR( "r128_eng_reset called without lock held\n" );
+ DRM_ERROR( "r128_cce_start called without lock held\n" );
return -EINVAL;
}
- return r128_do_engine_reset( dev );
+ if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 )
+ return 0;
+
+ r128_do_cce_start( dev_priv );
+
+ dev_priv->cce_running = 1;
+ return 0;
}
-static int r128_do_engine_flush( drm_device_t *dev )
+int r128_cce_stop( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
drm_r128_private_t *dev_priv = dev->dev_private;
- u32 tmp;
- tmp = R128_READ( R128_PM4_BUFFER_DL_WPTR );
- R128_WRITE( R128_PM4_BUFFER_DL_WPTR, tmp | R128_PM4_BUFFER_DL_DONE );
+ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
+ dev->lock.pid != current->pid ) {
+ DRM_ERROR( "r128_cce_stop called without lock held\n" );
+ return -EINVAL;
+ }
+
+ if ( !dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 )
+ return 0;
+
+ /* Flush any pending CCE commands, then turn off the engine */
+ r128_do_cce_flush( dev_priv );
+ r128_do_cce_idle( dev_priv );
+ r128_do_cce_stop( dev_priv );
+
+ /* Mark the CCE as off so it is not reset */
+ dev_priv->cce_running = 0;
+
+ /* Reset the engine, but not the CCE */
+ r128_do_engine_reset( dev );
return 0;
}
-int r128_eng_flush( struct inode *inode, struct file *filp,
+/* Just reset the CCE ring. Called as part of an X Server engine reset.
+ */
+int r128_cce_reset( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
+ drm_r128_private_t *dev_priv = dev->dev_private;
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
dev->lock.pid != current->pid ) {
- DRM_ERROR( "r128_eng_flush called without lock held\n" );
+ DRM_ERROR( "r128_cce_reset called without lock held\n" );
return -EINVAL;
}
- return r128_do_engine_flush( dev );
-}
+ if ( !dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 )
+ return 0;
+ r128_do_cce_reset( dev_priv );
-/* ================================================================
- * CCE FIFO control
- */
+ /* The ring is no longer in use */
+ dev_priv->cce_running = 0;
+ return 0;
+}
-static int r128_do_cce_wait_for_fifo( drm_r128_private_t *dev_priv,
- int entries )
+int r128_cce_idle( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
{
- int i;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_private_t *dev_priv = dev->dev_private;
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- int slots = R128_READ( R128_PM4_STAT ) & R128_PM4_FIFOCNT_MASK;
- if ( slots >= entries ) return 0;
- udelay( 1 );
+ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
+ dev->lock.pid != current->pid ) {
+ DRM_ERROR( "r128_cce_idle called without lock held\n" );
+ return -EINVAL;
}
- return -EBUSY;
+
+ r128_do_cce_flush( dev_priv );
+ return r128_do_cce_idle( dev_priv );
}
-static inline int r128_do_cce_idle_ring( drm_r128_private_t *dev_priv )
+int r128_engine_reset( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
{
- int i;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- if ( *dev_priv->ring_read_ptr ==
- dev_priv->sarea_priv->ring_write ) {
- int pm4stat = R128_READ( R128_PM4_STAT );
- if ( (pm4stat & R128_PM4_FIFOCNT_MASK) >=
- dev_priv->cce_fifo_size &&
- !(pm4stat & (R128_PM4_BUSY |
- R128_PM4_GUI_ACTIVE)) ) {
- return r128_do_pixcache_flush( dev_priv );
- }
- }
- udelay( 1 );
+ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
+ dev->lock.pid != current->pid ) {
+ DRM_ERROR( "r128_engine_reset called without lock held\n" );
+ return -EINVAL;
}
- return -EBUSY;
+
+ return r128_do_engine_reset( dev );
}
-static inline int r128_do_cce_idle_pio( drm_r128_private_t *dev_priv )
+
+/* ================================================================
+ * Freelist management
+ */
+
+void r128_freelist_reset( drm_device_t *dev )
{
- int ret;
+ drm_device_dma_t *dma = dev->dma;
int i;
- ret = r128_do_cce_wait_for_fifo( dev_priv, dev_priv->cce_fifo_size );
- if ( ret < 0 ) return ret;
-
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- int pm4stat = R128_READ( R128_PM4_STAT );
- if ( !(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE)) ) {
- return r128_do_pixcache_flush( dev_priv );
- }
- udelay( 1 );
+ for ( i = 0 ; i < dma->buf_count ; i++ ) {
+ drm_buf_t *buf = dma->buflist[i];
+ drm_r128_buf_priv_t *buf_priv = buf->dev_private;
+ buf_priv->age = 0;
}
- return -EBUSY;
}
-static int r128_do_cce_idle( drm_device_t *dev )
+drm_buf_t *r128_freelist_get( drm_device_t *dev )
{
+ drm_device_dma_t *dma = dev->dma;
drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_buf_priv_t *buf_priv;
+ drm_buf_t *buf;
+ int i, t;
+
+ /* FIXME: Optimize -- use freelist code */
- if ( dev_priv->cce_is_bm_mode ) {
- return r128_do_cce_idle_ring( dev_priv );
- } else {
- return r128_do_cce_idle_pio( dev_priv );
+ for ( i = 0 ; i < dma->buf_count ; i++ ) {
+ buf = dma->buflist[i];
+ buf_priv = buf->dev_private;
+ if ( buf->pid == 0 ) return buf;
}
-}
-int r128_cce_idle( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
+ for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
+ u32 done_age = R128_READ( R128_VB_AGE_REG );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "r128_wait_idle called without lock held\n" );
- return -EINVAL;
+ for ( i = 0 ; i < dma->buf_count ; i++ ) {
+ buf = dma->buflist[i];
+ buf_priv = buf->dev_private;
+ if ( buf->pending && buf_priv->age <= done_age ) {
+ /* The buffer has been processed, so it
+ * can now be used.
+ */
+ buf->pending = 0;
+ return buf;
+ }
+ }
+ udelay( 1 );
}
- return r128_do_cce_idle( dev );
+ r128_status( dev );
+ return NULL;
}
@@ -497,6 +718,34 @@ int r128_cce_idle( struct inode *inode, struct file *filp,
* CCE packet submission
*/
+int r128_wait_ring( drm_r128_private_t *dev_priv, int n )
+{
+ drm_r128_ring_buffer_t *ring = &dev_priv->ring;
+ int i;
+
+ for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+ ring->space = *ring->head - dev_priv->ring.tail;
+ if ( ring->space <= 0 )
+ ring->space += ring->size;
+
+ if ( ring->space >= n )
+ return 0;
+
+ udelay( 1 );
+ }
+
+ return -EBUSY;
+}
+
+void r128_update_ring_snapshot( drm_r128_private_t *dev_priv )
+{
+ drm_r128_ring_buffer_t *ring = &dev_priv->ring;
+
+ ring->space = *ring->head - dev_priv->ring.tail;
+ if ( ring->space <= 0 )
+ ring->space += ring->size;
+}
+
static int r128_verify_command( drm_r128_private_t *dev_priv,
u32 cmd, int *size )
{
@@ -543,6 +792,7 @@ static int r128_verify_command( drm_r128_private_t *dev_priv,
static int r128_submit_packet_ring_secure( drm_r128_private_t *dev_priv,
u32 *commands, int *count )
{
+#if 0
int write = dev_priv->sarea_priv->ring_write;
int *write_ptr = dev_priv->ring_start + write;
int c = *count;
@@ -589,48 +839,14 @@ static int r128_submit_packet_ring_secure( drm_r128_private_t *dev_priv,
R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write );
*count = 0;
-
- return 0;
-}
-
-static int r128_submit_packet_pio_secure( drm_r128_private_t *dev_priv,
- u32 *commands, int *count )
-{
- u32 tmp = 0;
- int psize = 0;
- int writing = 1;
- int addr = R128_PM4_FIFO_DATA_EVEN;
- int ret;
-
- while ( *count > 0 ) {
- tmp = *commands++;
- if (!psize) {
- writing = r128_verify_command( dev_priv, tmp, &psize );
- }
- psize--;
-
- if ( writing ) {
- ret = r128_do_cce_wait_for_fifo( dev_priv, 1 );
- if ( ret ) return ret;
- R128_WRITE( addr, tmp );
- addr ^= 0x0004;
- }
-
- *count -= 1;
- }
-
- if ( addr == R128_PM4_FIFO_DATA_ODD ) {
- ret = r128_do_cce_wait_for_fifo( dev_priv, 1 );
- if ( ret < 0 ) return ret;
- R128_WRITE( addr, R128_CCE_PACKET2 );
- }
-
+#endif
return 0;
}
static int r128_submit_packet_ring_insecure( drm_r128_private_t *dev_priv,
u32 *commands, int *count )
{
+#if 0
int write = dev_priv->sarea_priv->ring_write;
int *write_ptr = dev_priv->ring_start + write;
int c = *count;
@@ -667,31 +883,7 @@ static int r128_submit_packet_ring_insecure( drm_r128_private_t *dev_priv,
R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write );
*count = 0;
-
- return 0;
-}
-
-static int r128_submit_packet_pio_insecure( drm_r128_private_t *dev_priv,
- u32 *commands, int *count )
-{
- int ret;
-
- while ( *count > 1 ) {
- ret = r128_do_cce_wait_for_fifo( dev_priv, 2 );
- if ( ret < 0 ) return ret;
- R128_WRITE( R128_PM4_FIFO_DATA_EVEN, *commands++ );
- R128_WRITE( R128_PM4_FIFO_DATA_ODD, *commands++ );
- *count -= 2;
- }
-
- if ( *count ) {
- ret = r128_do_cce_wait_for_fifo( dev_priv, 2 );
- if ( ret < 0 ) return ret;
- R128_WRITE( R128_PM4_FIFO_DATA_EVEN, *commands++ );
- R128_WRITE( R128_PM4_FIFO_DATA_ODD, R128_CCE_PACKET2 );
- *count = 0;
- }
-
+#endif
return 0;
}
@@ -703,28 +895,23 @@ int r128_do_submit_packet( drm_r128_private_t *dev_priv,
u32 *buffer, int count )
{
int c = count;
- int ret;
-
- if ( dev_priv->cce_is_bm_mode ) {
- int left = 0;
+ int ret = 0;
- if ( c >= dev_priv->ring_entries ) {
- c = dev_priv->ring_entries - 1;
- left = count - c;
- }
+#if 0
+ int left = 0;
- /* Since this is only used by the kernel we can use the
- * insecure ring buffer submit packet routine.
- */
- ret = r128_submit_packet_ring_insecure( dev_priv, buffer, &c );
- c += left;
- } else {
- /* Since this is only used by the kernel we can use the
- * insecure PIO submit packet routine.
- */
- ret = r128_submit_packet_pio_insecure( dev_priv, buffer, &c );
+ if ( c >= dev_priv->ring_entries ) {
+ c = dev_priv->ring_entries - 1;
+ left = count - c;
}
+ /* Since this is only used by the kernel we can use the
+ * insecure ring buffer submit packet routine.
+ */
+ ret = r128_submit_packet_ring_insecure( dev_priv, buffer, &c );
+ c += left;
+#endif
+
return ( ret < 0 ) ? ret : c;
}
@@ -743,6 +930,12 @@ int r128_cce_packet( struct inode *inode, struct file *filp,
int size;
int ret = 0;
+#if 0
+ /* GH: Disable packet submission for now.
+ */
+ return -EINVAL;
+#endif
+
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
dev->lock.pid != current->pid ) {
DRM_ERROR( "r128_submit_packet called without lock held\n" );
@@ -753,10 +946,11 @@ int r128_cce_packet( struct inode *inode, struct file *filp,
sizeof(packet) ) )
return -EFAULT;
+#if 0
c = packet.count;
size = c * sizeof(*buffer);
- if ( dev_priv->cce_is_bm_mode ) {
+ {
int left = 0;
if ( c >= dev_priv->ring_entries ) {
@@ -779,23 +973,12 @@ int r128_cce_packet( struct inode *inode, struct file *filp,
buffer, &c );
}
c += left;
- } else {
- buffer = kmalloc( size, 0 );
- if ( buffer == NULL )
- return -ENOMEM;
- if ( copy_from_user( buffer, packet.buffer, size ) )
- return -EFAULT;
-
- if ( dev_priv->cce_secure ) {
- ret = r128_submit_packet_pio_secure( dev_priv,
- buffer, &c );
- } else {
- ret = r128_submit_packet_pio_insecure( dev_priv,
- buffer, &c );
- }
}
kfree( buffer );
+#else
+ c = 0;
+#endif
packet.count = c;
if ( copy_to_user( (drm_r128_packet_t *)arg, &packet,
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h
index 0870b6cb2..8afbdaa39 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h
@@ -51,9 +51,9 @@
#define R128_UPLOAD_CLIPRECTS 0x200 /* handled client-side */
#define R128_REQUIRE_QUIESCENCE 0x400
-#define R128_FRONT 0x1
-#define R128_BACK 0x2
-#define R128_DEPTH 0x4
+#define R128_FRONT 0x1
+#define R128_BACK 0x2
+#define R128_DEPTH 0x4
/* Keep these small for testing.
*/
@@ -140,7 +140,6 @@ typedef struct drm_r128_sarea {
drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1];
int tex_age[R128_NR_TEX_HEAPS];
int ctx_owner;
- int ring_write;
} drm_r128_sarea_t;
@@ -155,24 +154,35 @@ typedef struct drm_r128_init {
int sarea_priv_offset;
int is_pci;
int cce_mode;
- int cce_fifo_size;
int cce_secure;
int ring_size;
int usec_timeout;
- int fb_offset;
- int agp_ring_offset;
- int agp_read_ptr_offset;
- int agp_vertbufs_offset;
- int agp_indbufs_offset;
- int agp_textures_offset;
- int mmio_offset;
+ unsigned int fb_bpp;
+ unsigned int front_offset, front_pitch;
+ unsigned int front_x, front_y;
+ unsigned int back_offset, back_pitch;
+ unsigned int back_x, back_y;
+ unsigned int depth_bpp;
+ unsigned int depth_offset, depth_pitch;
+ unsigned int depth_x, depth_y;
+
+ unsigned int fb_offset;
+ unsigned int mmio_offset;
+ unsigned int ring_offset;
+ unsigned int ring_rptr_offset;
+ unsigned int vertex_buffers_offset;
+ unsigned int indirect_buffers_offset;
+ unsigned int agp_textures_offset;
} drm_r128_init_t;
typedef struct drm_r128_clear {
+ unsigned int flags;
+ int x, y, w, h;
unsigned int clear_color;
unsigned int clear_depth;
- unsigned int flags;
+ unsigned int color_mask;
+ unsigned int depth_mask;
} drm_r128_clear_t;
typedef struct drm_r128_vertex {
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c
index ff20e5994..e2ee253ba 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c
@@ -35,7 +35,7 @@
#define R128_NAME "r128"
#define R128_DESC "ATI Rage 128"
-#define R128_DATE "20000919"
+#define R128_DATE "20000928"
#define R128_MAJOR 1
#define R128_MINOR 1
#define R128_PATCHLEVEL 0
@@ -105,12 +105,16 @@ static drm_ioctl_desc_t r128_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
#endif
- [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_init_cce, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_eng_reset, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_FLUSH)] = { r128_eng_flush, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_IDLE)] = { r128_cce_idle, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 },
};
#define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h
index 7139eddf9..d51f4af0e 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h
@@ -29,105 +29,119 @@
*
*/
-#ifndef _R128_DRV_H_
-#define _R128_DRV_H_
+#ifndef __R128_DRV_H__
+#define __R128_DRV_H__
typedef struct drm_r128_freelist {
- unsigned int age;
- drm_buf_t *buf;
+ unsigned int age;
+ drm_buf_t *buf;
struct drm_r128_freelist *next;
struct drm_r128_freelist *prev;
} drm_r128_freelist_t;
typedef struct drm_r128_ring_buffer {
- __volatile__ u32 *read_ptr;
-
- u32 start;
- u32 end;
- int size;
- int size_l2qw;
- u32 *virtual_start;
-
- int head;
- int tail;
- u32 tail_mask;
- int space;
+ u32 *start;
+ u32 *end;
+ int size;
+ int size_l2qw;
+
+ volatile u32 *head;
+ u32 tail;
+ u32 tail_mask;
+ int space;
} drm_r128_ring_buffer_t;
typedef struct drm_r128_private {
- __volatile__ u32 *ring_read_ptr;
+ drm_r128_ring_buffer_t ring;
drm_r128_sarea_t *sarea_priv;
- u32 *ring_start;
- u32 *ring_end;
- int ring_size;
- int ring_sizel2qw;
- int ring_entries;
-
- int cce_mode;
- int cce_fifo_size;
- int cce_is_bm_mode;
- int cce_secure;
- u32 *cce_buffer;
+ int cce_mode;
+ int cce_fifo_size;
+ int cce_secure;
+ int cce_running;
drm_r128_freelist_t *head;
drm_r128_freelist_t *tail;
- unsigned int submit_age;
-
- int usec_timeout;
- int is_pci;
-
- drm_map_t *sarea;
- drm_map_t *fb;
- drm_map_t *agp_ring;
- drm_map_t *agp_read_ptr;
- drm_map_t *agp_vertbufs;
- drm_map_t *agp_indbufs;
- drm_map_t *agp_textures;
- drm_map_t *mmio;
+ unsigned int submit_age;
+
+ int usec_timeout;
+ int is_pci;
+
+ unsigned int fb_bpp;
+ unsigned int front_offset;
+ unsigned int front_pitch;
+ unsigned int front_x;
+ unsigned int front_y;
+ unsigned int back_offset;
+ unsigned int back_pitch;
+ unsigned int back_x;
+ unsigned int back_y;
+
+ unsigned int depth_bpp;
+ unsigned int depth_offset;
+ unsigned int depth_pitch;
+ unsigned int depth_x;
+ unsigned int depth_y;
+
+ drm_map_t *sarea;
+ drm_map_t *fb;
+ drm_map_t *mmio;
+ drm_map_t *cce_ring;
+ drm_map_t *ring_rptr;
+ drm_map_t *vertex_buffers;
+ drm_map_t *indirect_buffers;
+ drm_map_t *agp_textures;
} drm_r128_private_t;
typedef struct drm_r128_buf_priv {
- u32 age;
- int discard;
- int dispatched;
+ u32 age;
+ int discard;
+ int dispatched;
drm_r128_freelist_t *my_freelist;
} drm_r128_buf_priv_t;
/* r128_drv.c */
-extern int r128_version(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int r128_open(struct inode *inode, struct file *filp);
-extern int r128_release(struct inode *inode, struct file *filp);
-extern int r128_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int r128_lock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int r128_unlock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-
- /* r128_dma.c */
-extern int r128_init_cce(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int r128_eng_reset(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int r128_eng_flush(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int r128_cce_packet(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int r128_cce_idle(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-
-extern void r128_flush_write_combine( void );
-extern int r128_do_wait_for_idle( drm_r128_private_t *dev_priv );
-extern int r128_do_submit_packet( drm_r128_private_t *dev_priv,
- u32 *buffer, int count );
+extern int r128_version( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int r128_open( struct inode *inode, struct file *filp );
+extern int r128_release( struct inode *inode, struct file *filp );
+extern int r128_ioctl( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int r128_lock( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int r128_unlock( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+
+ /* r128_cce.c */
+extern int r128_cce_init( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int r128_cce_start( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int r128_cce_stop( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int r128_cce_reset( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int r128_cce_idle( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int r128_engine_reset( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int r128_cce_packet( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+
+extern void r128_freelist_reset( drm_device_t *dev );
extern drm_buf_t *r128_freelist_get( drm_device_t *dev );
+extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n );
+extern void r128_update_ring_snapshot( drm_r128_private_t *dev_priv );
+
/* r128_state.c */
-extern int r128_cce_vertex(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
+extern int r128_cce_clear( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int r128_cce_swap( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int r128_cce_vertex( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
/* r128_bufs.c */
extern int r128_addbufs(struct inode *inode, struct file *filp,
@@ -182,12 +196,29 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_AUX3_SC_TOP 0x168c
#define R128_AUX3_SC_BOTTOM 0x1690
+#define R128_BUS_CNTL 0x0030
+# define R128_BUS_MASTER_DIS (1 << 6)
+
#define R128_CLOCK_CNTL_INDEX 0x0008
#define R128_CLOCK_CNTL_DATA 0x000c
# define R128_PLL_WR_EN (1 << 7)
#define R128_CONSTANT_COLOR_C 0x1d34
+#define R128_DP_GUI_MASTER_CNTL 0x146c
+# define R128_GMC_BRUSH_SOLID_COLOR (13 << 4)
+# define R128_GMC_BRUSH_NONE (15 << 4)
+# define R128_GMC_DST_16BPP (4 << 8)
+# define R128_GMC_DST_24BPP (5 << 8)
+# define R128_GMC_DST_32BPP (6 << 8)
+# define R128_GMC_SRC_DATATYPE_COLOR (3 << 12)
+# define R128_DP_SRC_SOURCE_MEMORY (2 << 24)
+# define R128_DP_SRC_SOURCE_HOST_DATA (3 << 24)
+# define R128_GMC_CLR_CMP_CNTL_DIS (1 << 28)
+# define R128_GMC_AUX_CLIP_DIS (1 << 29)
+# define R128_GMC_WR_MSK_DIS (1 << 30)
+# define R128_ROP3_S 0x00cc0000
+# define R128_ROP3_P 0x00f00000
#define R128_DP_WRITE_MASK 0x16cc
#define R128_DST_PITCH_OFFSET_C 0x1c80
@@ -214,7 +245,25 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
# define R128_PC_FLUSH_ALL 0x00ff
# define R128_PC_BUSY (1 << 31)
+#define R128_PRIM_TEX_CNTL_C 0x1cb0
+
+#define R128_SCALE_3D_CNTL 0x1a00
+#define R128_SEC_TEX_CNTL_C 0x1d00
+#define R128_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c
+#define R128_SETUP_CNTL 0x1bc4
+#define R128_STEN_REF_MASK_C 0x1d40
+
+#define R128_TEX_CNTL_C 0x1c9c
+# define R128_TEX_CACHE_FLUSH (1 << 23)
+
+#define R128_WINDOW_XY_OFFSET 0x1bcc
+
+
+/* CCE registers
+ */
+#define R128_PM4_BUFFER_OFFSET 0x0700
#define R128_PM4_BUFFER_CNTL 0x0704
+# define R128_PM4_MASK (15 << 28)
# define R128_PM4_NONPM4 (0 << 28)
# define R128_PM4_192PIO (1 << 28)
# define R128_PM4_192BM (2 << 28)
@@ -226,6 +275,13 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28)
# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28)
+#define R128_PM4_BUFFER_WM_CNTL 0x0708
+# define R128_WMA_SHIFT 0
+# define R128_WMB_SHIFT 8
+# define R128_WMC_SHIFT 16
+# define R128_WB_WM_SHIFT 24
+
+#define R128_PM4_BUFFER_DL_RPTR_ADDR 0x070c
#define R128_PM4_BUFFER_DL_RPTR 0x0710
#define R128_PM4_BUFFER_DL_WPTR 0x0714
# define R128_PM4_BUFFER_DL_DONE (1 << 31)
@@ -237,6 +293,11 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
# define R128_PM4_BUSY (1 << 16)
# define R128_PM4_GUI_ACTIVE (1 << 31)
+#define R128_PM4_MICROCODE_ADDR 0x07d4
+#define R128_PM4_MICROCODE_RADDR 0x07d8
+#define R128_PM4_MICROCODE_DATAH 0x07dc
+#define R128_PM4_MICROCODE_DATAL 0x07e0
+
#define R128_PM4_BUFFER_ADDR 0x07f0
#define R128_PM4_MICRO_CNTL 0x07fc
# define R128_PM4_MICRO_FREERUN (1 << 30)
@@ -244,19 +305,6 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_PM4_FIFO_DATA_EVEN 0x1000
#define R128_PM4_FIFO_DATA_ODD 0x1004
-#define R128_PRIM_TEX_CNTL_C 0x1cb0
-
-#define R128_SCALE_3D_CNTL 0x1a00
-#define R128_SEC_TEX_CNTL_C 0x1d00
-#define R128_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c
-#define R128_SETUP_CNTL 0x1bc4
-#define R128_STEN_REF_MASK_C 0x1d40
-
-#define R128_TEX_CNTL_C 0x1c9c
-# define R128_TEX_CACHE_FLUSH (1 << 23)
-
-#define R128_WINDOW_XY_OFFSET 0x1bcc
-
/* CCE command packets
*/
@@ -264,6 +312,9 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_CCE_PACKET1 0x40000000
#define R128_CCE_PACKET2 0x80000000
#define R128_CCE_PACKET3 0xC0000000
+# define R128_CNTL_HOSTDATA_BLT 0x00009400
+# define R128_CNTL_PAINT_MULTI 0x00009A00
+# define R128_CNTL_BITBLT_MULTI 0x00009B00
# define R128_3D_RNDR_GEN_INDX_PRIM 0x00002300
#define R128_CCE_PACKET_MASK 0xC0000000
@@ -285,6 +336,13 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030
#define R128_CCE_VC_CNTL_NUM_SHIFT 16
+/* Constants */
+#define R128_AGP_OFFSET 0x02000000
+
+#define R128_WATERMARK_L 16
+#define R128_WATERMARK_M 8
+#define R128_WATERMARK_N 8
+#define R128_WATERMARK_K 128
#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */
@@ -328,77 +386,44 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr);
(pkt) | ((n) << 16))
-#define R128_VERBOSE 0
+#define r128_flush_write_combine() mb()
+
-#if 0
+#define R128_VERBOSE 0
-#define RING_LOCALS unsigned long outring, ringmask; volatile u32 *virt;
+#define RING_LOCALS int write; unsigned int mask; volatile u32 *ring;
#define BEGIN_RING( n ) do { \
if ( R128_VERBOSE ) { \
- DRM_DEBUG( "BEGIN_RING( %d ) in %s\n", \
+ DRM_INFO( "BEGIN_RING( %d ) in %s\n", \
n, __FUNCTION__ ); \
} \
if ( dev_priv->ring.space < n * sizeof(u32) ) { \
r128_wait_ring( dev_priv, n * sizeof(u32) ); \
} \
dev_priv->ring.space -= n * sizeof(u32); \
- outring = dev_priv->ring.tail; \
- ringmask = dev_priv->ring.tail_mask; \
- virt = dev_priv->->ring.virtual_start; \
-} while (0)
-
-#define ADVANCE_RING() do { \
- if ( R128_VERBOSE ) { \
- DRM_DEBUG( "ADVANCE_RING()\n" ); \
- } \
- dev_priv->sarea_priv->ring_write = write;
- R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write );
- __ret = r128_do_submit_packet( dev_priv, buffer, outring ); \
- if ( __ret < 0 ) { \
- DRM_ERROR( "ADVANCE_RING fucked up!\n" ); \
- } \
-} while (0)
-
-#define OUT_RING( x ) do { \
- if ( R128_VERBOSE ) { \
- DRM_DEBUG( " OUT_RING( 0x%08x )\n", \
- (unsigned int)(x) ); \
- } \
- buffer[outring++] = x; \
-} while (0)
-
-#else
-
-#define RING_LOCALS unsigned long outring; u32 *buffer; int __ret;
-
-#define BEGIN_RING( n ) do { \
- if ( R128_VERBOSE ) { \
- DRM_DEBUG( "BEGIN_RING( %d ) in %s\n", \
- n, __FUNCTION__ ); \
- } \
- outring = 0; \
- buffer = dev_priv->cce_buffer; \
+ write = dev_priv->ring.tail; \
+ mask = dev_priv->ring.tail_mask; \
+ ring = dev_priv->ring.start; \
} while (0)
#define ADVANCE_RING() do { \
if ( R128_VERBOSE ) { \
- DRM_DEBUG( "ADVANCE_RING()\n" ); \
- } \
- __ret = r128_do_submit_packet( dev_priv, buffer, outring ); \
- if ( __ret < 0 ) { \
- DRM_ERROR( "ADVANCE_RING fucked up!\n" ); \
+ DRM_INFO( "ADVANCE_RING() tail=0x%06x wr=0x%06x\n", \
+ write, dev_priv->ring.tail ); \
} \
+ r128_flush_write_combine(); \
+ dev_priv->ring.tail = write; \
+ R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write ); \
} while (0)
#define OUT_RING( x ) do { \
if ( R128_VERBOSE ) { \
- DRM_DEBUG( " OUT_RING( 0x%08x )\n", \
- (unsigned int)(x) ); \
+ DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
+ (unsigned int)(x), write ); \
} \
- buffer[outring++] = x; \
+ ring[write++] = x; \
+ write &= mask; \
} while (0)
-#endif
-
-#endif
+#endif /* __R128_DRV_H__ */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c
index 124d9938e..b9ea930bf 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c
@@ -181,7 +181,7 @@ static inline void r128_emit_tex0( drm_r128_private_t *dev_priv )
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
- BEGIN_RING( 3 );
+ BEGIN_RING( 7 + R128_TEX_MAXLEVELS );
OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C,
2 + R128_TEX_MAXLEVELS ) );
@@ -207,7 +207,7 @@ static inline void r128_emit_tex1( drm_r128_private_t *dev_priv )
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
- BEGIN_RING( 3 );
+ BEGIN_RING( 5 + R128_TEX_MAXLEVELS );
OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C,
1 + R128_TEX_MAXLEVELS ) );
@@ -274,16 +274,214 @@ static inline void r128_emit_state( drm_r128_private_t *dev_priv )
* CCE command dispatch functions
*/
-static void r128_cce_dispatch_swap( drm_device_t *dev )
+static void r128_print_dirty( const char *msg, unsigned int flags )
{
-
+ DRM_INFO( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
+ msg,
+ flags,
+ (flags & R128_UPLOAD_CORE) ? "core, " : "",
+ (flags & R128_UPLOAD_CONTEXT) ? "context, " : "",
+ (flags & R128_UPLOAD_SETUP) ? "setup, " : "",
+ (flags & R128_UPLOAD_TEX0) ? "tex0, " : "",
+ (flags & R128_UPLOAD_TEX1) ? "tex1, " : "",
+ (flags & R128_UPLOAD_MASKS) ? "masks, " : "",
+ (flags & R128_UPLOAD_WINDOW) ? "window, " : "",
+ (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
+ (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
}
-static void r128_cce_dispatch_clear( drm_device_t *dev, int flags,
+static void r128_cce_dispatch_clear( drm_device_t *dev,
+ unsigned int flags,
+ int cx, int cy, int cw, int ch,
unsigned int clear_color,
- unsigned int clear_depth )
+ unsigned int clear_depth,
+ unsigned int color_mask,
+ unsigned int depth_mask )
{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ int nbox = sarea_priv->nbox;
+ drm_clip_rect_t *pbox = sarea_priv->boxes;
+ u32 fb_bpp, depth_bpp;
+ int i;
+ RING_LOCALS;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ switch ( dev_priv->fb_bpp ) {
+ case 16:
+ fb_bpp = R128_GMC_DST_16BPP;
+ break;
+ case 24:
+ fb_bpp = R128_GMC_DST_24BPP;
+ break;
+ case 32:
+ default:
+ fb_bpp = R128_GMC_DST_32BPP;
+ break;
+ }
+ switch ( dev_priv->depth_bpp ) {
+ case 16:
+ depth_bpp = R128_GMC_DST_16BPP;
+ break;
+ case 24:
+ depth_bpp = R128_GMC_DST_32BPP;
+ break;
+ case 32:
+ depth_bpp = R128_GMC_DST_32BPP;
+ break;
+ default:
+ return;
+ }
+
+ for ( i = 0 ; i < nbox ; i++ ) {
+ int x = pbox[i].x1;
+ int y = pbox[i].y1;
+ int w = pbox[i].x2 - x;
+ int h = pbox[i].y2 - y;
+
+ DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
+ pbox[i].x1, pbox[i].y1, pbox[i].x2,
+ pbox[i].y2, flags );
+
+ if ( flags & (R128_FRONT | R128_BACK) ) {
+ BEGIN_RING( 7 );
+
+ OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
+ OUT_RING( color_mask );
+
+ ADVANCE_RING();
+ }
+
+ if ( flags & R128_FRONT ) {
+ int fx = x + dev_priv->front_x;
+ int fy = y + dev_priv->front_y;
+
+ DRM_DEBUG( "clear front\n");
+ BEGIN_RING( 5 );
+
+ OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 3 ) );
+ OUT_RING( R128_GMC_BRUSH_SOLID_COLOR
+ | fb_bpp
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_ROP3_P
+ | R128_GMC_CLR_CMP_CNTL_DIS
+ | R128_GMC_AUX_CLIP_DIS );
+ OUT_RING( clear_color );
+ OUT_RING( (fx << 16) | fy );
+ OUT_RING( (w << 16) | h );
+
+ ADVANCE_RING();
+ }
+
+ if ( flags & R128_BACK ) {
+ int bx = x + dev_priv->back_x;
+ int by = y + dev_priv->back_y;
+
+ DRM_DEBUG( "clear back\n" );
+ BEGIN_RING( 5 );
+
+ OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 3 ) );
+ OUT_RING( R128_GMC_BRUSH_SOLID_COLOR
+ | fb_bpp
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_ROP3_P
+ | R128_GMC_CLR_CMP_CNTL_DIS
+ | R128_GMC_AUX_CLIP_DIS );
+ OUT_RING( clear_color );
+ OUT_RING( (bx << 16) | by );
+ OUT_RING( (w << 16) | h );
+
+ ADVANCE_RING();
+ }
+
+ if ( flags & R128_DEPTH ) {
+ int dx = x + dev_priv->depth_x;
+ int dy = y + dev_priv->depth_y;
+
+ DRM_DEBUG( "clear depth\n" );
+ BEGIN_RING( 7 );
+
+ OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
+ OUT_RING( depth_mask );
+
+ OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 3 ) );
+ OUT_RING( R128_GMC_BRUSH_SOLID_COLOR
+ | depth_bpp
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_ROP3_P
+ | R128_GMC_CLR_CMP_CNTL_DIS
+ | R128_GMC_AUX_CLIP_DIS );
+ OUT_RING( clear_depth );
+ OUT_RING( (dx << 16) | dy );
+ OUT_RING( (w << 16) | h );
+
+ ADVANCE_RING();
+ }
+ }
+}
+
+static void r128_cce_dispatch_swap( drm_device_t *dev )
+{
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ int nbox = sarea_priv->nbox;
+ drm_clip_rect_t *pbox = sarea_priv->boxes;
+ u32 fb_bpp;
+ int i;
+ RING_LOCALS;
+ DRM_INFO( "%s\n", __FUNCTION__ );
+
+ switch ( dev_priv->fb_bpp ) {
+ case 16:
+ fb_bpp = R128_GMC_DST_16BPP;
+ break;
+ case 24:
+ fb_bpp = R128_GMC_DST_24BPP;
+ break;
+ case 32:
+ default:
+ fb_bpp = R128_GMC_DST_32BPP;
+ break;
+ }
+
+ for ( i = 0 ; i < nbox ; i++ ) {
+ int fx = pbox[i].x1;
+ int fy = pbox[i].y1;
+ int fw = pbox[i].x2 - fx;
+ int fh = pbox[i].y2 - fy;
+ int bx = fx + dev_priv->back_x;
+ int by = fy + dev_priv->back_y;
+
+ fx += dev_priv->front_x;
+ fy += dev_priv->front_x;
+
+ BEGIN_RING( 5 );
+
+ OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 3 ) );
+ OUT_RING( R128_GMC_BRUSH_NONE
+ | R128_GMC_SRC_DATATYPE_COLOR
+ | R128_DP_SRC_SOURCE_MEMORY
+ | fb_bpp
+ | R128_ROP3_S
+ | R128_GMC_CLR_CMP_CNTL_DIS
+ | R128_GMC_AUX_CLIP_DIS
+ | R128_GMC_WR_MSK_DIS );
+
+ OUT_RING( (bx << 16) | by );
+ OUT_RING( (fx << 16) | fy );
+ OUT_RING( (fw << 16) | fh );
+ ADVANCE_RING();
+ }
+
+#if 0
+ BEGIN_RING( 2 );
+
+ OUT_RING( CCE_PACKET0( R128_SWAP_AGE_REG, 0 ) );
+ OUT_RING( r128ctx->lastSwapAge );
+
+ ADVANCE_RING();
+#endif
}
static void r128_cce_dispatch_vertex( drm_device_t *dev,
@@ -295,7 +493,7 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
int vertsize = sarea_priv->vertsize;
int format = sarea_priv->vc_format;
int index = buf->idx;
- int offset = dev_priv->agp_vertbufs->offset
+ int offset = dev_priv->vertex_buffers->offset
+ buf->offset - dev->agp->base;
int size = buf->used / (vertsize * sizeof(u32));
int prim;
@@ -309,6 +507,11 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
DRM_DEBUG( "vertex size = %d\n", vertsize );
DRM_DEBUG( "vertex format = 0x%x\n", format );
+ r128_update_ring_snapshot( dev_priv );
+
+ if ( 0 )
+ r128_print_dirty( "dispatch_vertex", sarea_priv->dirty );
+
prim = R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST;
if ( buf->used ) {
@@ -389,6 +592,68 @@ static void r128_get_vertex_buffer( drm_device_t *dev, drm_r128_vertex_t *v )
v->granted = 1;
}
+int r128_cce_clear( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ drm_r128_clear_t clear;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
+ dev->lock.pid != current->pid ) {
+ DRM_ERROR( "r128_cce_clear called without lock held\n" );
+ return -EINVAL;
+ }
+
+ if ( copy_from_user( &clear, (drm_r128_clear_t *) arg,
+ sizeof(clear) ) )
+ return -EFAULT;
+
+ if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
+ sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
+
+ r128_cce_dispatch_clear( dev, clear.flags,
+ clear.x, clear.y, clear.w, clear.h,
+ clear.clear_color, clear.clear_depth,
+ clear.color_mask, clear.depth_mask );
+
+ /* Make sure we restore the 3D state next time.
+ */
+ dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
+
+ return 0;
+}
+
+int r128_cce_swap( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_r128_private_t *dev_priv = dev->dev_private;
+ drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
+ dev->lock.pid != current->pid ) {
+ DRM_ERROR( "r128_cce_swap called without lock held\n" );
+ return -EINVAL;
+ }
+
+ if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
+ sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
+
+ r128_cce_dispatch_swap( dev );
+
+ /* Make sure we restore the 3D state next time.
+ */
+ dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
+
+ return 0;
+}
+
int r128_cce_vertex( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c
index 6b9e8f662..71cf44401 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c
@@ -79,24 +79,41 @@ int drmR128InitCCE( int fd, drmR128Init *info )
{
drm_r128_init_t init;
- memset(&init, 0, sizeof(drm_r128_init_t));
-
- init.func = R128_INIT_CCE;
- init.sarea_priv_offset = info->sarea_priv_offset;
- init.is_pci = info->is_pci;
- init.cce_mode = info->cce_mode;
- init.cce_fifo_size = info->cce_fifo_size;
- init.cce_secure = info->cce_secure;
- init.ring_size = info->ring_size;
- init.usec_timeout = info->usec_timeout;
-
- init.fb_offset = info->fb_offset;
- init.agp_ring_offset = info->agp_ring_offset;
- init.agp_read_ptr_offset = info->agp_read_ptr_offset;
- init.agp_vertbufs_offset = info->agp_vertbufs_offset;
- init.agp_indbufs_offset = info->agp_indbufs_offset;
- init.agp_textures_offset = info->agp_textures_offset;
- init.mmio_offset = info->mmio_offset;
+ memset( &init, 0, sizeof(drm_r128_init_t) );
+
+ init.func = R128_INIT_CCE;
+ init.sarea_priv_offset = info->sarea_priv_offset;
+ init.is_pci = info->is_pci;
+ init.cce_mode = info->cce_mode;
+ init.cce_secure = info->cce_secure;
+ init.ring_size = info->ring_size;
+ init.usec_timeout = info->usec_timeout;
+
+ init.fb_bpp = info->fb_bpp;
+ init.depth_bpp = info->depth_bpp;
+
+ init.front_offset = info->front_offset;
+ init.front_pitch = info->front_pitch;
+ init.front_x = info->front_x;
+ init.front_y = info->front_y;
+
+ init.back_offset = info->back_offset;
+ init.back_pitch = info->back_pitch;
+ init.back_x = info->back_x;
+ init.back_y = info->back_y;
+
+ init.depth_offset = info->depth_offset;
+ init.depth_pitch = info->depth_pitch;
+ init.depth_x = info->depth_x;
+ init.depth_y = info->depth_y;
+
+ init.fb_offset = info->fb_offset;
+ init.mmio_offset = info->mmio_offset;
+ init.ring_offset = info->ring_offset;
+ init.ring_rptr_offset = info->ring_rptr_offset;
+ init.vertex_buffers_offset = info->vertex_buffers_offset;
+ init.indirect_buffers_offset = info->indirect_buffers_offset;
+ init.agp_textures_offset = info->agp_textures_offset;
if ( ioctl( fd, DRM_IOCTL_R128_INIT, &init ) ) {
return -errno;
@@ -120,97 +137,83 @@ int drmR128CleanupCCE( int fd )
}
}
-int drmR128EngineReset( int fd )
+int drmR128StartCCE( int fd )
{
- if ( ioctl( fd, DRM_IOCTL_R128_RESET, NULL ) ) {
+ if ( ioctl( fd, DRM_IOCTL_R128_CCE_START, NULL ) ) {
return -errno;
} else {
return 0;
}
}
-int drmR128EngineFlush( int fd )
+int drmR128StopCCE( int fd )
{
- if ( ioctl( fd, DRM_IOCTL_R128_FLUSH, NULL ) ) {
+ if ( ioctl( fd, DRM_IOCTL_R128_CCE_STOP, NULL ) ) {
return -errno;
} else {
return 0;
}
}
-int drmR128WaitForIdle( int fd )
+int drmR128ResetCCE( int fd )
{
- if ( ioctl( fd, DRM_IOCTL_R128_IDLE, NULL ) ) {
+ if ( ioctl( fd, DRM_IOCTL_R128_CCE_RESET, NULL ) ) {
return -errno;
} else {
return 0;
}
}
-int drmR128SubmitPacket( int fd, void *buffer, int *count, int flags )
+int drmR128WaitForIdleCCE( int fd )
{
- drm_r128_packet_t packet;
- int ret;
-
- memset( &packet, 0, sizeof(drm_r128_packet_t) );
-
- packet.count = *count;
- packet.flags = flags;
-
- while (packet.count > 0) {
- packet.buffer = (CARD32 *)buffer + (*count - packet.count);
- ret = ioctl(fd, DRM_IOCTL_R128_PACKET, &packet);
- if (ret < 0 && ret != -EAGAIN) {
- *count = packet.count;
- return -errno;
- }
+ if ( ioctl( fd, DRM_IOCTL_R128_CCE_IDLE, NULL ) ) {
+ return -errno;
+ } else {
+ return 0;
}
-
- *count = 0;
- return 0;
}
-#if 0
-
-int drmR128GetVertexBuffers( int fd, int count, int *indices, int *sizes )
+int drmR128EngineReset( int fd )
{
- drm_r128_vertex_t v;
-
- v.send_count = 0;
- v.send_indices = NULL;
- v.send_sizes = NULL;
- v.request_count = count;
- v.request_indices = indices;
- v.request_sizes = sizes;
- v.granted_count = 0;
-
- if ( ioctl( fd, DRM_IOCTL_R128_VERTEX, &v ) ) {
+ if ( ioctl( fd, DRM_IOCTL_R128_RESET, NULL ) ) {
return -errno;
} else {
- return v.granted_count;
+ return 0;
}
}
-int drmR128FlushVertexBuffers( int fd, int count, int *indices, int *sizes )
+int drmR128SwapBuffers( int fd )
{
- drm_r128_vertex_t v;
-
- v.send_count = count;
- v.send_indices = indices;
- v.send_sizes = sizes;
- v.request_count = 0;
- v.request_indices = NULL;
- v.request_sizes = NULL;
- v.granted_count = 0;
-
- if ( ioctl( fd, DRM_IOCTL_R128_VERTEX, &v ) < 0 ) {
+ if ( ioctl( fd, DRM_IOCTL_R128_SWAP, NULL ) ) {
return -errno;
} else {
return 0;
}
}
-#endif
+int drmR128Clear( int fd, unsigned int flags,
+ int x, int y, int w, int h,
+ unsigned int clear_color, unsigned int clear_depth,
+ unsigned int color_mask, unsigned int depth_mask )
+{
+ drm_r128_clear_t clear;
+
+ clear.flags = flags;
+ clear.x = x;
+ clear.y = y;
+ clear.w = w;
+ clear.h = h;
+ clear.clear_color = clear_color;
+ clear.clear_depth = clear_depth;
+ clear.color_mask = color_mask;
+ clear.depth_mask = depth_mask;
+
+ if ( ioctl( fd, DRM_IOCTL_R128_CLEAR, &clear ) < 0 ) {
+ return -errno;
+ } else {
+ return 0;
+ }
+}
int drmR128VertexBuffer( int fd, int *index, int used,
int send, int discard, int request )
@@ -232,3 +235,26 @@ int drmR128VertexBuffer( int fd, int *index, int used,
return 0;
}
}
+
+int drmR128SubmitPacket( int fd, void *buffer, int *count, int flags )
+{
+ drm_r128_packet_t packet;
+ int ret;
+
+ memset( &packet, 0, sizeof(drm_r128_packet_t) );
+
+ packet.count = *count;
+ packet.flags = flags;
+
+ while (packet.count > 0) {
+ packet.buffer = (unsigned int *)buffer + (*count - packet.count);
+ ret = ioctl(fd, DRM_IOCTL_R128_PACKET, &packet);
+ if (ret < 0 && ret != -EAGAIN) {
+ *count = packet.count;
+ return -errno;
+ }
+ }
+
+ *count = 0;
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
index 5a979e1cb..7bf24afef 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
@@ -11,11 +11,11 @@
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -23,7 +23,7 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
- *
+ *
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
*
@@ -357,11 +357,15 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_I810_DOCOPY DRM_IO ( 0x48)
/* Rage 128 specific ioctls */
-#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
-#define DRM_IOCTL_R128_RESET DRM_IO( 0x41)
-#define DRM_IOCTL_R128_FLUSH DRM_IO( 0x42)
-#define DRM_IOCTL_R128_IDLE DRM_IO( 0x43)
-#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x44, drm_r128_packet_t)
-#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x45, drm_r128_vertex_t)
+#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
+#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41)
+#define DRM_IOCTL_R128_CCE_STOP DRM_IO( 0x42)
+#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
+#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
+#define DRM_IOCTL_R128_RESET DRM_IO( 0x45)
+#define DRM_IOCTL_R128_SWAP DRM_IO( 0x46)
+#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x47, drm_r128_clear_t)
+#define DRM_IOCTL_R128_VERTEX DRM_IOWR(0x48, drm_r128_vertex_t)
+#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x49, drm_r128_packet_t)
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h
index f30a3f1fb..399e38b7f 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h
@@ -36,41 +36,55 @@
* the kernel include file as well (r128_drm.h)
*/
+#define DRM_R128_FRONT 0x1
+#define DRM_R128_BACK 0x2
+#define DRM_R128_DEPTH 0x4
+
typedef struct {
int sarea_priv_offset;
int is_pci;
int cce_mode;
- int cce_fifo_size;
int cce_secure;
int ring_size;
int usec_timeout;
- int fb_offset;
- int agp_ring_offset;
- int agp_read_ptr_offset;
- int agp_vertbufs_offset;
- int agp_indbufs_offset;
- int agp_textures_offset;
- int mmio_offset;
+ unsigned int fb_bpp;
+ unsigned int front_offset, front_pitch;
+ unsigned int front_x, front_y;
+ unsigned int back_offset, back_pitch;
+ unsigned int back_x, back_y;
+ unsigned int depth_bpp;
+ unsigned int depth_offset, depth_pitch;
+ unsigned int depth_x, depth_y;
+
+ unsigned int fb_offset;
+ unsigned int mmio_offset;
+ unsigned int ring_offset;
+ unsigned int ring_rptr_offset;
+ unsigned int vertex_buffers_offset;
+ unsigned int indirect_buffers_offset;
+ unsigned int agp_textures_offset;
} drmR128Init;
extern int drmR128InitCCE( int fd, drmR128Init *info );
extern int drmR128CleanupCCE( int fd );
-extern int drmR128EngineReset( int fd );
-extern int drmR128EngineFlush( int fd );
-extern int drmR128WaitForIdle( int fd );
-extern int drmR128SubmitPacket( int fd, void *buffer,
- int *count, int flags );
+extern int drmR128StartCCE( int fd );
+extern int drmR128ResetCCE( int fd );
+extern int drmR128StopCCE( int fd );
+extern int drmR128WaitForIdleCCE( int fd );
-#if 0
-extern int drmR128GetVertexBuffers( int fd, int count,
- int *indices, int *sizes );
-extern int drmR128FlushVertexBuffers( int fd, int count,
- int *indices, int *sizes );
-#endif
+extern int drmR128EngineReset( int fd );
+extern int drmR128SwapBuffers( int fd );
+extern int drmR128Clear( int fd, unsigned int flags,
+ int x, int y, int w, int h,
+ unsigned int clear_color, unsigned int clear_depth,
+ unsigned int color_mask, unsigned int depth_mask );
extern int drmR128VertexBuffer( int fd, int *index, int used,
int send, int discard, int request );
+extern int drmR128SubmitPacket( int fd, void *buffer,
+ int *count, int flags );
+
#endif