Initial revision

This commit is contained in:
Kaleb Keithley
2003-11-14 16:48:55 +00:00
commit 284d0bde93
17 changed files with 9811 additions and 0 deletions

23
CALLMAP Normal file
View File

@@ -0,0 +1,23 @@
-- Only Once, calling order --
ChipIdentify (S3VIdentify)
ChipProbe (S3VProbe)
Passive only, no ram determination, no writing
-- For each ScrnInfoRec, still calling order --
ChipPreInit (S3VPreInit)
Allows probing and mapping, hardware must remain unchanged
ChipGetRec
ChipScreenInit
ChipMapMem
ChipSave
vgaHWSaveMMIO
ChipModeInit
vtSema=TRUE
ChipWriteMode
vgaHWRestoreMMIO
$XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/CALLMAP,v 1.2 1998/11/22 10:37:28 dawes Exp $

64
README.sgml Normal file
View File

@@ -0,0 +1,64 @@
<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN" [
<!ENTITY % defs SYSTEM "defs.ent"> %defs;
]>
<article>
<title> Information for S3 ViRGE Users
<author>The XFree86 Project Inc.
<date>19 Dec 2001
<ident>
$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/s3virge.sgml,v 1.6 2003/02/13 03:21:33 dawes Exp $
</ident>
<toc>
<sect> Supported hardware
<p>
The s3virge driver in XFree86 &relvers; supports the S3 ViRGE, ViRGE DX, GX, GX2, MX, MX+, and VX chipsets. It also supports Trio3D and Trio3D/2x chips. A majority of testing is done on ViRGE DX chips, making them the most stable to date. This release has added support for doublescan modes on DX.
This driver is moderately stable, however please use caution with any new install. Please report any problems to
<email>XFree86@XFree86.org</email>
using the appropriate bug report sheet.
<sect>Features:
<p>
<itemize>
<item>Fully accelerated support for S3 ViRGE family video adapters
<item>uses linear frame buffer
<item>supports resolutions up to 2048x2048
<item>supports color depths of 8, 15, 16 and 24
<item>full use of video card memory for acceleration caching when visible framebuffer leaves extra memory
<item>XVideo on DX, GX, GX2, MX, MX+ and Trio3D/2X at depth 16 and 24
<item>Doublescan modes on DX, possibly others (untested)
</itemize>
<sect>Configuration:
<p>
The driver auto-detects RAM size, RAMDAC and ClockChip. Do not bother putting
these in your "Device" section.
<sect>Documentation:
<p>
The driver has several supported options which are documented in the s3virge man
page. Please refer to it for additional details about XF86Config options.
<sect>Support:
<p>
For support with XFree86 video drivers please refer to our web site at <url name="XFree86" url="http://www.XFree86.org">. For problems not addressed in the web page please contact our support email address <email>XFree86@XFree86.org</email>
<sect>Authors
<p>
<itemize>
<item>Mark Vojkovich <email>mvojkovich@nvidia.com</email>
<item>Sebastien Marineau
<item>Harald Koenig <email>koenig@tat.physik.uni-tuebingen.de</email>
<item>Matt Grossman <email>mattg@oz.net</email>
<item>Kevin Brosius <email>cobra@compuserve.com</email>
</itemize>
</article>

326
TODO_NOTES Normal file
View File

@@ -0,0 +1,326 @@
S3 ViRGE 4.0 devel notes
Status
------
1/26/2003
Ver 1.8.6
Pre-4.3.0 release. 320x240 doublescan support w/mouse adjust,
power management printouts, DAC error printout fix, log XVideo status based
on chipset, preliminary support for disabling XV when a mode doesn't
support it.
5/18/2002
Ver 1.8.5
320x240 mode support (doublescan).
2/2/02
Ver 1.8.4
Make 320x240 mode work in depth 15 & 16.
Testing, need to switch streams on/off based on dblscan_v flag and mode.
Virge MX panel_on test (doesn't work.)
1/10/02
Ver 1.8.3
DGA fix, buffer pointer used wrong value. Submitted for 4.2.0 (late).
Ver 1.8.2
DPMS testing (display DPMS status, disable MX LCD panel), DGA testing.
11/11/01 KJB
Ver 1.8.1
ViRGE MX (& GX2) fix to CR63 for problems with modes < 1024x768 from
max <sunmax@libero.it>. Submitted for 4.2.0.
11/5/01 KJB
Ver 1.8.0
ViRGE MX & GX2 XVideo changes. Fix overlap/color keying on MX, fix
and enable GX2 XVideo.
Submitted for 4.2.0.
11/4/01 KJB
Ver 1.7.0
Bump version for 4.2.0. Update man and README.
11/3/01 KJB
Ver 1.6.16
Pre-4.2.0 patch. cr3a fix, virge mx xvideo support, xvideo disable option
(helps with high res modes on dx and screen noise), remove accel solid
fill rect for trio3d, bring over some trio3d and mx fixes from 4.0.3 test
drivers. Includes VERBLEV bump to 5 to remove register dumps in log file.
Ver 1.6.15
Experimental - Scanline color expand - GX2
9/21/01 KJB
Ver 1.6.14
ModeInit - cr3a for MX/GX2, don't clear reserved bit 0x40 (revert change).
Back out previous cr3a patch for testing.
9/18/01 KJB
Ver 1.6.13
Option "xvideo" added. Add patch provided by Sven Menke
<Menke@SLAC.Stanford.EDU> for XV support on MX (slight changes to logic).
Ver 1.6.12
Adam J. Richter's cr3a fix (possibly temporary).
5/30/01 KJB
Ver 1.6.10
Disable MaxHValue & MaxVValue setting.
1/03/01 KJB
Ver 1.6.0
Revert ViRGE to pre-Xv changes. ViRGE DX still supports Xv, but changes
added for Xv and ViRGE caused problems with normal display.
11/27/00 KJB
Ver 1.5.0
Clean up, bump version for 4.0.2 submission.
CR3A, bit 0x40 (reserved) cleared for MX/GX2. Update man page.
11/24/00 KJB
Disable CPU to screen color expansion on GX2, causes lockups on GX2 with
'locate html' in an xterm. Add WaitCmd code to prevent accelerator and
reg command path activity at the same time on GX2.
XVideo fixes, left side clipping fixed for video windows extending off left
side of screen. Add horizontal filtering modes for 1-2x and >3x scaling.
11/7/00 KJB
Ver 1.4.0
Enable MX fixes, testing with accel BLT_BUG set is worse on GX2, so left
it out. BLT_BUG wasn't being enabled on ViRGE & VX because of case usage,
enabled now. Re-enable silken mouse for GX2. Add Render/fbPicture support.
Fix a few compiler warnings.
11/5/00 KJB
Continued work on GX2, much stabler now, but I think there is a lockup case
left if you enable pci_burst and pci_retry with accel. I still see screen
flashes with vertical bars once in a while, and the log reports a GEReset.
Added fbPicture (render) support, untested. XV code for GX2 is added,
but not working yet.
10/29/00 KJB
Much work on GX2, now SWCursor locks up but HWCursor is stable, go figure.
Loading Netscape a couple times with the mail window was enough to lock it
up twice in a row. Server was locked but not a box (PCI) lock. Also,
vertical barring still occurred a couple times, so HW cursor wasn't causing
that. Try blt_bug flag again for lock up case. And attach to debug server
and bt... Sleep now...
10/21/00 KJB
Ver 1.3.0
Depth 16 Xv support added. Testing on ViRGE DX. 1280x1024x24 is noisy, so
needs FIFO tuning.
9/27/00 KJB
Initial Xv support in depth 24.
9/10/00 KJB
Convert to FB. Add option "UseFB", default true. Added
VerticalRetraceWait timeout back as default. #if0 out the line accel
code in s3v_accel.c. The Subsequent...Bresenham line code causes a lockup
when used with fb. We didn't have any hardware accel in there anyway...
7/25/00 KJB
Started Xv additions.
6/26/00 KJB
GX2 seems to have an accel bug. I see the entire screen go solid color or
a wide stripe pattern for about 1 second. The S3VGEReset gets called twice,
and then everything is okay. Unless SilkenMouse is enabled... That seems to
get you a server lock instead. Short term is to disable SilkenMouse for GX2
only. SilkenMouse isn't really the problem of course, it just happens that if
we move the mouse during the 1 second engine lockup we appear more likely to
never recover.
6/23/00 KJB
Ver 1.2.0 - Fix console corruption on GX2 caused by reserved bit use in CR3A.
Fix GX2 noise on screen in hi-res depth 24 by increasing FIFO fill threshold.
6/12/00 KJB
Ver 1.1.0 - Add Init for SilkenMouse, add xf86SetBackingStore call, move
int10Symbols[] to remove warnings.
3/3/00 KJB
Ver 1.0.0 - S3VProbeDDC code for X -configure option added, add timeout to
WAITIDLE macro in s3v_macros.h, change ImageWriteFlags adding NO_GXCOPY.
Start of GX2 fixes, use CR regs for FIFO settings. Update copyrights.
2/11/00 KJB
Ver 0.11.0 - Add cfb16/24BresS to module symbols to remove warnings.
Fix viewport restore problem after EnterVT in 24 bpp.
Clean up log output, removing register dumps from normal console log.
6/26/99 KJB
Make the memory settings for fifo_conservative the default, 'fifo_conservative'
does nothing additional now. Patch includes DGA2 additions below, non-working.
Expected to be included in 3.9Pu.
Changes in 3.9Pt by others include additions for newer RAC support. Some reports
say multi-head works now with ViRGE.
6/17/99 KJB
Ver 0.9.0 - Prelim DGA2 support modeled after MGA.
5/28/99 KJB
Ver 0.8.0 - Changes to 3.9Po - Cleaned up debug register printing function, minor
changes to man page, remove S3V.sgml and add new s3virge.sgml in doc/sgml, also
remove README.S3V from doc directory.
4/5/99 KJB
3.9Ph - Ver 0.7.0 - Virge man page added, HW Cursor fixed, rename chipsets removing
slashes in the names.
03/27/99 KJB
Ver 0.6.0 - hwcursor additions, added s3v_hwcurs.c and Option "swcursor".
Default is hwcursor, Option "swcursor" will disable it.
Ver 0.5.0 - patch against 3.9Pf (seq 2615), fix depth 24 and Accel flags, sync pci_burst option to previous changes, remove s3v_comp.h and s3v_pio.c and merge as needed.
03/21/99 KJB
3.9Pf has Matt Grossman's Alpha changes.
For next patch - remove s3v_pio.c and s3v_comp.h. Include the EnableMMIO and
DisableMMIO functions from s3v_pio.c in s3v_driver.c.
03/02/99 KJB
3.9Pc - depth 24 doesn't work on my ViRGE DX. NoAccel doesn't start, accel does
but has blocky noise.
03/01/99 KJB
Macro change done, VGAIN/VGAOUT for register access, INREG/OUTREG for s3v_accel.c.
Added Mark Vojkovich's re-write of the accel code. It may only be clean for ViRGE DX
at the moment. x11perf showed a couple artifacts in 'move window via parent'.
In progress, attempt to call cfbScreenInit() functions after MapMem/EnterVT. Not
working yet. Version stamped 0.4.0.
02/22/99 KJB
Macro change coming to add Mark's accel update. VGAOUT for old stuff and MEMOUT
for new stuff? That way there's no confusion with the old INREG/OUTREG macros.
Or maybe just stick with INREG/OUTREG for new stuff.
01/30/99 KJB
Version stamp 0.3.0. Changed Chipset flags to use PCI IDs exclusively, also use
common/xf86PciInfo.h for PCI IDs rather than coding them in regs3v.h.
11/28/98 KJB
Bumped version stamp to 0.2, expect code in 3.9No. Cleaned up s3v.h and
s3v_driver.c by removing unused definition & code sections. Added
options set_mclk (from 3.3.2) and set_lcdclk (3.3.3 MX). Code support
from 3.3.3 for ViRGE GX2 and MX+ is included.
Disabled call to 32 bpp AccelInit to get -depth 24 -bpp 32 working again.
11/27/98 KJB
More 3.3.3 import.
New registers saved, CR40,CR45,SR8,(for MX) SR29,SR45,SR55,SR56,SR57.
Reviewed s3vdriver.h, rehs3v.h, newmmio.h, s3v_accel.c, s3v_driver.c.
Added ViRGE MX, MX+ & GX2 support. Re-synced parts of mode save and init
with 3.3.3 versions. Added timeout ability for WaitIdle() and friends.
Added chipnames and numbers to Chipsets struct.
11/26/98 KJB
Import additions from 3.3.3, newmmio.h, regs3v.h,
Trap fills disabled because they don't match cfb, pixmap cache & ImageWrite
working, fixed depth 8 color loss on VT switches, INREG & OUTREG modified to
use a single offset value instead of adding the base and offset together.
11/18/98 KJB
3.9Nn
Acceleration working for Bitblt, ScreenToScreenCopy, Color 8x8 Rect fills,
and Rect/Trap fills.
Trap fills do not support transparency, so that needs to be exported to XAA.
10/31/98 KJB
Working depth 8, discolored dep 16 but runs, dep 24 screen goes black,
C-A-Bkspc restores text console. At 3.9Nk tree level, module would not
load in Loader server. why? Static server tested.
10/29/98 KJB
ModeInit() needs work, options are heavily #if'd to try and get 8bpp
working.
10/16/98 KJB
General 4.0 architecture is setup. Presently at 3.9Nc level, if moved
to a newer tree you will need to add the resource handling functions from
Egbert (I haven't tackled that yet).
At the moment the ScreenInit() function is coded to return FALSE. On my
ViRGE DX card this version does not lock up, but it does destroy the
video mode. Make sure you have an external terminal or network connection
if you run it (or blindly do a restart from your main terminal). I make
no guarantees that it won't hard lock other versions of ViRGE.
I've left out the Alpha memory mapping, along with all option processing.
Those will need to be done once the driver is minimally working.
Note that everything in s3v_driver.c is MMIO only. There are a pair of
PIO functions in s3v_pio.c, but that is the only place. See notes below
about my ViRGE DX BIOS and why I needed to do this on my hardware.
Other stuff...
Some test stuff is assuming 8bpp, so 16 & 24 are broken.
On my hardware, I am presently trying to get the Save/Restore sequence to
recover the video mode. At the moment, when I run this driver, I get:
ScreenInit() runs to completion.
It returns FALSE, so the Server aborts.
LeaveVT() is called, and runs to completion.
The Server exits gracefully, but my monitor goes powersaver and the video
mode is not recovered.
TODO items
----------
1/30/03 General option "videoram" is ignored by the virge driver.
(Meelis Roos)
3/24/02 Xv reported to not work as secondary in Xinerama multihead.
(xav on irc)
3/24/02 DPMS doesn't fully disable the screen. Blue line across the
center in all modes. (xav on irc)
3/25/02 Secondary reports primary BIOS during int10 detection. ie:
(II) S3VIRGE(1): VESA BIOS detected
(II) S3VIRGE(1): VESA VBE Version 2.0
(II) S3VIRGE(1): VESA VBE Total Mem: 4194240 kB
(II) S3VIRGE(1): VESA VBE OEM: ATI RAGE128
(II) S3VIRGE(1): VESA VBE OEM Software Rev: 1.0
(II) S3VIRGE(1): VESA VBE OEM Vendor: ATI Technologies Inc.
(II) S3VIRGE(1): VESA VBE OEM Product: R128
(II) S3VIRGE(1): VESA VBE OEM Product Rev: 01.00
(xav on irc)
Check CR65 usage, bit 2 set based on S3_EARLY_SC? In my manual bit 2 is
enable MMIO to RAMDAC registers.
Notes:
----------
/config/cf/xfree86.cf
have to add s3v to XF86CardDrivers for imake to make the
drivers/s3v Makefile.
To remake makefiles, after editing Imakefile, go to dir above drivers/s3v
and do a 'make Makefiles'.
For debug, make CDEBUGFLAGS='-g -DDEBUG', adding -DMetroLink enables
timeout for VerticalRetraceWait().
S3 ViRGE DX stuff:
Card seems to power up (or BIOS forces) with MMIO disabled. All flavors are
disabled, because CR53 comes up as 0. This may preclude using this card
as the second device in a multi-head situation although David D. says that
the new config. management stuff may help here.
$XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/TODO_NOTES,v 1.23 2003/02/13 03:21:33 dawes Exp $

245
man/s3virge.man Normal file
View File

@@ -0,0 +1,245 @@
.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3virge.man,v 1.4 2003/02/13 03:21:33 dawes Exp $
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH s3virge __drivermansuffix__ __vendorversion__
.SH NAME
s3virge \- S3 ViRGE video driver
.SH SYNOPSIS
.B "Section \*qDevice\*q"
.br
.BI " Identifier \*q" devname \*q
.br
.B " Driver \*qs3virge\*q"
.br
\ \ ...
.br
\ \ [
.B "Option"
"optionname" ["optionvalue"]]
.br
.B EndSection
.SH DESCRIPTION
.B s3virge
is an XFree86 driver for S3 based video cards. The driver is fully
accelerated, and provides support for the following framebuffer depths:
8, 15, 16, and 24. All
visual types are supported for depth 8, and TrueColor
visuals are supported for the other depths. XVideo hardware up scaling
is supported in depth 16 and 24 on the DX, GX, GX2, MX, MX+, and
Trio3D/2X. Doublescan modes are supported and tested in depth 8
and 16 on DX, but disable XVideo. Doublescan modes on other chipsets
are untested.
.SH SUPPORTED HARDWARE
The
.B s3virge
driver supports PCI and AGP video cards based on the following S3 chips:
.TP 12
.B ViRGE
86C325
.TP 12
.B ViRGE VX
86C988
.TP 12
.B ViRGE DX
86C375
.TP 12
.B ViRGE GX
86C385
.TP 12
.B ViRGE GX2
86C357
.TP 12
.B ViRGE MX
86C260
.TP 12
.B ViRGE MX+
86C280
.TP 12
.B Trio 3D
86C365
.TP 12
.B Trio 3D/2X
86C362, 86C368
.SH CONFIGURATION DETAILS
Please refer to XF86Config(__filemansuffix__) for general configuration
details. This section only covers configuration details specific to this
driver. All options names are case and white space insensitive when
parsed by the server, for example, "virge vx" and "VIRGEvx" are equivalent.
.PP
The driver auto-detects the chipset type, but the following
.B ChipSet
names may optionally be specified in the config file
.B \*q"Device\*q"
section, and will override the auto-detection:
.PP
.RS 4
"virge", "86c325", "virge vx", "86c988", "virge dx", "86c375",
"virge gx", "86c385", "virge gx2", "86c357", "virge mx", "86c260",
"virge mx+", "86c280", "trio 3d", "86c365", "trio 3d/2x", "86c362",
"86c368".
.RE
.PP
The following Cursor
.B Options
are supported:
.TP
.BI "Option \*qHWCursor\*q [\*q" boolean \*q]
Enable or disable the HW cursor. Default: on.
.TP
.BI "Option \*qSWCursor\*q [\*q" boolean \*q]
Inverse of "HWCursor". Default: off.
.PP
The following display
.B Options
are supported:
.TP
.BI "Option \*qShadowFB\*q [\*q" boolean \*q]
Use shadow framebuffer. Disables HW acceleration. Default: off.
.TP
.BR "Option \*qRotate\*q \*q" cw " | " ccw \*q
Rotate the screen CW - clockwise or CCW - counter clockwise.
Disables HW Acceleration and HW Cursor, uses ShadowFB.
Default: no rotation.
.TP
.BR "Option \*qXVideo\*q [\*q" boolean \*q]
Disable XVideo support by using the off option. This changes FIFO
settings which prevent screen noise for high-res modes. Default: on
.PP
The following video memory
.B Options
are supported:
.TP
.BI "Option \*qslow_edodram\*q"
Switch the standard ViRGE to 2-cycle edo mode. Try this
if you encounter pixel corruption on the ViRGE. Using this option will
cause a large decrease in performance. Default: off.
.TP
.BI "Option \*qfpm_vram\*q"
Switch the ViRGE/VX to fast page mode vram mode. Default: off.
.TP
.BR "Option \*qslow_dram " | " fast_dram\*q"
Change Trio 3D and 3D/2X memory options. Default: Use BIOS defaults.
.TP
.BR "Option \*qearly_ras_precharge " | " late_ras_precharge\*q"
adjust memory parameters. One
of these will us the same settings as your video card defaults, and
using neither in the config file does the same. Default: none.
.TP
.BI "Option \*qset_mclk\*q \*q" integer \*q
sets the memory clock, where
.I integer
is in kHz, and
.I integer
<= 100000. Default: probe the memory clock value,
and use it at server start.
.TP
.BI "Option \*qset_refclk\*q \*q" integer \*q
sets the ref clock for ViRGE MX, where
.I integer
is in kHz. Default: probe the memory clock value,
and use it at server start.
.PP
The following acceleration and graphics engine
.B Options
are supported:
.TP
.B "Option \*qNoAccel\*q"
Disable acceleration. Very useful for determining if the
driver has problems with drawing and acceleration routines. This is the first
option to try if your server runs but you see graphic corruption on the screen.
Using it decreases performance, as it uses software emulation for drawing
operations the video driver can accelerate with hardware.
Default: acceleration is enabled.
.TP
.B "Option \*qUseFB\*q"
There are two framebuffer rendering methods. fb and cfb. Both are
available in the driver. fb is the newer and default method. To switch
back to cfb use this option with no, off or other negative parameter.
Default: on.
.TP
.BR "Option \*qfifo_aggressive " | " fifo_moderate " | " fifo_conservative\*q"
alter the settings
for the threshold at which the pixel FIFO takes over the internal
memory bus to refill itself. The smaller this threshold, the better
the acceleration performance of the card. You may try the fastest
setting
.RB ( "fifo_aggressive" )
and move down if you encounter pixel corruption.
The optimal setting will probably depend on dot-clock and on color
depth. Note that specifying any of these options will also alter other
memory settings which may increase performance, so trying
.B "fifo_conservative"
will in most cases be a slight benefit (this uses the chip defaults).
If pixel corruption or transient streaking is observed during drawing
operations then removing any fifo options is recommended. Default: none.
.PP
The following PCI bus
.B Options
are supported:
.TP
.BI "Option \*qpci_burst\*q [\*q" boolean \*q]
will enable PCI burst mode. This should work on all but a
few broken PCI chipsets, and will increase performance. Default: off.
.TP
.BI "Option \*qpci_retry\*q [\*q" boolean \*q]
will allow the driver to rely on PCI Retry to program the
ViRGE registers.
.B "pci_burst"
must be enabled for this to work.
This will increase performance, especially for small fills/blits,
because the driver does not have to poll the ViRGE before sending it
commands to make sure it is ready. It should work on most
recent PCI chipsets. Default: off.
.PP
The following ViRGE MX LCD
.B Options
are supported:
.TP
.BI "Option \*qlcd_center\*q"
.TP
.BI "Option \*qset_lcdclk\*q \*q" integer \*q
allows setting the clock for a ViRGE MX LCD display.
.I integer
is in Hz. Default: use probed value.
.PP
The following additional
.B Options
are supported:
.TP
.BI "Option \*qShowCache\*q [\*q" boolean \*q]
Enable or disable viewing offscreen cache memory. A
development debug option. Default: off.
.TP
.BI "Option \*qmx_cr3a_fix\*q [\*q" boolean \*q]
Enable or disable a cr3a fix added for ViRGE MX. Default: on.
.SH SEE ALSO
XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__)
.SH KNOWN BUGS
The VideoRam generic driver parameter is presently ignored by the
s3virge driver. On PPC this is reported to cause problems for 2M
cards, because they may autodetect as 4M.
.SH SUPPORT
For assistance with this driver, or XFree86 in general, check the XFree86 web
site at http://www.xfree86.org. A FAQ is available on the web site at
http://www.xfree86.org/FAQ/. If you find a problem with XFree86 or have a
question not answered in the FAQ please use our bug report form available on
the web site or send mail to XFree86@XFree86.org. When reporting problems
with the driver send as much detail as possible, including chipset type, a
server output log, and operating system specifics.
.SH AUTHORS
Kevin Brosius,
Matt Grossman,
Harald Koenig,
Sebastien Marineau,
Mark Vojkovich.

619
src/newmmio.h Normal file
View File

@@ -0,0 +1,619 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/newmmio.h,v 1.5 1999/03/21 07:35:15 dawes Exp $ */
/*
Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
/***************************************************************************
*
* typedefs and macros for MMIO mode, S3 ViRGE
*
* who when vers
* HK 9609126 0.0
*
* based on:
*
* typedefs and macros for old and new MMIO mode, Trio64V+ and 868/968
*
* who when vers
* BL 0300296 0.1
* SM 200497 0.2 Added Caching version of register macros.
* KJB 9/98 0.3 Added S3V_MMIO_REGSIZE
***************************************************************************/
#ifndef _NEWMMIO_H
#define _NEWMMIO_H
/* base for S3_OUTW macro */
#define S3_NEWMMIO_REGBASE 0x1000000 /* 16MB */
#define S3_NEWMMIO_REGSIZE 0x10000 /* 64KB */
#define S3V_MMIO_REGSIZE 0x8000 /* 32KB */
/* #include <Xmd.h> */
#define int16 CARD16
#define int32 CARD32
#define S3_NEWMMIO_VGABASE (S3_NEWMMIO_REGBASE + 0x8000)
#if 0
typedef struct { int16 vendor_ID; int16 device_ID; } pci_id;
typedef struct { int16 cmd; int16 devsel; } cmd_devsel;
typedef struct {
pci_id pci_ident;
cmd_devsel cmd_device_sel;
int32 class_code;
char dummy_0c;
char latnecy_timer;
int16 dummy_0e;
int32 base0;
char dummy_14[0x20-sizeof(int32)];
int32 bios_base;
int32 dummy_34;
int32 dummy_38;
char int_line;
char int_pin;
int16 latency_grant;
} pci_conf_regs;
typedef struct {
int32 prim_stream_cntl;
int32 col_chroma_key_cntl;
char dummy1[0x8190 - 0x8184-sizeof(int32)];
int32 second_stream_cntl;
int32 chroma_key_upper_bound;
int32 second_stream_stretch;
char dummy2[0x81a0 - 0x8198-sizeof(int32)];
int32 blend_cntl;
char dummy3[0x81c0 - 0x81a0-sizeof(int32)];
int32 prim_fbaddr0;
int32 prim_fbaddr1;
int32 prim_stream_stride;
int32 double_buffer;
int32 second_fbaddr0;
int32 second_fbaddr1;
int32 second_stream_stride;
int32 opaq_overlay_cntl;
int32 k1;
int32 k2;
int32 dda_vert;
int32 streams_fifo;
int32 prim_start_coord;
int32 prim_window_size;
int32 second_start_coord;
int32 second_window_size;
} streams_proc_regs;
typedef struct {
int32 fifo_control;
int32 miu_control;
int32 streams_timeout;
int32 misc_timeout;
int32 dummy_8210, dummy_8214, dummy_8218, dummy_821c;
int32 dma_read_base_addr;
int32 dma_read_stride_width;
} memport_proc_regs;
typedef struct {
int32 subsystem_csr;
int32 dummy_8508;
int32 adv_func_cntl;
} subsys_regs;
typedef struct {
int32 start_sysmem_addr;
int32 transfer_length;
int32 transfer_enable;
} video_dma_regs;
typedef struct {
int32 base_addr;
int32 write_pointer;
int32 read_pointer;
int32 dma_enable;
} cmd_dma_regs;
typedef struct {
video_dma_regs video;
int32 dummy_858c;
cmd_dma_regs cmd;
} dma_regs;
typedef struct {
int32 lpb_mode;
int32 lpb_fifostat;
int32 lpb_intflags;
int32 lpb_fb0addr;
int32 lpb_fb1addr;
int32 lpb_direct_addr;
int32 lpb_direct_data;
int32 lpb_gpio;
int32 lpb_serial_port;
int32 lpb_input_winsize;
int32 lpb_data_offsets;
int32 lpb_hor_decimctl;
int32 lpb_vert_decimctl;
int32 lpb_line_stride;
int32 lpb_output_fifo;
} lpbus_regs;
typedef struct { char atr_cntl_ind; char attr_cntl_dat; char misc_out;
char viseo_enable; } v3c0;
typedef struct { char seq_index; char seq_data; char dac_mask;
char dac_rd_index; } v3c4;
typedef struct { char dac_wr_index; char dac_data; char feature_cntl;
char filler; } v3c8;
typedef struct v3cc { char misc_out; char filler; char graph_cntl_index;
char graph_cntl_data; } v3cc;
typedef struct {
v3c0 v3c0_regs;
v3c4 v3c4_regs;
v3c8 v3c8_regs;
v3cc v3cc_regs;
} vga_3c_regs;
typedef struct { char crt_index; char crt_data; int16 filler; } v3d4;
typedef struct { int16 filler1; char feature_cntl; char filler2;} v3d8;
typedef struct {
int32 filler;
v3d4 v3d4_regs;
v3d8 v3d8_regs;
} vga_3bd_regs ;
typedef struct {
char filler1[-(0xa000-0xa100)];
int32 patt[-(0xa100-0xa1bc) / sizeof(int32) + 1];
} colpatt_regs;
typedef struct {
char filler1[-(0xa400-0xa4d4)];
int32 src_base;
int32 dest_base;
int32 clip_l_r;
int32 clip_t_b;
int32 dest_src_str;
int32 mono_pat0;
int32 mono_pat1;
int32 pat_bg_clr;
int32 pat_fg_clr;
int32 src_bg_clr;
int32 src_fg_clr;
int32 cmd_set;
int32 rwidth_height;
int32 rsrc_xy;
int32 rdest_xy;
} bltfill_regs;
typedef struct {
char filler1[-(0xa800-0xa8d4)];
int32 src_base;
int32 dest_base;
int32 clip_l_r;
int32 clip_t_b;
int32 dest_src_str;
int32 dummy1;
int32 dummy2;
int32 dummy3;
int32 pat_fg_clr;
int32 dummy4;
int32 dummy5;
int32 cmd_set;
char filler2[-(0xa904-0xa96c)];
int32 lxend0_end1;
int32 ldx;
int32 lxstart;
int32 lystart;
int32 lycnt;
} line_regs;
typedef struct {
char filler1[-(0xac00-0xacd4)];
int32 src_base;
int32 dest_base;
int32 clip_l_r;
int32 clip_t_b;
int32 dest_src_str;
int32 mono_pat0;
int32 mono_pat1;
int32 pat_bg_clr;
int32 pat_fg_clr;
int32 dummy1;
int32 dummy2;
int32 cmd_set;
char filler2[-(0xad04-0xad68)];
int32 prdx;
int32 prxstart;
int32 pldx;
int32 plxstart;
int32 pystart;
int32 pycnt;
} polyfill_regs;
typedef struct {
char filler1[-(0xb000-0xb0d4)];
int32 z_base;
int32 dest_base;
int32 clip_l_r;
int32 clip_t_b;
int32 dest_src_str;
int32 z_stride;
int32 dummy1;
int32 dummy2;
int32 fog_clr;
int32 dummy3;
int32 dummy4;
int32 cmd_set;
char filler2[-(0xb104-0xb144)];
int32 dgdy_dbdy;
int32 dady_drdy;
int32 gs_bs;
int32 as_rs;
int32 dummy5;
int32 dz;
int32 zstart;
int32 dummy6;
int32 dummy7;
int32 dummy8;
int32 xend0_end1;
int32 dx;
int32 xstart;
int32 ystart;
int32 ycnt;
} line3d_regs;
typedef struct {
char filler1[-(0xb400-0xb4d4)];
int32 z_base;
int32 dest_base;
int32 clip_l_r;
int32 clip_t_b;
int32 dest_src_str;
int32 z_stride;
int32 tex_base;
int32 tex_bdr_clr;
int32 fog_clr;
int32 color0;
int32 color1;
int32 cmd_set;
int32 bv;
int32 bu;
int32 dwdx;
int32 dwdy;
int32 ws;
int32 dddx;
int32 dvdx;
int32 dudx;
int32 dddy;
int32 dvdy;
int32 dudy;
int32 ds;
int32 vs;
int32 us;
int32 dgdx_dbdx;
int32 dadx_drdx;
int32 dgdy_dbdy;
int32 dady_drdy;
int32 gs_bs;
int32 as_rs;
int32 dzdx;
int32 dzdy;
int32 zs;
int32 dxdy12;
int32 xend12;
int32 dxdy01;
int32 xend01;
int32 dxdy02;
int32 xstart02;
int32 ystart;
int32 y01_y12;
} triangle3d_regs;
typedef struct {
int32 img[0x8000/4];
union { pci_conf_regs regs;
char dummy[-(0x8000 - 0x8180)];
} pci_regs;
union { streams_proc_regs regs;
char dummy[-(0x8180 - 0x8200)];
} streams_regs;
union { memport_proc_regs regs;
char dummy[-(0x8200 - 0x83b0)];
} memport_regs;
union { vga_3bd_regs regs;
char dummy[-(0x83b0 - 0x83c0)];
} v3b_regs;
union { vga_3c_regs regs;
char dummy[-(0x83c0 - 0x83d0)];
} v3c_regs;
union { vga_3bd_regs regs;
char dummy[-(0x83d0 - 0x8504)];
} v3d_regs;
union { subsys_regs regs;
char dummy[-(0x8504 - 0x8580)];
} subsys_regs;
union { dma_regs regs;
char dummy[-(0x8580 - 0xa000)];
} dma_regs;
union { colpatt_regs regs;
char dummy[-(0xa000 - 0xa400)];
} colpatt_regs;
union { bltfill_regs regs;
char dummy[-(0xa400 - 0xa800)];
} bltfill_regs;
union { line_regs regs;
char dummy[-(0xa800 - 0xac00)];
} line_regs;
union { polyfill_regs regs;
char dummy[-(0xac00 - 0xb000)];
} polyfill_regs;
union { line3d_regs regs;
char dummy[-(0xb000 - 0xb400)];
} line3d_regs;
union { triangle3d_regs regs;
char dummy[-(0xb400 - 0xff00)];
} triangle3d_regs;
union { lpbus_regs regs;
char dummy[-(0xff00 - 0xff5c)];
} lbp_regs;
} mm_virge_regs ;
#define mmtr volatile mm_virge_regs *
#define SET_WRT_MASK(msk) /* */
#define SET_RD_MASK(msk) /* */
#define SET_FRGD_COLOR(col) /* */
#define SET_BKGD_COLOR(col) /* */
#define SET_FRGD_MIX(fmix) /* */
#define SET_BKGD_MIX(bmix) /* */
#define SET_PIX_CNTL(val) /* */
#define SET_MIN_AXIS_PCNT(min) /* */
#define SET_MAJ_AXIS_PCNT(maj) /* */
#define SET_CURPT(c_x, c_y) /* */
#define SET_CUR_X(c_x) /* */
#define SET_CUR_Y(c_y) /* */
#define SET_DESTSTP(x,y) /* */
#define SET_AXIS_PCNT(maj, min) /* */
#define SET_CMD(c_d) /* */
#define SET_ERR_TERM(e) /* */
#define SET_SCISSORS(x1,y1,x2,y2) /* */
#define SET_SCISSORS_RB(x,y) /* */
#define SET_MULT_MISC(val) /* */
#define SET_PIX_TRANS_W(val) /* */
#define SET_PIX_TRANS_L(val) /* */
#define SET_MIX(fmix,bmix) /* */
#endif /* 0 */
/*
* reads from SUBSYS_STAT
*/
#define IN_SUBSYS_STAT() (INREG(SUBSYS_STAT_REG))
#define SET_SUBSYS_CRTL(val) do { write_mem_barrier();\
OUTREG((val), SUBSYS_STAT_REG);\
write_mem_barrier(); } while (0)
#if 0
#define SET_DAC_W_INDEX(index) OUTREG8(DAC_W_INDEX, index)
#define SET_DAC_DATA(val) OUTREG8(DAC_DATA,val)
#endif
#if 0
#define IMG_TRANS (((mmtr)s3vMmioMem)->img)
#define SET_PIXTRANS(a,v) IMG_TRANS[a] = (v)
#define COLOR_PATTERN (((mmtr)s3vMmioMem)->colpatt_regs.regs)
#define CMD_DMA_BASE(val) (((mmtr)s3vMmioMem)->dma_regs.regs.cmd.base_addr) = (val)
#define CMD_DMA_WRITEP(val) (((mmtr)s3vMmioMem)->dma_regs.regs.cmd.write_pointer) = (val)
#define CMD_DMA_READP(val) (((mmtr)s3vMmioMem)->dma_regs.regs.cmd.read_pointer) = (val)
#define CMD_DMA_ENABLE(val) (((mmtr)s3vMmioMem)->dma_regs.regs.cmd.dma_enable) = (val)
#define SETB_SRC_BASE(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.src_base = (val)
#define SETB_DEST_BASE(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.dest_base = (val)
#define SETB_CLIP_L_R(l,r) ((mmtr)s3vMmioMem)->bltfill_regs.regs.clip_l_r = ((l)<<16 | (r))
#define SETB_CLIP_T_B(t,b) ((mmtr)s3vMmioMem)->bltfill_regs.regs.clip_t_b = ((t)<<16 | (b))
/* #define SETB_DEST_SRC_STR(d,s) ((mmtr)s3vMmioMem)->bltfill_regs.regs.dest_src_str = ((d)<<16 | (s)) */
#define SETB_DEST_SRC_STR(d, s) (OUTREG(DEST_SRC_STR, ((d) << 16 | (s))))
#define SETB_MONO_PAT0(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.mono_pat0 = (val)
#define SETB_MONO_PAT1(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.mono_pat1 = (val)
#define SETB_PAT_BG_CLR(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.pat_bg_clr = (val)
#define SETB_PAT_FG_CLR(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.pat_fg_clr = (val)
#define SETB_SRC_BG_CLR(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.src_bg_clr = (val)
#define SETB_SRC_FG_CLR(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.src_fg_clr = (val)
#define SETB_CMD_SET(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->bltfill_regs.regs.cmd_set = (val); write_mem_barrier(); } while (0)
#define SETB_RWIDTH_HEIGHT(w,h) ((mmtr)s3vMmioMem)->bltfill_regs.regs.rwidth_height = ((w)<<16 | (h))
#define SETB_RSRC_XY(x,y) ((mmtr)s3vMmioMem)->bltfill_regs.regs.rsrc_xy = ((x)<<16 | (y))
#define SETB_RDEST_XY(x,y) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->bltfill_regs.regs.rdest_xy = ((x)<<16 | (y)); write_mem_barrier(); } while (0)
/* Caching version of the same MACROs */
#define CACHE_SETB_CLIP_L_R(l,r) do { unsigned int clip = ((l)<<16 | (r)); if (s3vCached_CLIP_LR != clip) { ((mmtr)s3vMmioMem)->bltfill_regs.regs.clip_l_r = clip; s3vCached_CLIP_LR = clip; s3vCacheMiss++;} else s3vCacheHit++;} while(0)
#define CACHE_SETB_CLIP_T_B(t,b) do { unsigned int clip = ((t)<<16 | (b)); if (s3vCached_CLIP_TB != clip) { ((mmtr)s3vMmioMem)->bltfill_regs.regs.clip_t_b = clip; s3vCached_CLIP_TB = clip; s3vCacheMiss++;} else s3vCacheHit++;} while(0)
#define CACHE_SETB_RSRC_XY(x,y) do { unsigned int src = ((x)<<16 | (y)); if (s3vCached_RSRC_XY != src) { ((mmtr)s3vMmioMem)->bltfill_regs.regs.rsrc_xy = src; s3vCached_RSRC_XY = src; s3vCacheMiss++;} else s3vCacheHit++;} while(0)
#define CACHE_SETB_RWIDTH_HEIGHT(w,h) do { unsigned int rwh = ((w)<<16 | (h)); if (s3vCached_RWIDTH_HEIGHT != rwh) { ((mmtr)s3vMmioMem)->bltfill_regs.regs.rwidth_height = rwh; s3vCached_RWIDTH_HEIGHT = rwh; s3vCacheMiss++;} else s3vCacheHit++;} while(0)
#define CACHE_SETB_MONO_PAT0(val) do { \
if (s3vCached_MONO_PATTERN0 != (val)) { \
((mmtr)s3vMmioMem)->bltfill_regs.regs.mono_pat0 = (val); \
s3vCached_MONO_PATTERN0 = (val); \
s3vCacheMiss++; \
} else s3vCacheHit++; \
} while(0)
#define CACHE_SETB_MONO_PAT1(val) do { \
if (s3vCached_MONO_PATTERN1 != (val)) { \
((mmtr)s3vMmioMem)->bltfill_regs.regs.mono_pat1 = (val); \
s3vCached_MONO_PATTERN1 = (val); \
s3vCacheMiss++; \
} else s3vCacheHit++;\
} while(0)
#define CACHE_SETB_PAT_FG_CLR(val) do { \
if (s3vCached_PAT_FGCLR != (val)) { \
((mmtr)s3vMmioMem)->bltfill_regs.regs.pat_fg_clr = (val); \
s3vCached_PAT_FGCLR = (val); \
s3vCacheMiss++; \
} else s3vCacheHit++; \
} while(0)
#define CACHE_SETB_PAT_BG_CLR(val) do { \
if (s3vCached_PAT_BGCLR != (val)) { \
((mmtr)s3vMmioMem)->bltfill_regs.regs.pat_bg_clr = (val); \
s3vCached_PAT_BGCLR = (val); \
s3vCacheMiss++; \
} else s3vCacheHit++; \
} while(0)
#define CACHE_SETB_CMD_SET(val) do { \
if (s3vCached_CMD_SET != (val)) { \
write_mem_barrier(); \
((mmtr)s3vMmioMem)->bltfill_regs.regs.cmd_set = (val); \
s3vCached_CMD_SET = (val); \
s3vCacheMiss++; \
write_mem_barrier(); \
} else s3vCacheHit++; \
} while(0)
#define SETL_SRC_BASE(val) ((mmtr)s3vMmioMem)->line_regs.regs.src_base = (val)
#define SETL_DEST_BASE(val) ((mmtr)s3vMmioMem)->line_regs.regs.dest_base = (val)
#define SETL_CLIP_L_R(l,r) ((mmtr)s3vMmioMem)->line_regs.regs.clip_l_r = ((l)<<16 | (r))
#define SETL_CLIP_T_B(t,b) ((mmtr)s3vMmioMem)->line_regs.regs.clip_t_b = ((t)<<16 | (b))
#define SETL_DEST_SRC_STR(d,s) ((mmtr)s3vMmioMem)->line_regs.regs.dest_src_str = ((d)<<16 | (s))
#define SETL_PAT_FG_CLR(val) ((mmtr)s3vMmioMem)->line_regs.regs.pat_fg_clr = (val)
#define SETL_CMD_SET(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->line_regs.regs.cmd_set = (val); write_mem_barrier(); } while (0)
#define SETL_LXEND0_END1(e0,e1) ((mmtr)s3vMmioMem)->line_regs.regs.lxend0_end1 = ((e0)<<16 | (e1))
#define SETL_LDX(val) ((mmtr)s3vMmioMem)->line_regs.regs.ldx = (val)
#define SETL_LXSTART(val) ((mmtr)s3vMmioMem)->line_regs.regs.lxstart = (val)
#define SETL_LYSTART(val) ((mmtr)s3vMmioMem)->line_regs.regs.lystart = (val)
#define SETL_LYCNT(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->line_regs.regs.lycnt = (val); write_mem_barrier(); } while (0)
/* Cache version */
#define CACHE_SETL_CMD_SET(val) do { if (s3vCached_CMD_SET != val) { write_mem_barrier(); ((mmtr)s3vMmioMem)->line_regs.regs.cmd_set = val; s3vCached_CMD_SET = val; s3vCacheMiss++; write_mem_barrier(); } else s3vCacheHit++;} while(0)
#define SETP_SRC_BASE(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.src_base = (val)
#define SETP_DEST_BASE(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.dest_base = (val)
#define SETP_CLIP_L_R(l,r) ((mmtr)s3vMmioMem)->polyfill_regs.regs.clip_l_r = ((l)<<16 | (r))
#define SETP_CLIP_T_B(t,b) ((mmtr)s3vMmioMem)->polyfill_regs.regs.clip_t_b = ((t)<<16 | (b))
#define SETP_DEST_SRC_STR(d,s) ((mmtr)s3vMmioMem)->polyfill_regs.regs.dest_src_str = ((d)<<16 | (s))
#define SETP_MONO_PAT0(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.mono_pat0 = (val)
#define SETP_MONO_PAT1(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.mono_pat1 = (val)
#define SETP_PAT_BG_CLR(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.pat_bg_clr = (val)
#define SETP_PAT_FG_CLR(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.pat_fg_clr = (val)
#define SETP_CMD_SET(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->polyfill_regs.regs.cmd_set = (val); write_mem_barrier(); } while (0)
#define SETP_RWIDTH_HEIGHT(w,h) ((mmtr)s3vMmioMem)->polyfill_regs.regs.rwidth_height = ((w)<<16 | (h))
#define SETP_PRDX(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.prdx = (val)
#define SETP_PRXSTART(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.prxstart = (val)
#define SETP_PLDX(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.pldx = (val)
#define SETP_PLXSTART(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.plxstart = (val)
#define SETP_PYSTART(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.pystart = (val)
#define SETP_PYCNT(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->polyfill_regs.regs.pycnt = (val); write_mem_barrier(); } while (0)
/* Cache version */
#define CACHE_SETP_CMD_SET(val) do { if (s3vCached_CMD_SET != val) { write_mem_barrier(); ((mmtr)s3vMmioMem)->polyfill_regs.regs.cmd_set = val; s3vCached_CMD_SET = val; s3vCacheMiss++; write_mem_barrier(); } else s3vCacheHit++;} while(0)
#define SETL3_Z_BASE(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.z_base = (val)
#define SETL3_DEST_BASE(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.dest_base = (val)
#define SETL3_CLIP_L_R(l,r) ((mmtr)s3vMmioMem)->line3d_regs.regs.clip_l_r = ((l)<<16 | (r))
#define SETL3_CLIP_T_B(t,b) ((mmtr)s3vMmioMem)->line3d_regs.regs.clip_t_b = ((t)<<16 | (b))
#define SETL3_DEST_SRC_STR(d,s) ((mmtr)s3vMmioMem)->line3d_regs.regs.dest_src_str = ((d)<<16 | (s))
#define SETL3_Z_STRIDE(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.z_stride = (val)
#define SETL3_FOG_CLR(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.fog_clr = (val)
#define SETL3_CMD_SET(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->line3d_regs.regs.cmd_set = (val); write_mem_barrier(); } while (0)
#define SETL3_DGDY_DBDY(dg,db) ((mmtr)s3vMmioMem)->line3d_regs.regs.dgdy_dbdy = ((dg)<<16 | (db))
#define SETL3_DADY_DRDY(da,dr) ((mmtr)s3vMmioMem)->line3d_regs.regs.dady_drdy = ((da)<<16 | (dr))
#define SETL3_GS_BS(gs,bs) ((mmtr)s3vMmioMem)->line3d_regs.regs.gs_bs = ((gs)<<16 | (bs))
#define SETL3_AS_RS(as,rs) ((mmtr)s3vMmioMem)->line3d_regs.regs.as_rs = ((as)<<16 | (rs))
#define SETL3_DZ(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.dz = (val)
#define SETL3_ZSTART(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.zstart = (val)
#define SETL3_XEND0_END1(e0,e1) ((mmtr)s3vMmioMem)->line3d_regs.regs.xend0_end1 = ((e0)<<16 | (e1))
#define SETL3_DX(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.dx = (val)
#define SETL3_XSTART(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.xstart = (val)
#define SETL3_YSTART(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.ystart = (val)
#define SETL3_YCNT(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->line3d_regs.regs.ycnt = (val); write_mem_barrier(); } while (0)
#define SETT3_Z_BASE(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.z_base = (val)
#define SETT3_DEST_BASE(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dest_base = (val)
#define SETT3_CLIP_L_R(l,r) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.clip_l_r = ((l)<<16 | (r))
#define SETT3_CLIP_T_B(t,b) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.clip_t_b = ((t)<<16 | (b))
#define SETT3_DEST_SRC_STR(d,s) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dest_src_str = ((d)<<16 | (s))
#define SETT3_Z_STRIDE(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.z_stride = (val)
#define SETT3_TEX_BASE(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.tex_base = (val)
#define SETT3_TEX_BDR_CLR(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.tex_bdr_clr = (val)
#define SETT3_FOG_CLR(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.fog_clr = (val)
#define SETT3_COLOR0(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.color0 = (val)
#define SETT3_COLOR1(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.color1 = (val)
#define SETT3_CMD_SET(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->triangle3d_regs.regs.cmd_set = (val); write_mem_barrier(); } while (0)
#define SETT3_BV(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.bv = (val)
#define SETT3_BU(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.bu = (val)
#define SETT3_DWDX(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dwdx = (val)
#define SETT3_DWDY(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dwdy = (val)
#define SETT3_WS(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.ws = (val)
#define SETT3_DDDX(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dddx = (val)
#define SETT3_DVDX(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dvdx = (val)
#define SETT3_DUDX(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dudx = (val)
#define SETT3_DDDY(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dddy = (val)
#define SETT3_DVDY(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dvdy = (val)
#define SETT3_DUDY(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dudy = (val)
#define SETT3_DS(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.ds = (val)
#define SETT3_VS(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.vs = (val)
#define SETT3_US(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.us = (val)
#define SETT3_DGDX_DBDX(gx,bx) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dgdx_dbdx = ((gx)<<16 | (bx))
#define SETT3_DADX_DRDX(ax,rx) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dadx_drdx = ((ax)<<16 | (rx))
#define SETT3_DGDY_DBDY(gy,by) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dgdy_dbdy = ((gy)<<16 | (by))
#define SETT3_DADY_DRDY(ay,ry) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dady_drdy = ((ay)<<16 | (ry))
#define SETT3_GS_BS(gs,bs) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.gs_bs = ((gs)<<16 | (bs))
#define SETT3_AS_RS(as,rs) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.as_rs = ((as)<<16 | (rs))
#define SETT3_DZDX(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dzdx = (val)
#define SETT3_DZDY(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dzdy = (val)
#define SETT3_ZS(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.zs = (val)
#define SETT3_DXDY12(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dxdy12 = (val)
#define SETT3_XEND12(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.xend12 = (val)
#define SETT3_DXDY01(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dxdy01 = (val)
#define SETT3_XEND01(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.xend01 = (val)
#define SETT3_DXDY02(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dxdy02 = (val)
#define SETT3_XSTART02(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.xstart02 = (val)
#define SETT3_YSTART(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.ystart = (val)
#define SETT3_Y01_Y12(y01,y12) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->triangle3d_regs.regs.y01_y12 = ((y01)<<16 | (y12)); write_mem_barrier(); } while (0)
#define DBGOUT(p) /* OUTREG8(0x3bc,p) */
#endif /* 0 */
#endif /* _NEWMMIO_H */

310
src/regs3v.h Normal file
View File

@@ -0,0 +1,310 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/regs3v.h,v 1.9 2002/01/25 21:56:08 tsi Exp $ */
/*
Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
/*
* regs3v.h
*
* Port to 4.0 design level
*
* S3 ViRGE driver
*
* Portions based on code containing the following notices:
**********************************************************
*
* Written by Jake Richter Copyright (c) 1989, 1990 Panacea Inc., Londonderry,
* NH - All Rights Reserved
*
* This code may be freely incorporated in any program without royalty, as long
* as the copyright notice stays intact.
*
* Additions by Kevin E. Martin (martin@cs.unc.edu)
*
* KEVIN E. MARTIN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEVIN E. MARTIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
*/
/* Taken from accel/s3_virge code */
/* 23/03/97 S. Marineau: fixed bug with first Doubleword Offset macros
* and added macro CommandWaitIdle to wait for the command FIFO to empty
*/
#ifndef _REGS3V_H
#define _REGS3V_H
#define S3_ViRGE_SERIES(chip) ((chip&0xfff0)==0x31e0)
#define S3_ViRGE_GX2_SERIES(chip) (chip == S3_ViRGE_GX2 || chip == S3_TRIO_3D_2X)
#define S3_ViRGE_MX_SERIES(chip) (chip == S3_ViRGE_MX || chip == S3_ViRGE_MXP)
#define S3_ViRGE_MXP_SERIES(chip) (chip == S3_ViRGE_MXP)
#define S3_ViRGE_VX_SERIES(chip) ((chip&0xfff0)==0x3de0)
#define S3_TRIO_3D_SERIES(chip) (chip == S3_TRIO_3D)
#define S3_TRIO_3D_2X_SERIES(chip) (chip == S3_TRIO_3D_2X)
/* Chip tags */
#define PCI_S3_VENDOR_ID PCI_VENDOR_S3
#define S3_UNKNOWN 0
#define S3_ViRGE PCI_CHIP_VIRGE
#define S3_ViRGE_VX PCI_CHIP_VIRGE_VX
#define S3_ViRGE_DXGX PCI_CHIP_VIRGE_DXGX
#define S3_ViRGE_GX2 PCI_CHIP_VIRGE_GX2
#define S3_ViRGE_MX PCI_CHIP_VIRGE_MX
#define S3_ViRGE_MXP PCI_CHIP_VIRGE_MXP
#define S3_TRIO_3D PCI_CHIP_Trio3D
#define S3_TRIO_3D_2X PCI_CHIP_Trio3D_2X
/* Subsystem Control Register */
#define GPCTRL_NC 0x0000
#define GPCTRL_ENAB 0x4000
#define GPCTRL_RESET 0x8000
/* Command Register */
#define CMD_OP_MSK (0xf << 27)
#define CMD_BITBLT (0x0 << 27)
#define CMD_RECT ((0x2 << 27) | 0x0100)
#define CMD_LINE (0x3 << 27)
#define CMD_POLYFILL (0x5 << 27)
#define CMD_NOP (0xf << 27)
#define BYTSEQ 0
#define _16BIT 0
#define PCDATA 0x80
#define INC_Y CMD_YP
#define YMAJAXIS 0
#define INC_X CMD_XP
#define DRAW 0x0020
#define LINETYPE 0x0008
#define LASTPIX 0
#define PLANAR 0 /* MIX_MONO_SRC */
#define WRTDATA 0
/*
* Short Stroke Vector Transfer Register (The angular Defs also apply to the
* Command Register
*/
#define VECDIR_000 0x0000
#define VECDIR_045 0x0020
#define VECDIR_090 0x0040
#define VECDIR_135 0x0060
#define VECDIR_180 0x0080
#define VECDIR_225 0x00a0
#define VECDIR_270 0x00c0
#define VECDIR_315 0x00e0
#define SSVDRAW 0x0010
/* Command AutoExecute */
#define CMD_AUTOEXEC 0x01
/* Command Hardware Clipping Enable */
#define CMD_HWCLIP 0x02
/* Destination Color Format */
#define DST_8BPP 0x00
#define DST_16BPP 0x04
#define DST_24BPP 0x08
/* BLT Mix modes */
#define MIX_BITBLT 0x0000
#define MIX_MONO_SRC 0x0040
#define MIX_CPUDATA 0x0080
#define MIX_MONO_PATT 0x0100
#define MIX_COLOR_PATT 0x0000
#define MIX_MONO_TRANSP 0x0200
/* Image Transfer Alignments */
#define CMD_ITA_BYTE 0x0000
#define CMD_ITA_WORD 0x0400
#define CMD_ITA_DWORD 0x0800
/* First Doubleword Offset (Image Transfer) */
#define CMD_FDO_BYTE0 0x00000
#define CMD_FDO_BYTE1 0x01000
#define CMD_FDO_BYTE2 0x02000
#define CMD_FDO_BYTE3 0x03000
/* X Positive, Y Positive (Bit BLT) */
#define CMD_XP 0x2000000
#define CMD_YP 0x4000000
/* 2D or 3D Select */
#define CMD_2D 0x00000000
#define CMD_3D 0x80000000
/* The Mix ROPs (selected ones, not all 256) */
#if 0
#define ROP_0 (0x00<<17)
#define ROP_DSon (0x11<<17)
#define ROP_DSna (0x22<<17)
#define ROP_Sn (0x33<<17)
#define ROP_SDna (0x44<<17)
#define ROP_Dn (0x55<<17)
#define ROP_DSx (0x66<<17)
#define ROP_DSan (0x77<<17)
#define ROP_DSa (0x88<<17)
#define ROP_DSxn (0x99<<17)
#define ROP_D (0xaa<<17)
#define ROP_DSno (0xbb<<17)
#define ROP_S (0xcc<<17)
#define ROP_SDno (0xdd<<17)
#define ROP_DSo (0xee<<17)
#define ROP_1 (0xff<<17)
/* ROP -> (ROP & P) | (D & ~P) */
#define ROP_0_PaDPnao /* DPna */ (0x0a<<17)
#define ROP_DSon_PaDPnao /* PDSPaox */ (0x1a<<17)
#define ROP_DSna_PaDPnao /* DPSana */ (0x2a<<17)
#define ROP_Sn_PaDPnao /* SPDSxox */ (0x3a<<17)
#define ROP_SDna_PaDPnao /* DPSDoax */ (0x4a<<17)
#define ROP_Dn_PaDPnao /* DPx */ (0x5a<<17)
#define ROP_DSx_PaDPnao /* DPSax */ (0x6a<<17)
#define ROP_DSan_PaDPnao /* DPSDnoax */ (0x7a<<17)
#define ROP_DSa_PaDPnao /* DSPnoa */ (0x8a<<17)
#define ROP_DSxn_PaDPnao /* DPSnax */ (0x9a<<17)
#define ROP_D_PaDPnao /* D */ (0xaa<<17)
#define ROP_DSno_PaDPnao /* DPSnao */ (0xba<<17)
#define ROP_S_PaDPnao /* DPSDxax */ (0xca<<17)
#define ROP_SDno_PaDPnao /* DPSDanax */ (0xda<<17)
#define ROP_DSo_PaDPnao /* DPSao */ (0xea<<17)
#define ROP_1_PaDPnao /* DPo */ (0xfa<<17)
/* S -> P */
#define ROP_DPon (0x05<<17)
#define ROP_DPna (0x0a<<17)
#define ROP_Pn (0x0f<<17)
#define ROP_PDna (0x50<<17)
#define ROP_DPx (0x5a<<17)
#define ROP_DPan (0x5f<<17)
#define ROP_DPa (0xa0<<17)
#define ROP_DPxn (0xa5<<17)
#define ROP_DPno (0xaf<<17)
#define ROP_P (0xf0<<17)
#define ROP_PDno (0xf5<<17)
#define ROP_DPo (0xfa<<17)
/* ROP -> (ROP & S) | (~ROP & D) */
#define ROP_DPSDxax (0xca<<17)
#define ROP_DSPnoa (0x8a<<17)
#define ROP_DPSao (0xea<<17)
#define ROP_DPSoa (0xa8<<17)
#define ROP_DSa (0x88<<17)
#define ROP_SSPxDSxax (0xe8<<17)
#define ROP_SDPoa (0xc8<<17)
#define ROP_DSPnao (0xae<<17)
#define ROP_SSDxPDxax (0x8e<<17)
#define ROP_DSo (0xee<<17)
#define ROP_SDPnao (0xce<<17)
#define ROP_SPDSxax (0xac<<17)
#define ROP_SDPnoa (0x8c<<17)
#define ROP_SDPao (0xec<<17)
/* ROP_sp -> (ROP_sp & S) | (D & ~S) */
#define ROP_0_SaDSnao /* DSna */ (0x22<<17)
#define ROP_DPa_SaDSnao /* DPSnoa */ (0xa2<<17)
#define ROP_PDna_SaDSnao /* DSPDoax */ (0x62<<17)
#define ROP_P_SaDSnao /* DSPDxax */ (0xe2<<17)
#define ROP_DPna_SaDSnao /* DPSana */ (0x2a<<17)
#define ROP_D_SaDSnao /* D */ (0xaa<<17)
#define ROP_DPx_SaDSnao /* DPSax */ (0x6a<<17)
#define ROP_DPo_SaDSnao /* DPSao */ (0xea<<17)
#define ROP_DPon_SaDSnao /* SDPSaox */ (0x26<<17)
#define ROP_DPxn_SaDSnao /* DSPnax */ (0xa6<<17)
#define ROP_Dn_SaDSnao /* DSx */ (0x66<<17)
#define ROP_PDno_SaDSnao /* SDPSanax */ (0xe6<<17)
#define ROP_Pn_SaDSnao /* PSDPxox */ (0x2e<<17)
#define ROP_DPno_SaDSnao /* DSPnao */ (0xae<<17)
#define ROP_DPan_SaDSnao /* SDPSnoax */ (0x6e<<17)
#define ROP_1_SaDSnao /* DSo */ (0xee<<17)
#endif
#define MAXLOOP 0x0fffff /* timeout value for engine waits, 0.5 secs */
/* Wait until "v" queue entries are free */
#define WaitQueue(v) \
if (ps3v->NoPCIRetry) { \
do { int loop=0; mem_barrier(); \
while ((((IN_SUBSYS_STAT()) & 0x1f00) < (((v)+2) << 8)) && (loop++<MAXLOOP)); \
if (loop >= MAXLOOP) S3VGEReset(pScrn,1,__LINE__,__FILE__); \
} while (0); }
/* Wait until GP is idle and queue is empty */
#define WaitIdleEmpty() \
do { int loop=0; mem_barrier(); \
if(S3_TRIO_3D_SERIES(ps3v->Chipset)) \
while (((IN_SUBSYS_STAT() & 0x3f802000 & 0x20002000) != 0x20002000) && \
(loop++<MAXLOOP)); \
else \
while (((IN_SUBSYS_STAT() & 0x3f00) != 0x3000) && (loop++<MAXLOOP)); \
if (loop >= MAXLOOP) S3VGEReset(pScrn,1,__LINE__,__FILE__); \
} while (0)
/* Wait until GP is idle */
#define WaitIdle() \
do { int loop=0; mem_barrier(); \
while ((!(IN_SUBSYS_STAT() & 0x2000)) && (loop++<MAXLOOP)); \
if (loop >= MAXLOOP) S3VGEReset(pScrn,1,__LINE__,__FILE__); \
} while (0)
/* Wait until Command FIFO is empty */
#define WaitCommandEmpty() do { int loop=0; mem_barrier(); \
if (S3_ViRGE_GX2_SERIES(S3_ViRGE_GX2) || S3_ViRGE_MX_SERIES(ps3v->Chipset)) \
while ((!(((((mmtr)s3vMmioMem)->subsys_regs.regs.adv_func_cntl)) & 0x400)) && (loop++<MAXLOOP)); \
else if (S3_TRIO_3D_SERIES(ps3v->Chipset)) \
while (((IN_SUBSYS_STAT() & 0x5f00) != 0x5f00) && (loop++<MAXLOOP)); \
else \
while ((!(((((mmtr)s3vMmioMem)->subsys_regs.regs.adv_func_cntl)) & 0x200)) && (loop++<MAXLOOP)); \
if (loop >= MAXLOOP) S3VGEReset(pScrn,1,__LINE__,__FILE__); \
} while (0)
/* Wait until a DMA transfer is done */
#define WaitDMAEmpty() \
do { int loop=0; mem_barrier(); \
while (((((mmtr)s3vMmioMem)->dma_regs.regs.cmd.write_pointer) != (((mmtr)s3vMmioMem)->dma_regs.regs.cmd.read_pointer)) && (loop++<MAXLOOP)); \
if (loop >= MAXLOOP) S3VGEReset(pScrn,1,__LINE__,__FILE__); \
} while(0)
#define RGB8_PSEUDO (-1)
#define RGB16_565 0
#define RGB16_555 1
#define RGB32_888 2
#endif /* _REGS3V_H */

435
src/s3v.h Normal file
View File

@@ -0,0 +1,435 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v.h,v 1.31 2003/02/04 02:20:49 dawes Exp $ */
/*
Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
#ifndef _S3V_H
#define _S3V_H
/* All drivers should typically include these */
#include "xf86.h"
#include "xf86_OSproc.h"
/* All drivers need this */
#include "xf86_ansic.h"
/* Everything using inb/outb, etc needs "compiler.h" */
#include "compiler.h"
/* Drivers for PCI hardware need this */
#include "xf86PciInfo.h"
/* Drivers that need to access the PCI config space directly need this */
#include "xf86Pci.h"
#include "xf86Cursor.h"
#include "vgaHW.h"
#include "s3v_macros.h"
/* All drivers initialising the SW cursor need this */
#include "mipointer.h"
/* All drivers using the mi colormap manipulation need this */
#include "micmap.h"
/* Drivers using cfb need this */
#define PSZ 8
#include "cfb.h"
#undef PSZ
/* Drivers supporting bpp 16, 24 or 32 with cfb need these */
#include "cfb16.h"
#include "cfb24.h"
#include "cfb32.h"
#include "cfb24_32.h"
/* fb support */
#include "fb.h"
/* Drivers using the XAA interface ... */
#include "xaa.h"
#include "xaalocal.h"
#include "xf86cmap.h"
#include "xf86i2c.h"
#include "vbe.h"
#include "xf86xv.h"
#include "Xv.h"
#include "fourcc.h"
#ifndef _S3V_VGAHWMMIO_H
#define _S3V_VGAHWMMIO_H
#define VGAIN8(addr) MMIO_IN8(ps3v->MapBase,(S3V_MMIO_REGSIZE + (addr)))
#define VGAIN16(addr) MMIO_IN16(ps3v->MapBase,(S3V_MMIO_REGSIZE + (addr)))
#define VGAIN(addr) MMIO_IN32(ps3v->MapBase,(S3V_MMIO_REGSIZE + (addr)))
#define VGAOUT8(addr,val) MMIO_OUT8(ps3v->MapBase,(S3V_MMIO_REGSIZE + (addr)),\
val)
#define VGAOUT16(addr,val) MMIO_OUT16(ps3v->MapBase,\
(S3V_MMIO_REGSIZE + (addr)), val)
#define VGAOUT(addr, val) MMIO_OUT32(ps3v->MapBase,\
(S3V_MMIO_REGSIZE + (addr)), val)
#define INREG(addr) MMIO_IN32(ps3v->MapBase, addr)
#define OUTREG(addr, val) MMIO_OUT32(ps3v->MapBase, addr, val)
#define NEW_INREG(addr) MMIO_IN32(s3vMmioMem, addr)
#define NEW_OUTREG(addr, val) MMIO_OUT32(s3vMmioMem, addr, val)
#endif /*_S3V_VGAHWMMIO_H*/
/******************* s3v_i2c ****************************/
Bool S3V_I2CInit(ScrnInfoPtr pScrn);
/******************* s3v_accel ****************************/
void S3VGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file);
/*********************************************/
/* locals */
/* Some S3 ViRGE structs */
#include "newmmio.h"
/* More ViRGE defines */
#include "regs3v.h"
/*********************************************/
/* Driver data structure; this should contain all needed info for a mode */
/* used to be in s3v_driver.h for pre 4.0 */
typedef struct {
unsigned char SR08, SR0A, SR0F;
unsigned char SR10, SR11, SR12, SR13, SR15, SR18; /* SR9-SR1C, ext seq. */
unsigned char SR29;
unsigned char SR54, SR55, SR56, SR57;
unsigned char Clock;
unsigned char s3DacRegs[0x101];
unsigned char CR31, CR33, CR34, CR36, CR3A, CR3B, CR3C;
unsigned char CR40, CR41, CR42, CR43, CR45;
unsigned char CR51, CR53, CR54, CR55, CR58, CR5D, CR5E;
unsigned char CR63, CR65, CR66, CR67, CR68, CR69, CR6D; /* Video attrib. */
unsigned char CR7B, CR7D;
unsigned char CR85, CR86, CR87;
unsigned char CR90, CR91, CR92, CR93;
unsigned char ColorStack[8]; /* S3 hw cursor color stack CR4A/CR4B */
unsigned int STREAMS[22]; /* Streams regs */
unsigned int MMPR0, MMPR1, MMPR2, MMPR3; /* MIU regs */
} S3VRegRec, *S3VRegPtr;
/*********************************/
/* S3VPortPrivRec */
/*********************************/
typedef struct {
unsigned char brightness;
unsigned char contrast;
FBAreaPtr area;
RegionRec clip;
CARD32 colorKey;
CARD32 videoStatus;
Time offTime;
Time freeTime;
int lastPort;
} S3VPortPrivRec, *S3VPortPrivPtr;
/*************************/
/* S3VRec */
/*************************/
typedef struct tagS3VRec {
/* accel additions */
CARD32 AccelFlags;
CARD32 AccelCmd;
CARD32 SrcBaseY, DestBaseY;
CARD32 Stride;
CARD32 CommonCmd;
CARD32 FullPlaneMask;
GCPtr CurrentGC;
/* fb support */
DrawablePtr CurrentDrawable;
/* end accel stuff */
/* ViRGE specifics -start- */
/* Xv support */
XF86VideoAdaptorPtr adaptor;
S3VPortPrivPtr portPrivate;
/* S3V console saved mode registers */
S3VRegRec SavedReg;
/* XServer video state mode registers */
S3VRegRec ModeReg;
/* HW Cursor info */
xf86CursorInfoPtr CursorInfoRec;
/* Flag indicating ModeReg has been */
/* duped from console state. */
Bool ModeStructInit;
/* Is STREAMS processor needed for */
/* this mode? */
Bool NeedSTREAMS;
/* Is STREAMS running now ? */
Bool STREAMSRunning;
/* Compatibility variables */
int vgaCRIndex, vgaCRReg;
int Width, Bpp,Bpl, ScissB;
/* XAA */
unsigned PlaneMask;
int bltbug_width1, bltbug_width2;
/* In units as noted, set in PreInit */
int videoRambytes;
int videoRamKbytes;
/* In Kbytes, set in PreInit */
int MemOffScreen;
/* Holds the virtual memory address */
/* returned when the MMIO registers */
/* are mapped with xf86MapPciMem */
unsigned char * MapBase;
unsigned char * MapBaseDense;
/* Same as MapBase, except framebuffer*/
unsigned char * FBBase;
/* Current visual FB starting location */
unsigned char * FBStart;
/* Cursor storage location */
CARD32 FBCursorOffset;
/* Saved CR53 value */
unsigned char EnableMmioCR53;
/* Extended reg unlock storage */
unsigned char CR38,CR39,CR40;
/* Flag indicating if vgaHWMapMem was */
/* used successfully for this screen */
Bool PrimaryVidMapped;
/* Clock value */
int dacSpeedBpp;
int minClock;
/* Maximum clock for present bpp */
int maxClock;
int HorizScaleFactor;
Bool bankedMono;
/* Memory Clock */
int MCLK;
/* input reference Clock */
int REFCLK;
/* MX LCD clock */
int LCDClk;
/* MX reference clock scale */
double refclk_fact;
/* Limit the number of errors */
/* printed using a counter */
int GEResetCnt;
/* Accel WaitFifo function */
void (*pWaitFifo)(struct tagS3VRec *, int);
/* Accel WaitCmd function */
void (*pWaitCmd)(struct tagS3VRec *);
/*************************/
/* ViRGE options -start- */
/*************************/
OptionInfoPtr Options;
/* Enable PCI burst mode for reads? */
Bool pci_burst;
/* Diasable PCI retries */
Bool NoPCIRetry;
/* Adjust fifo for acceleration? */
Bool fifo_conservative;
Bool fifo_moderate;
Bool fifo_aggressive;
/* Set memory options */
Bool slow_edodram;
Bool slow_dram;
Bool fast_dram;
Bool fpm_vram;
/* Disable Acceleration */
Bool NoAccel;
/* Adjust memory ras precharge */
/* timing */
Bool ShowCache;
Bool early_ras_precharge;
Bool late_ras_precharge;
/* MX LCD centering */
Bool lcd_center;
/* hardware cursor enabled */
Bool hwcursor;
Bool UseFB;
Bool mx_cr3a_fix;
Bool XVideo;
/* ViRGE options -end- */
/***********************/
/* ViRGE specifics -end- */
/* Used by ViRGE driver, but generic */
/* Pointer used to save wrapped */
/* CloseScreen function. */
CloseScreenProcPtr CloseScreen;
/* XAA info Rec */
XAAInfoRecPtr AccelInfoRec;
/* PCI info vars. */
pciVideoPtr PciInfo;
PCITAG PciTag;
/* Chip info, set using PCI */
/* above. */
int Chipset;
int ChipRev;
/* DGA2 */
DGAModePtr DGAModes;
int numDGAModes;
Bool DGAactive;
int DGAViewportStatus;
I2CBusPtr I2C;
vbeInfoPtr pVbe;
Bool shadowFB;
int rotate;
unsigned char * ShadowPtr;
int ShadowPitch;
void (*PointerMoved)(int index, int x, int y);
/* Used by ViRGE driver, but generic -end- */
} S3VRec, *S3VPtr;
#define S3VPTR(p) ((S3VPtr)((p)->driverPrivate))
/* #define S3V_DEBUG */
#ifdef S3V_DEBUG
#define PVERB5(arg) ErrorF(arg)
#define VERBLEV 1
#else
#define PVERB5(arg) xf86ErrorFVerb(5, arg)
#define VERBLEV 5
#endif
/******************* regs3v *******************************/
/* cep kjb */
#define VertDebug 1
/* #ifndef MetroLink */
#if !defined (MetroLink) && !defined (VertDebug)
#define VerticalRetraceWait() do { \
VGAOUT8(vgaCRIndex, 0x17); \
if ( VGAIN8(vgaCRReg) & 0x80 ) { \
while ((VGAIN8(vgaIOBase + 0x0A) & 0x08) == 0x00) ; \
while ((VGAIN8(vgaIOBase + 0x0A) & 0x08) == 0x08) ; \
while ((VGAIN8(vgaIOBase + 0x0A) & 0x08) == 0x00) ; \
}\
} while (0)
#else
#define SPIN_LIMIT 1000000
#define VerticalRetraceWait() do { \
VGAOUT8(vgaCRIndex, 0x17); \
if ( VGAIN8(vgaCRReg) & 0x80 ) { \
volatile unsigned long _spin_me; \
for (_spin_me = 0; \
((VGAIN8(vgaIOBase + 0x0A) & 0x08) == 0x00) && _spin_me <= SPIN_LIMIT; \
_spin_me++) ; \
if (_spin_me > SPIN_LIMIT) \
ErrorF("s3v: warning: VerticalRetraceWait timed out(1:3).\n"); \
for (_spin_me = 0; \
((VGAIN8(vgaIOBase + 0x0A) & 0x08) == 0x08) && _spin_me <= SPIN_LIMIT; \
_spin_me++) ; \
if (_spin_me > SPIN_LIMIT) \
ErrorF("s3v: warning: VerticalRetraceWait timed out(2:3).\n"); \
for (_spin_me = 0; \
((VGAIN8(vgaIOBase + 0x0A) & 0x08) == 0x00) && _spin_me <= SPIN_LIMIT; \
_spin_me++) ; \
if (_spin_me > SPIN_LIMIT) \
ErrorF("s3v: warning: VerticalRetraceWait timed out(3:3).\n"); \
} \
} while (0)
#endif
/*********************************************************/
/* Various defines which are used to pass flags between the Setup and
* Subsequent functions.
*/
#define NO_MONO_FILL 0x00
#define NEED_MONO_FILL 0x01
#define MONO_TRANSPARENCY 0x02
/* prototypes */
/* s3v_dac.c */
extern void S3VCommonCalcClock(ScrnInfoPtr pScrn, DisplayModePtr mode,
long freq, int min_m, int min_n1, int max_n1,
int min_n2, int max_n2, long freq_min, long freq_max,
unsigned char * mdiv, unsigned char * ndiv);
/* s3v_accel.c */
extern Bool S3VAccelInit(ScreenPtr pScreen);
extern Bool S3VAccelInit32(ScreenPtr pScreen);
void S3VAccelSync(ScrnInfoPtr);
void S3VWaitFifoGX2(S3VPtr ps3v, int slots );
void S3VWaitFifoMain(S3VPtr ps3v, int slots );
void S3VWaitCmdGX2(S3VPtr ps3v);
void S3VWaitDummy(S3VPtr ps3v);
/* s3v_hwcurs.c */
extern Bool S3VHWCursorInit(ScreenPtr pScreen);
/* s3v_driver.c */
void S3VAdjustFrame(int scrnIndex, int x, int y, int flags);
Bool S3VSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
/* s3v_dga.c */
Bool S3VDGAInit(ScreenPtr pScreen);
/* in s3v_shadow.c */
void s3vPointerMoved(int index, int x, int y);
void s3vRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void s3vRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void s3vRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void s3vRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void s3vRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
/* s3v_xv.c X Video Extension support */
void S3VInitVideo(ScreenPtr pScreen);
int S3VQueryXvCapable(ScrnInfoPtr);
#endif /*_S3V_H*/
/*EOF*/

1081
src/s3v_accel.c Normal file

File diff suppressed because it is too large Load Diff

121
src/s3v_dac.c Normal file
View File

@@ -0,0 +1,121 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dac.c,v 1.4 2003/02/04 02:20:50 dawes Exp $ */
/*
Copyright (C) 1994-1998 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
/*
* s3v_dac.c
* Port to 4.0 design level
*
* S3 ViRGE driver
*
*
* s3vcommonCalcClock from S3gendac.c in pre 4.0 tree.
*
*/
#include "s3v.h"
#define BASE_FREQ 14.31818 /* MHz */
/* function */
void
S3VCommonCalcClock(ScrnInfoPtr pScrn, DisplayModePtr mode,
long freq, int min_m, int min_n1,
int max_n1, int min_n2, int max_n2,
long freq_min, long freq_max,
unsigned char * mdiv, unsigned char * ndiv)
{
double ffreq, ffreq_min, ffreq_max, ffreq_min_warn;
double div, diff, best_diff;
unsigned int m;
unsigned char n1, n2;
unsigned char best_n1=16+2, best_n2=2, best_m=125+2;
ffreq = freq / 1000.0 / BASE_FREQ;
ffreq_min = freq_min / 1000.0 / BASE_FREQ;
ffreq_max = freq_max / 1000.0 / BASE_FREQ;
/* Doublescan modes can run at half the min frequency */
/* But only use that value for warning and changing */
/* ffreq, don't change the actual min used for clock calcs below. */
if(mode->Flags & V_DBLSCAN && ffreq_min)
ffreq_min_warn = ffreq_min / 2;
else
ffreq_min_warn = ffreq_min;
if (ffreq < ffreq_min_warn / (1<<max_n2)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"invalid frequency %1.3f MHz [freq <= %1.3f MHz]\n",
ffreq*BASE_FREQ, ffreq_min_warn*BASE_FREQ / (1<<max_n2));
ffreq = ffreq_min_warn / (1<<max_n2);
}
if (ffreq > ffreq_max / (1<<min_n2)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"invalid frequency %1.3f MHz [freq >= %1.3f MHz]\n",
ffreq*BASE_FREQ, ffreq_max*BASE_FREQ / (1<<min_n2));
ffreq = ffreq_max / (1<<min_n2);
}
/* work out suitable timings */
best_diff = ffreq;
for (n2=min_n2; n2<=max_n2; n2++) {
for (n1 = min_n1+2; n1 <= max_n1+2; n1++) {
m = (int)(ffreq * n1 * (1<<n2) + 0.5) ;
if (m < min_m+2 || m > 127+2)
continue;
div = (double)(m) / (double)(n1);
if ((div >= ffreq_min) &&
(div <= ffreq_max)) {
diff = ffreq - div / (1<<n2);
if (diff < 0.0)
diff = -diff;
if (diff < best_diff) {
best_diff = diff;
best_m = m;
best_n1 = n1;
best_n2 = n2;
}
}
}
}
#ifdef EXTENDED_DEBUG
ErrorF("Clock parameters for %1.6f MHz: m=%d, n1=%d, n2=%d\n",
((double)(best_m) / (double)(best_n1) / (1 << best_n2)) * BASE_FREQ,
best_m-2, best_n1-2, best_n2);
#endif
if (max_n1 == 63)
*ndiv = (best_n1 - 2) | (best_n2 << 6);
else
*ndiv = (best_n1 - 2) | (best_n2 << 5);
*mdiv = best_m - 2;
}

359
src/s3v_dga.c Normal file
View File

@@ -0,0 +1,359 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dga.c,v 1.7 2002/01/14 18:02:58 dawes Exp $ */
/*
Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
/*
Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
/*
* file: s3v_dga.c
* ported from mga
*
*/
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "xf86Pci.h"
#include "xf86PciInfo.h"
#include "xaa.h"
#include "xaalocal.h"
#include "s3v.h"
#if 0
#include "mga_bios.h"
#include "mga.h"
#include "mga_reg.h"
#include "mga_macros.h"
#endif
#include "dgaproc.h"
static Bool S3V_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
int *, int *, int *);
static Bool S3V_SetMode(ScrnInfoPtr, DGAModePtr);
static int S3V_GetViewport(ScrnInfoPtr);
static void S3V_SetViewport(ScrnInfoPtr, int, int, int);
static void S3V_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
static void S3V_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
/* dummy... */
#if 0
static void MGA_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
unsigned long);
#endif
static
DGAFunctionRec S3V_DGAFuncs = {
S3V_OpenFramebuffer,
NULL,
S3V_SetMode,
S3V_SetViewport,
S3V_GetViewport,
S3VAccelSync,
S3V_FillRect,
S3V_BlitRect,
NULL
/* dummy... MGA_BlitTransRect */
};
Bool
S3VDGAInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
S3VPtr ps3v = S3VPTR(pScrn);
DGAModePtr modes = NULL, newmodes = NULL, currentMode;
DisplayModePtr pMode, firstMode;
int Bpp = pScrn->bitsPerPixel >> 3;
int num = 0;
Bool oneMore;
PVERB5(" S3VDGAInit\n");
pMode = firstMode = pScrn->modes;
while(pMode) {
/* The MGA driver wasn't designed with switching depths in
mind. Subsequently, large chunks of it will probably need
to be rewritten to accommodate depth changes in DGA mode */
if(0 /*pScrn->displayWidth != pMode->HDisplay*/) {
newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec));
oneMore = TRUE;
} else {
newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
oneMore = FALSE;
}
if(!newmodes) {
xfree(modes);
return FALSE;
}
modes = newmodes;
SECOND_PASS:
currentMode = modes + num;
num++;
currentMode->mode = pMode;
currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
if(!ps3v->NoAccel)
currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
if(pMode->Flags & V_DBLSCAN)
currentMode->flags |= DGA_DOUBLESCAN;
if(pMode->Flags & V_INTERLACE)
currentMode->flags |= DGA_INTERLACED;
currentMode->byteOrder = pScrn->imageByteOrder;
currentMode->depth = pScrn->depth;
currentMode->bitsPerPixel = pScrn->bitsPerPixel;
currentMode->red_mask = pScrn->mask.red;
currentMode->green_mask = pScrn->mask.green;
currentMode->blue_mask = pScrn->mask.blue;
currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
currentMode->viewportWidth = pMode->HDisplay;
currentMode->viewportHeight = pMode->VDisplay;
/* currentMode->xViewportStep = (3 - ps3v->BppShift); */
/* always 1 on ViRGE ? */
currentMode->xViewportStep = 1;
currentMode->yViewportStep = 1;
currentMode->viewportFlags = DGA_FLIP_RETRACE;
/* currentMode->offset = ps3v->YDstOrg * (pScrn->bitsPerPixel / 8);
* MGA, 0 for ViRGE */
currentMode->offset = 0;
/* currentMode->address = pMga->FbStart; MGA */
currentMode->address = ps3v->FBBase;
/*cep*/
xf86ErrorFVerb(VERBLEV,
" S3VDGAInit firstone vpWid=%d, vpHgt=%d, Bpp=%d, mdbitsPP=%d\n",
currentMode->viewportWidth,
currentMode->viewportHeight,
Bpp,
currentMode->bitsPerPixel
);
if(oneMore) { /* first one is narrow width */
currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
currentMode->imageWidth = pMode->HDisplay;
/* currentMode->imageHeight = pMga->FbUsableSize /
currentMode->bytesPerScanline;
MGA above */
currentMode->imageHeight = pMode->VDisplay;
currentMode->pixmapWidth = currentMode->imageWidth;
currentMode->pixmapHeight = currentMode->imageHeight;
currentMode->maxViewportX = currentMode->imageWidth -
currentMode->viewportWidth;
/* this might need to get clamped to some maximum */
currentMode->maxViewportY = currentMode->imageHeight -
currentMode->viewportHeight;
oneMore = FALSE;
/*cep*/
xf86ErrorFVerb(VERBLEV,
" S3VDGAInit imgHgt=%d, ram=%d, bytesPerScanl=%d\n",
currentMode->imageHeight,
ps3v->videoRambytes,
currentMode->bytesPerScanline );
goto SECOND_PASS;
} else {
currentMode->bytesPerScanline =
((pScrn->displayWidth * Bpp) + 3) & ~3L;
currentMode->imageWidth = pScrn->displayWidth;
/* currentMode->imageHeight = pMga->FbUsableSize /
currentMode->bytesPerScanline;
*/
currentMode->imageHeight = ps3v->videoRambytes /
currentMode->bytesPerScanline;
currentMode->pixmapWidth = currentMode->imageWidth;
currentMode->pixmapHeight = currentMode->imageHeight;
currentMode->maxViewportX = currentMode->imageWidth -
currentMode->viewportWidth;
/* this might need to get clamped to some maximum */
currentMode->maxViewportY = currentMode->imageHeight -
currentMode->viewportHeight;
}
pMode = pMode->next;
if(pMode == firstMode)
break;
}
ps3v->numDGAModes = num;
ps3v->DGAModes = modes;
return DGAInit(pScreen, &S3V_DGAFuncs, modes, num);
}
static Bool
S3V_SetMode(
ScrnInfoPtr pScrn,
DGAModePtr pMode
){
static int OldDisplayWidth[MAXSCREENS];
int index = pScrn->pScreen->myNum;
S3VPtr ps3v = S3VPTR(pScrn);
if(!pMode) { /* restore the original mode */
/* put the ScreenParameters back */
pScrn->displayWidth = OldDisplayWidth[index];
S3VSwitchMode(index, pScrn->currentMode, 0);
ps3v->DGAactive = FALSE;
} else {
if(!ps3v->DGAactive) { /* save the old parameters */
OldDisplayWidth[index] = pScrn->displayWidth;
ps3v->DGAactive = TRUE;
}
pScrn->displayWidth = pMode->bytesPerScanline /
(pMode->bitsPerPixel >> 3);
S3VSwitchMode(index, pMode->mode, 0);
}
return TRUE;
}
static int
S3V_GetViewport(
ScrnInfoPtr pScrn
){
S3VPtr ps3v = S3VPTR(pScrn);
return ps3v->DGAViewportStatus;
}
static void
S3V_SetViewport(
ScrnInfoPtr pScrn,
int x, int y,
int flags
){
S3VPtr ps3v = S3VPTR(pScrn);
S3VAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
ps3v->DGAViewportStatus = 0; /* MGAAdjustFrame loops until finished */
}
static void
S3V_FillRect (
ScrnInfoPtr pScrn,
int x, int y, int w, int h,
unsigned long color
){
S3VPtr ps3v = S3VPTR(pScrn);
if(ps3v->AccelInfoRec) {
(*ps3v->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
(*ps3v->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
SET_SYNC_FLAG(ps3v->AccelInfoRec);
}
}
static void
S3V_BlitRect(
ScrnInfoPtr pScrn,
int srcx, int srcy,
int w, int h,
int dstx, int dsty
){
S3VPtr ps3v = S3VPTR(pScrn);
if(ps3v->AccelInfoRec) {
int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
int ydir = (srcy < dsty) ? -1 : 1;
(*ps3v->AccelInfoRec->SetupForScreenToScreenCopy)(
pScrn, xdir, ydir, GXcopy, ~0, -1);
(*ps3v->AccelInfoRec->SubsequentScreenToScreenCopy)(
pScrn, srcx, srcy, dstx, dsty, w, h);
SET_SYNC_FLAG(ps3v->AccelInfoRec);
}
}
#if 0
static void
MGA_BlitTransRect(
ScrnInfoPtr pScrn,
int srcx, int srcy,
int w, int h,
int dstx, int dsty,
unsigned long color
){
/* this one should be separate since the XAA function would
prohibit usage of ~0 as the key */
}
#endif
static Bool
S3V_OpenFramebuffer(
ScrnInfoPtr pScrn,
char **name,
unsigned char **mem,
int *size,
int *offset,
int *flags
){
S3VPtr ps3v = S3VPTR(pScrn);
*name = NULL; /* no special device */
*mem = (unsigned char*)ps3v->PciInfo->memBase[0];
*size = ps3v->videoRambytes;
*offset = 0;
*flags = DGA_NEED_ROOT;
return TRUE;
}

4039
src/s3v_driver.c Normal file

File diff suppressed because it is too large Load Diff

263
src/s3v_hwcurs.c Normal file
View File

@@ -0,0 +1,263 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_hwcurs.c,v 1.7 2003/02/04 02:20:50 dawes Exp $ */
/*
Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
/*
* s3v_hwcurs.c
* HW Cursor support for 4.0 design level
*
* S3 ViRGE driver
*
*
*/
#include "s3v.h"
/* protos */
static void S3VLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
static void S3VShowCursor(ScrnInfoPtr pScrn);
static void S3VHideCursor(ScrnInfoPtr pScrn);
static void S3VSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
static void S3VSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
/*
* Read/write to the DAC via MMIO
*/
#define inCRReg(reg) (VGAHWPTR(pScrn))->readCrtc( VGAHWPTR(pScrn), reg )
#define outCRReg(reg, val) (VGAHWPTR(pScrn))->writeCrtc( VGAHWPTR(pScrn), reg, val )
/****
*** HW Cursor
*/
static void
S3VLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
{
S3VPtr ps3v = S3VPTR(pScrn);
/*PVERB5(" S3VLoadCursorImage\n");*/
/* Load storage location. */
outCRReg( HWCURSOR_ADDR_LOW_CR4D, 0xff & (ps3v->FBCursorOffset/1024));
outCRReg( HWCURSOR_ADDR_HIGH_CR4C, (0x0f00 & (ps3v->FBCursorOffset/1024)) >> 8);
/* Copy cursor image to framebuffer storage */
memcpy( (ps3v->FBBase + ps3v->FBCursorOffset), src, 1024);
}
static void
S3VShowCursor(ScrnInfoPtr pScrn)
{
char tmp;
tmp = inCRReg(HWCURSOR_MODE_CR45);
/* Enable cursor */
outCRReg(HWCURSOR_MODE_CR45, tmp | 1 );
}
static void
S3VHideCursor(ScrnInfoPtr pScrn)
{
char tmp;
tmp = inCRReg(HWCURSOR_MODE_CR45);
/* Disable cursor */
outCRReg(HWCURSOR_MODE_CR45, tmp & ~1 );
}
static void
S3VSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
unsigned char xoff = 0, yoff = 0;
/*
if (!xf86VTSema)
return;
*/
/*
x -= s3vHotX;
y -= s3vHotY;
*/
/*
* Make these even when used. There is a bug/feature on at least
* some chipsets that causes a "shadow" of the cursor in interlaced
* mode. Making this even seems to have no visible effect, so just
* do it for the generic case.
* note - xoff & yoff are used for displaying partial cursors on screen
* edges.
*/
if (x < 0) {
xoff = ((-x) & 0xFE);
x = 0;
}
if (y < 0) {
yoff = ((-y) & 0xFE);
y = 0;
}
/* Double y position for a doublescan mode */
if(pScrn->currentMode->Flags & V_DBLSCAN) y <<= 1;
/* This is the recommended order to move the cursor */
outCRReg( 0x46, (x & 0xff00)>>8 );
outCRReg( 0x47, (x & 0xff) );
outCRReg( 0x49, (y & 0xff) );
outCRReg( 0x4e, xoff );
outCRReg( 0x4f, yoff );
outCRReg( 0x48, (y & 0xff00)>>8 );
}
static void
S3VSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
S3VPtr ps3v = S3VPTR(pScrn);
/*PVERB5(" S3VSetCursorColors\n");*/
switch( pScrn->bitsPerPixel) {
case 8:
if (!(S3_ViRGE_GX2_SERIES(ps3v->Chipset) || S3_ViRGE_MX_SERIES(ps3v->Chipset))) {
/* Reset the cursor color stack pointer */
inCRReg(0x45);
/* Write foreground */
outCRReg(0x4a, fg);
outCRReg(0x4a, fg);
/* Reset the cursor color stack pointer */
inCRReg(0x45);
/* Write background */
outCRReg(0x4b, bg);
outCRReg(0x4b, bg);
break;
} /* else fall through for ViRGE/MX... */
case 16:
if (!(S3_ViRGE_GX2_SERIES(ps3v->Chipset) || S3_ViRGE_MX_SERIES(ps3v->Chipset))) {
/* adjust colors to 16 bits */
if (pScrn->weight.green == 5 && ps3v->Chipset != S3_ViRGE_VX) {
fg = ((fg & 0xf80000) >> 9) |
((fg & 0xf800) >> 6) |
((fg & 0xf8) >> 3);
bg = ((bg & 0xf80000) >> 9) |
((bg & 0xf800) >> 6) |
((bg & 0xf8) >> 3);
} else {
fg = ((fg & 0xf80000) >> 8) |
((fg & 0xfc00) >> 5) |
((fg & 0xf8) >> 3);
bg = ((bg & 0xf80000) >> 8) |
((bg & 0xfc00) >> 5) |
((bg & 0xf8) >> 3);
}
inCRReg(0x45);
/* Write foreground */
outCRReg(0x4a, fg);
outCRReg(0x4a, fg >> 8);
/* needed for 2nd pixel in double-clock modes */
outCRReg(0x4a, fg);
outCRReg(0x4a, fg >> 8);
/* Reset the cursor color stack pointer */
inCRReg(0x45);
/* Write background */
outCRReg(0x4b, bg);
outCRReg(0x4b, bg >> 8);
/* needed for 2nd pixel in double-clock modes */
outCRReg(0x4b, bg);
outCRReg(0x4b, bg >> 8);
break;
} /* else fall through for ViRGE/MX... */
case 24:
case 32:
/* Do it straight, full 24 bit color. */
/* Reset the cursor color stack pointer */
inCRReg(0x45);
/* Write low, mid, high bytes - foreground */
outCRReg(0x4a, fg);
outCRReg(0x4a, fg >> 8);
outCRReg(0x4a, fg >> 16);
/* Reset the cursor color stack pointer */
inCRReg(0x45);
/* Write low, mid, high bytes - background */
outCRReg(0x4b, bg);
outCRReg(0x4b, bg >> 8);
outCRReg(0x4b, bg >> 16);
break;
}
}
Bool
S3VHWCursorInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
S3VPtr ps3v = S3VPTR(pScrn);
xf86CursorInfoPtr infoPtr;
PVERB5(" S3VHWCursorInit\n");
infoPtr = xf86CreateCursorInfoRec();
if(!infoPtr) return FALSE;
ps3v->CursorInfoRec = infoPtr;
infoPtr->MaxWidth = 64;
infoPtr->MaxHeight = 64;
infoPtr->Flags = HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 |
HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
if (S3_ViRGE_GX2_SERIES(ps3v->Chipset) || S3_ViRGE_MX_SERIES(ps3v->Chipset))
infoPtr->Flags |= HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
HARDWARE_CURSOR_INVERT_MASK;
infoPtr->SetCursorColors = S3VSetCursorColors;
infoPtr->SetCursorPosition = S3VSetCursorPosition;
infoPtr->LoadCursorImage = S3VLoadCursorImage;
infoPtr->HideCursor = S3VHideCursor;
infoPtr->ShowCursor = S3VShowCursor;
infoPtr->UseHWCursor = NULL;
return(xf86InitCursor(pScreen, infoPtr));
}
/*EOF*/

116
src/s3v_i2c.c Normal file
View File

@@ -0,0 +1,116 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_i2c.c,v 1.4 2000/03/31 20:13:32 dawes Exp $ */
/*
Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
/*
Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "compiler.h"
#include "xf86Pci.h"
#include "xf86PciInfo.h"
#include "vgaHW.h"
#include "s3v.h"
static void
s3v_I2CPutBits(I2CBusPtr b, int clock, int data)
{
S3VPtr ps3v = S3VPTR(xf86Screens[b->scrnIndex]);
unsigned int reg = 0x10;
if(clock) reg |= 0x1;
if(data) reg |= 0x2;
OUTREG(DDC_REG,reg);
/*ErrorF("s3v_I2CPutBits: %d %d\n", clock, data); */
}
static void
s3v_I2CGetBits(I2CBusPtr b, int *clock, int *data)
{
S3VPtr ps3v = S3VPTR(xf86Screens[b->scrnIndex]);
unsigned int reg;
reg = (INREG(DDC_REG));
*clock = reg & 0x4;
*data = reg & 0x8;
/*ErrorF("s3v_I2CGetBits: %d %d\n", *clock, *data);*/
}
Bool
S3V_I2CInit(ScrnInfoPtr pScrn)
{
S3VPtr ps3v = S3VPTR(pScrn);
I2CBusPtr I2CPtr;
I2CPtr = xf86CreateI2CBusRec();
if(!I2CPtr) return FALSE;
ps3v->I2C = I2CPtr;
I2CPtr->BusName = "I2C bus";
I2CPtr->scrnIndex = pScrn->scrnIndex;
I2CPtr->I2CPutBits = s3v_I2CPutBits;
I2CPtr->I2CGetBits = s3v_I2CGetBits;
if (!xf86I2CBusInit(I2CPtr))
return FALSE;
return TRUE;
}

127
src/s3v_macros.h Normal file
View File

@@ -0,0 +1,127 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_macros.h,v 1.11 2000/11/28 20:59:18 dawes Exp $ */
/*
Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
#ifndef _S3V_MACROS_H
#define _S3V_MACROS_H
/* use these macros and INREG/OUTREG to access the extended registers
of s3 virge -- add any others you need here */
/* miscellaneous registers */
#define SUBSYS_STAT_REG 0x8504
#define ADV_FUNC_CNTR 0x850c
/* memory port controller registers */
#define FIFO_CONTROL_REG 0x8200
#define MIU_CONTROL_REG 0x8204
#define STREAMS_TIMEOUT_REG 0x8208
#define MISC_TIMEOUT_REG 0x820c
/* Cursor Registers */
#define HWCURSOR_MODE_CR45 0x45
#define HWCURSOR_ADDR_LOW_CR4D 0x4d
#define HWCURSOR_ADDR_HIGH_CR4C 0x4c
/* streams registers */
#define PSTREAM_CONTROL_REG 0x8180
#define COL_CHROMA_KEY_CONTROL_REG 0x8184
#define SSTREAM_CONTROL_REG 0x8190
#define CHROMA_KEY_UPPER_BOUND_REG 0x8194
#define SSTREAM_STRETCH_REG 0x8198
#define BLEND_CONTROL_REG 0x81A0
#define PSTREAM_FBADDR0_REG 0x81C0
#define PSTREAM_FBADDR1_REG 0x81C4
#define PSTREAM_STRIDE_REG 0x81C8
#define DOUBLE_BUFFER_REG 0x81CC
#define SSTREAM_FBADDR0_REG 0x81D0
#define SSTREAM_FBADDR1_REG 0x81D4
#define SSTREAM_STRIDE_REG 0x81D8
#define OPAQUE_OVERLAY_CONTROL_REG 0x81DC
#define K1_VSCALE_REG 0x81E0
#define K2_VSCALE_REG 0x81E4
#define DDA_VERT_REG 0x81E8
#define STREAMS_FIFO_REG 0x81EC
#define PSTREAM_START_REG 0x81F0
#define PSTREAM_WINDOW_SIZE_REG 0x81F4
#define SSTREAM_START_REG 0x81F8
#define SSTREAM_WINDOW_SIZE_REG 0x81FC
/* image write stuff */
#define SRC_BASE 0xA4D4
#define DEST_BASE 0xA4D8
#define CLIP_L_R 0xA4DC
#define CLIP_T_B 0xA4E0
#define DEST_SRC_STR 0xA4E4
#define MONO_PAT_0 0xA4E8
#define MONO_PAT_1 0xA4EC
#define PAT_BG_CLR 0xA4F0
#define PAT_FG_CLR 0xA4F4
#define SRC_BG_CLR 0xA4F8
#define SRC_FG_CLR 0xA4FC
#define CMD_SET 0xA500
#define RWIDTH_HEIGHT 0xA504
#define RSRC_XY 0xA508
#define RDEST_XY 0xA50C
/* Local Periperal Bus Registers */
#define DDC_REG 0xFF20
#define BLT_BUG 0x00000001
#define MONO_TRANS_BUG 0x00000002
#define MAXLOOP 0x0fffff /* timeout value for engine waits, 0.5 secs */
/* Switchable per chipset, must be initialized prior to a mode */
/* switch! */
#define WAITFIFO(n) ((*ps3v->pWaitFifo)(ps3v,n))
#define WAITCMD() ((*ps3v->pWaitCmd)(ps3v))
#define WAITIDLE()\
do { int loop=0; mem_barrier(); \
while(((INREG(SUBSYS_STAT_REG) & 0x3f00) < 0x3000) && (loop++<MAXLOOP)) \
if (loop >= MAXLOOP) S3VGEReset(pScrn,1,__LINE__,__FILE__); \
} while (0)
#define CHECK_DEST_BASE(y,h)\
if((y < ps3v->DestBaseY) || ((y + h) > (ps3v->DestBaseY + 2048))) {\
ps3v->DestBaseY = ((y + h) <= 2048) ? 0 : y;\
WAITFIFO(1);\
OUTREG(DEST_BASE, ps3v->DestBaseY * ps3v->Stride);\
}\
y -= ps3v->DestBaseY
#define CHECK_SRC_BASE(y,h)\
if((y < ps3v->SrcBaseY) || ((y + h) > (ps3v->SrcBaseY + 2048))) {\
ps3v->SrcBaseY = ((y + h) <= 2048) ? 0 : y;\
WAITFIFO(1);\
OUTREG(SRC_BASE, ps3v->SrcBaseY * ps3v->Stride);\
}\
y -= ps3v->SrcBaseY
#endif /* _S3V_MACROS_H */

207
src/s3v_rop.h Normal file
View File

@@ -0,0 +1,207 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_rop.h,v 1.3 1999/03/14 03:22:04 dawes Exp $ */
/*
Copyright (C) 1994-1998 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
/* This file contains the data structures which map the X ROPs to the
* ViRGE ROPs. It also contains other mappings which are used when supporting
* planemasks and transparency.
*
* Created by Sebastien Marineau, 29/03/97.
* This file should be included only from s3v_accel.c to avoid
* duplicate symbols.
*
*/
#include "regs3v.h"
static int s3vAlu[16] =
{
ROP_0, /* GXclear */
ROP_DSa, /* GXand */
ROP_SDna, /* GXandReverse */
ROP_S, /* GXcopy */
ROP_DSna, /* GXandInverted */
ROP_D, /* GXnoop */
ROP_DSx, /* GXxor */
ROP_DSo, /* GXor */
ROP_DSon, /* GXnor */
ROP_DSxn, /* GXequiv */
ROP_Dn, /* GXinvert*/
ROP_SDno, /* GXorReverse */
ROP_Sn, /* GXcopyInverted */
ROP_DSno, /* GXorInverted */
ROP_DSan, /* GXnand */
ROP_1 /* GXset */
};
/* S -> P, for solid and pattern fills. */
static int s3vAlu_sp[16]=
{
ROP_0,
ROP_DPa,
ROP_PDna,
ROP_P,
ROP_DPna,
ROP_D,
ROP_DPx,
ROP_DPo,
ROP_DPon,
ROP_DPxn,
ROP_Dn,
ROP_PDno,
ROP_Pn,
ROP_DPno,
ROP_DPan,
ROP_1
};
/* ROP -> (ROP & P) | (D & ~P) */
/* These are used to support a planemask for S->D ops */
static int s3vAlu_pat[16] =
{
ROP_0_PaDPnao,
ROP_DSa_PaDPnao,
ROP_SDna_PaDPnao,
ROP_S_PaDPnao,
ROP_DSna_PaDPnao,
ROP_D_PaDPnao,
ROP_DSx_PaDPnao,
ROP_DSo_PaDPnao,
ROP_DSon_PaDPnao,
ROP_DSxn_PaDPnao,
ROP_Dn_PaDPnao,
ROP_SDno_PaDPnao,
ROP_Sn_PaDPnao,
ROP_DSno_PaDPnao,
ROP_DSan_PaDPnao,
ROP_1_PaDPnao
};
/* ROP_sp -> (ROP_sp & S) | (D & ~S) */
/* This is used for our transparent mono pattern fills to support trans/plane*/
static int s3vAlu_MonoTrans[16] =
{
ROP_0_SaDSnao,
ROP_DPa_SaDSnao,
ROP_PDna_SaDSnao,
ROP_P_SaDSnao,
ROP_DPna_SaDSnao,
ROP_D_SaDSnao,
ROP_DPx_SaDSnao,
ROP_DPo_SaDSnao,
ROP_DPon_SaDSnao,
ROP_DPxn_SaDSnao,
ROP_Dn_SaDSnao,
ROP_PDno_SaDSnao,
ROP_Pn_SaDSnao,
ROP_DPno_SaDSnao,
ROP_DPan_SaDSnao,
ROP_1_SaDSnao
};
/* This function was taken from accel/s3v.h. It adjusts the width
* of transfers for mono images to works around some bugs.
*/
static __inline__ int S3VCheckLSPN(S3VPtr ps3v, int w, int dir)
{
int lspn = (w * ps3v->Bpp) & 63; /* scanline width in bytes modulo 64*/
if (ps3v->Bpp == 1) {
if (lspn <= 8*1)
w += 16;
else if (lspn <= 16*1)
w += 8;
} else if (ps3v->Bpp == 2) {
if (lspn <= 4*2)
w += 8;
else if (lspn <= 8*2)
w += 4;
} else { /* ps3v->Bpp == 3 */
if (lspn <= 3*3)
w += 6;
else if (lspn <= 6*3)
w += 3;
}
if (dir && w >= ps3v->bltbug_width1 && w <= ps3v->bltbug_width2) {
w = ps3v->bltbug_width2 + 1;
}
return w;
}
/* And this adjusts color bitblts widths to work around GE bugs */
static __inline__ int S3VCheckBltWidth(S3VPtr ps3v, int w)
{
if (w >= ps3v->bltbug_width1 && w <= ps3v->bltbug_width2) {
w = ps3v->bltbug_width2 + 1;
}
return w;
}
/* This next function determines if the Source operand is present in the
* given ROP. The rule is that both the lower and upper nibble of the rop
* have to be neither 0x00, 0x05, 0x0a or 0x0f. If a CPU-Screen blit is done
* with a ROP which does not contain the source, the virge will hang when
* data is written to the image transfer area.
*/
static __inline__ Bool S3VROPHasSrc(int shifted_rop)
{
int rop = (shifted_rop & (0xff << 17)) >> 17;
if ((((rop & 0x0f) == 0x0a) | ((rop & 0x0f) == 0x0f)
| ((rop & 0x0f) == 0x05) | ((rop & 0x0f) == 0x00)) &
(((rop & 0xf0) == 0xa0) | ((rop & 0xf0) == 0xf0)
| ((rop & 0xf0) == 0x50) | ((rop & 0xf0) == 0x00)))
return FALSE;
else
return TRUE;
}
/* This next function determines if the Destination operand is present in the
* given ROP. The rule is that both the lower and upper nibble of the rop
* have to be neither 0x00, 0x03, 0x0c or 0x0f.
*/
static __inline__ Bool S3VROPHasDst(int shifted_rop)
{
int rop = (shifted_rop & (0xff << 17)) >> 17;
if ((((rop & 0x0f) == 0x0c) | ((rop & 0x0f) == 0x0f)
| ((rop & 0x0f) == 0x03) | ((rop & 0x0f) == 0x00)) &
(((rop & 0xf0) == 0xc0) | ((rop & 0xf0) == 0xf0)
| ((rop & 0xf0) == 0x30) | ((rop & 0xf0) == 0x00)))
return FALSE;
else
return TRUE;
}

301
src/s3v_shadow.c Normal file
View File

@@ -0,0 +1,301 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_shadow.c,v 1.3 2000/03/31 20:13:33 dawes Exp $ */
/*
Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
/*
Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation 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 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, FIT-
NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
Except as contained in this notice, the name of the XFree86 Project shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the XFree86 Project.
*/
/*
Copyright (c) 1999,2000 The XFree86 Project Inc.
based on code written by Mark Vojkovich <markv@valinux.com>
*/
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Resources.h"
#include "xf86_ansic.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#include "shadowfb.h"
#include "servermd.h"
#include "s3v.h"
void
s3vRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
S3VPtr ps3v = S3VPTR(pScrn);
int width, height, Bpp, FBPitch;
unsigned char *src, *dst;
Bpp = pScrn->bitsPerPixel >> 3;
FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
while(num--) {
width = (pbox->x2 - pbox->x1) * Bpp;
height = pbox->y2 - pbox->y1;
src = ps3v->ShadowPtr + (pbox->y1 * ps3v->ShadowPitch) +
(pbox->x1 * Bpp);
dst = ps3v->FBStart + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
while(height--) {
memcpy(dst, src, width);
dst += FBPitch;
src += ps3v->ShadowPitch;
}
pbox++;
}
}
void
s3vPointerMoved(int index, int x, int y)
{
ScrnInfoPtr pScrn = xf86Screens[index];
S3VPtr ps3v = S3VPTR(pScrn);
int newX, newY;
if(ps3v->rotate == 1) {
newX = pScrn->pScreen->height - y - 1;
newY = x;
} else {
newX = y;
newY = pScrn->pScreen->width - x - 1;
}
(*ps3v->PointerMoved)(index, newX, newY);
}
void
s3vRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
S3VPtr ps3v = S3VPTR(pScrn);
int count, width, height, y1, y2, dstPitch, srcPitch;
CARD8 *dstPtr, *srcPtr, *src;
CARD32 *dst;
dstPitch = pScrn->displayWidth;
srcPitch = -ps3v->rotate * ps3v->ShadowPitch;
while(num--) {
width = pbox->x2 - pbox->x1;
y1 = pbox->y1 & ~3;
y2 = (pbox->y2 + 3) & ~3;
height = (y2 - y1) >> 2; /* in dwords */
if(ps3v->rotate == 1) {
dstPtr = ps3v->FBStart +
(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
srcPtr = ps3v->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
} else {
dstPtr = ps3v->FBStart +
((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
srcPtr = ps3v->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
}
while(width--) {
src = srcPtr;
dst = (CARD32*)dstPtr;
count = height;
while(count--) {
*(dst++) = src[0] | (src[srcPitch] << 8) |
(src[srcPitch * 2] << 16) |
(src[srcPitch * 3] << 24);
src += srcPitch * 4;
}
srcPtr += ps3v->rotate;
dstPtr += dstPitch;
}
pbox++;
}
}
void
s3vRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
S3VPtr ps3v = S3VPTR(pScrn);
int count, width, height, y1, y2, dstPitch, srcPitch;
CARD16 *dstPtr, *srcPtr, *src;
CARD32 *dst;
dstPitch = pScrn->displayWidth;
srcPitch = -ps3v->rotate * ps3v->ShadowPitch >> 1;
while(num--) {
width = pbox->x2 - pbox->x1;
y1 = pbox->y1 & ~1;
y2 = (pbox->y2 + 1) & ~1;
height = (y2 - y1) >> 1; /* in dwords */
if(ps3v->rotate == 1) {
dstPtr = (CARD16*)ps3v->FBStart +
(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
srcPtr = (CARD16*)ps3v->ShadowPtr +
((1 - y2) * srcPitch) + pbox->x1;
} else {
dstPtr = (CARD16*)ps3v->FBStart +
((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
srcPtr = (CARD16*)ps3v->ShadowPtr +
(y1 * srcPitch) + pbox->x2 - 1;
}
while(width--) {
src = srcPtr;
dst = (CARD32*)dstPtr;
count = height;
while(count--) {
*(dst++) = src[0] | (src[srcPitch] << 16);
src += srcPitch * 2;
}
srcPtr += ps3v->rotate;
dstPtr += dstPitch;
}
pbox++;
}
}
/* this one could be faster */
void
s3vRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
S3VPtr ps3v = S3VPTR(pScrn);
int count, width, height, y1, y2, dstPitch, srcPitch;
CARD8 *dstPtr, *srcPtr, *src;
CARD32 *dst;
dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
srcPitch = -ps3v->rotate * ps3v->ShadowPitch;
while(num--) {
width = pbox->x2 - pbox->x1;
y1 = pbox->y1 & ~3;
y2 = (pbox->y2 + 3) & ~3;
height = (y2 - y1) >> 2; /* blocks of 3 dwords */
if(ps3v->rotate == 1) {
dstPtr = ps3v->FBStart +
(pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
srcPtr = ps3v->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
} else {
dstPtr = ps3v->FBStart +
((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
srcPtr = ps3v->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
}
while(width--) {
src = srcPtr;
dst = (CARD32*)dstPtr;
count = height;
while(count--) {
dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
(src[srcPitch] << 24);
dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
(src[srcPitch * 2] << 16) |
(src[(srcPitch * 2) + 1] << 24);
dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
(src[(srcPitch * 3) + 1] << 16) |
(src[(srcPitch * 3) + 2] << 24);
dst += 3;
src += srcPitch * 4;
}
srcPtr += ps3v->rotate * 3;
dstPtr += dstPitch;
}
pbox++;
}
}
void
s3vRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
S3VPtr ps3v = S3VPTR(pScrn);
int count, width, height, dstPitch, srcPitch;
CARD32 *dstPtr, *srcPtr, *src, *dst;
dstPitch = pScrn->displayWidth;
srcPitch = -ps3v->rotate * ps3v->ShadowPitch >> 2;
while(num--) {
width = pbox->x2 - pbox->x1;
height = pbox->y2 - pbox->y1;
if(ps3v->rotate == 1) {
dstPtr = (CARD32*)ps3v->FBStart +
(pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
srcPtr = (CARD32*)ps3v->ShadowPtr +
((1 - pbox->y2) * srcPitch) + pbox->x1;
} else {
dstPtr = (CARD32*)ps3v->FBStart +
((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
srcPtr = (CARD32*)ps3v->ShadowPtr +
(pbox->y1 * srcPitch) + pbox->x2 - 1;
}
while(width--) {
src = srcPtr;
dst = dstPtr;
count = height;
while(count--) {
*(dst++) = *src;
src += srcPitch;
}
srcPtr += ps3v->rotate;
dstPtr += dstPitch;
}
pbox++;
}
}

1175
src/s3v_xv.c Normal file

File diff suppressed because it is too large Load Diff