diff options
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 |