diff options
author | gareth <gareth> | 2000-10-09 01:55:32 +0000 |
---|---|---|
committer | gareth <gareth> | 2000-10-09 01:55:32 +0000 |
commit | 6e6b109b1708692c6e1cf98c76a531cddbcdb037 (patch) | |
tree | 63d29416148c2afca9306376babc3cb6cc940f20 | |
parent | 2548e4c111964730cc0e021d22763b538580e240 (diff) |
Checking in latest development work - I need to merge the trunk intoati-4-1-1-20001009-freeze
this branch so I can work on my Mobility 128 laptop. This code is
probably broken, and may not even compile properly until after the merge
is done.
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 |