|
@@ -1,3 +1,45 @@
|
|
|
+
|
|
|
+/* Portions of this file derived from work with the following copyright */
|
|
|
+
|
|
|
+ /***************************************************************************\
|
|
|
+|* *|
|
|
|
+|* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
|
|
|
+|* *|
|
|
|
+|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
|
|
|
+|* international laws. Users and possessors of this source code are *|
|
|
|
+|* hereby granted a nonexclusive, royalty-free copyright license to *|
|
|
|
+|* use this code in individual and commercial software. *|
|
|
|
+|* *|
|
|
|
+|* Any use of this source code must include, in the user documenta- *|
|
|
|
+|* tion and internal comments to the code, notices to the end user *|
|
|
|
+|* as follows: *|
|
|
|
+|* *|
|
|
|
+|* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
|
|
|
+|* *|
|
|
|
+|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
|
|
|
+|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
|
|
|
+|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
|
|
|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
|
|
|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
|
|
|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
|
|
|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
|
|
|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
|
|
|
+|* SULTING 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 SOURCE CODE. *|
|
|
|
+|* *|
|
|
|
+|* U.S. Government End Users. This source code is a "commercial *|
|
|
|
+|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
|
|
|
+|* consisting of "commercial computer software" and "commercial *|
|
|
|
+|* computer software documentation," as such terms are used in *|
|
|
|
+|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
|
|
|
+|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
|
|
|
+|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
|
|
|
+|* all U.S. Government End Users acquire the source code with only *|
|
|
|
+|* those rights set forth herein. *|
|
|
|
+|* *|
|
|
|
+ \***************************************************************************/
|
|
|
+
|
|
|
#include "u.h"
|
|
|
#include "../port/lib.h"
|
|
|
#include "mem.h"
|
|
@@ -11,19 +53,31 @@
|
|
|
#include <memdraw.h>
|
|
|
#include <cursor.h>
|
|
|
#include "screen.h"
|
|
|
+#include "nv_dma.h"
|
|
|
|
|
|
enum {
|
|
|
Pramin = 0x00710000,
|
|
|
Pramdac = 0x00680000,
|
|
|
Fifo = 0x00800000,
|
|
|
- Pgraph = 0x00400000
|
|
|
+ Pgraph = 0x00400000,
|
|
|
+ Pfb = 0x00100000
|
|
|
};
|
|
|
|
|
|
enum {
|
|
|
hwCurPos = Pramdac + 0x0300,
|
|
|
- hwCurImage = Pramin + (0x00010000 - 0x0800),
|
|
|
};
|
|
|
|
|
|
+#define SKIPS 8
|
|
|
+
|
|
|
+struct {
|
|
|
+ ulong *dmabase;
|
|
|
+ int dmacurrent;
|
|
|
+ int dmaput;
|
|
|
+ int dmafree;
|
|
|
+ int dmamax;
|
|
|
+} nv;
|
|
|
+
|
|
|
+
|
|
|
/* Nvidia is good about backwards compatibility -- any did >= 0x20 is fine */
|
|
|
static Pcidev*
|
|
|
nvidiapci(void)
|
|
@@ -81,8 +135,8 @@ static void
|
|
|
nvidiaenable(VGAscr* scr)
|
|
|
{
|
|
|
Pcidev *p;
|
|
|
- ulong aperture;
|
|
|
- int align, size;
|
|
|
+ ulong aperture, *q;
|
|
|
+ int align, size, tmp;
|
|
|
|
|
|
/*
|
|
|
* Only once, can't be disabled for now.
|
|
@@ -109,6 +163,27 @@ nvidiaenable(VGAscr* scr)
|
|
|
scr->apsize = size;
|
|
|
addvgaseg("nvidiascreen", aperture, size);
|
|
|
}
|
|
|
+
|
|
|
+ /* find video memory size */
|
|
|
+ if (scr->id & 0x0F00) {
|
|
|
+ q = KADDR(scr->io + Pfb + 0x020C);
|
|
|
+ tmp = (*q >> 20) & 0xFF;
|
|
|
+ if (tmp == 0)
|
|
|
+ tmp = 16;
|
|
|
+ scr->storage = tmp*1024*1024;
|
|
|
+ } else {
|
|
|
+ q = KADDR(scr->io + Pfb);
|
|
|
+ tmp = *q;
|
|
|
+ if (tmp & 0x0100) {
|
|
|
+ scr->storage = ((tmp >> 12) & 0x0F) * 1024 + 1024 * 2;
|
|
|
+ } else {
|
|
|
+ tmp &= 0x03;
|
|
|
+ if (tmp)
|
|
|
+ scr->storage = (1024*1024*2) << tmp;
|
|
|
+ else
|
|
|
+ scr->storage = 1024*1024*32;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -120,6 +195,7 @@ nvidiacurdisable(VGAscr* scr)
|
|
|
vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static void
|
|
|
nvidiacurload(VGAscr* scr, Cursor* curs)
|
|
|
{
|
|
@@ -133,20 +209,14 @@ nvidiacurload(VGAscr* scr, Cursor* curs)
|
|
|
|
|
|
vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
|
|
|
|
|
|
- p = KADDR(scr->io + hwCurImage);
|
|
|
+ if (scr->id & 0x0F00)
|
|
|
+ p = KADDR(scr->aperture + scr->storage - 96*1024);
|
|
|
+ else
|
|
|
+ p = KADDR(scr->io + Pramin + 0x1E00 * 4);
|
|
|
|
|
|
for(i=0; i<16; i++) {
|
|
|
- switch(scr->id){
|
|
|
- default:
|
|
|
- c = (curs->clr[2 * i] << 8) | curs->clr[2 * i+1];
|
|
|
- s = (curs->set[2 * i] << 8) | curs->set[2 * i+1];
|
|
|
- break;
|
|
|
- case 0x171: /* for Geforece4 MX bug, K.Okamoto */
|
|
|
- case 0x181:
|
|
|
- c = (curs->clr[2 * i+1] << 8) | curs->clr[2 * i];
|
|
|
- s = (curs->set[2 * i+1] << 8) | curs->set[2 * i];
|
|
|
- break;
|
|
|
- }
|
|
|
+ c = (curs->clr[2 * i] << 8) | curs->clr[2 * i+1];
|
|
|
+ s = (curs->set[2 * i] << 8) | curs->set[2 * i+1];
|
|
|
tmp = 0;
|
|
|
for (j=0; j<16; j++){
|
|
|
if(s&0x8000)
|
|
@@ -203,34 +273,82 @@ nvidiacurenable(VGAscr* scr)
|
|
|
vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);
|
|
|
}
|
|
|
|
|
|
-enum {
|
|
|
- RopFifo = 0x00000000,
|
|
|
- ClipFifo = 0x00002000,
|
|
|
- PattFifo = 0x00004000,
|
|
|
- BltFifo = 0x00008000,
|
|
|
- BitmapFifo = 0x0000A000,
|
|
|
-};
|
|
|
+void
|
|
|
+writeput(VGAscr *scr, int data)
|
|
|
+{
|
|
|
+ uchar *p, scratch;
|
|
|
+ ulong *fifo;
|
|
|
|
|
|
-enum {
|
|
|
- RopRop3 = RopFifo + 0x300,
|
|
|
+ outb(0x3D0,0);
|
|
|
+ p=KADDR(scr->aperture);
|
|
|
+ scratch = *p;
|
|
|
+ fifo = KADDR(scr->io + Fifo);
|
|
|
+ fifo[0x10] = (data << 2);
|
|
|
+ USED(scratch);
|
|
|
+}
|
|
|
|
|
|
- ClipTopLeft = ClipFifo + 0x300,
|
|
|
- ClipWidthHeight = ClipFifo + 0x304,
|
|
|
+ulong
|
|
|
+readget(VGAscr *scr)
|
|
|
+{
|
|
|
+ ulong *fifo;
|
|
|
|
|
|
- PattShape = PattFifo + 0x0308,
|
|
|
- PattColor0 = PattFifo + 0x0310,
|
|
|
- PattColor1 = PattFifo + 0x0314,
|
|
|
- PattMonochrome0 = PattFifo + 0x0318,
|
|
|
- PattMonochrome1 = PattFifo + 0x031C,
|
|
|
+ fifo = KADDR(scr->io + Fifo);
|
|
|
+ return (fifo[0x0011] >> 2);
|
|
|
+}
|
|
|
|
|
|
- BltTopLeftSrc = BltFifo + 0x0300,
|
|
|
- BltTopLeftDst = BltFifo + 0x0304,
|
|
|
- BltWidthHeight = BltFifo + 0x0308,
|
|
|
+void
|
|
|
+nvdmakickoff(VGAscr *scr)
|
|
|
+{
|
|
|
+ if(nv.dmacurrent != nv.dmaput) {
|
|
|
+ nv.dmaput = nv.dmacurrent;
|
|
|
+ writeput(scr, nv.dmaput);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+nvdmanext(ulong data)
|
|
|
+{
|
|
|
+ nv.dmabase[nv.dmacurrent++] = data;
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+nvdmawait(VGAscr *scr, int size)
|
|
|
+{
|
|
|
+ int dmaget;
|
|
|
+
|
|
|
+ size++;
|
|
|
+
|
|
|
+ while(nv.dmafree < size) {
|
|
|
+ dmaget = readget(scr);
|
|
|
+
|
|
|
+ if(nv.dmaput >= dmaget) {
|
|
|
+ nv.dmafree = nv.dmamax - nv.dmacurrent;
|
|
|
+ if(nv.dmafree < size) {
|
|
|
+ nvdmanext(0x20000000);
|
|
|
+ if(dmaget <= SKIPS) {
|
|
|
+ if (nv.dmaput <= SKIPS) /* corner case - will be idle */
|
|
|
+ writeput(scr, SKIPS + 1);
|
|
|
+ do { dmaget = readget(scr); }
|
|
|
+ while(dmaget <= SKIPS);
|
|
|
+ }
|
|
|
+ writeput(scr, SKIPS);
|
|
|
+ nv.dmacurrent = nv.dmaput = SKIPS;
|
|
|
+ nv.dmafree = dmaget - (SKIPS + 1);
|
|
|
+ }
|
|
|
+ } else
|
|
|
+ nv.dmafree = dmaget - nv.dmacurrent - 1;
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- BitmapColor1A = BitmapFifo + 0x03FC,
|
|
|
- BitmapURect0TopLeft = BitmapFifo + 0x0400,
|
|
|
- BitmapURect0WidthHeight = BitmapFifo + 0x0404,
|
|
|
-};
|
|
|
+
|
|
|
+static void
|
|
|
+nvdmastart(VGAscr *scr, ulong tag, int size)
|
|
|
+{
|
|
|
+ if (nv.dmafree <= size)
|
|
|
+ nvdmawait(scr, size);
|
|
|
+ nvdmanext((size << 18) | tag);
|
|
|
+ nv.dmafree -= (size + 1);
|
|
|
+}
|
|
|
|
|
|
static void
|
|
|
waitforidle(VGAscr *scr)
|
|
@@ -240,6 +358,12 @@ waitforidle(VGAscr *scr)
|
|
|
|
|
|
pgraph = KADDR(scr->io + Pgraph);
|
|
|
|
|
|
+ x = 0;
|
|
|
+ while((readget(scr) != nv.dmaput) && x++ < 1000000)
|
|
|
+ ;
|
|
|
+ if(x >= 1000000)
|
|
|
+ iprint("idle stat %lud put %d scr %p pc %luX\n", readget(scr), nv.dmaput, scr, getcallerpc(&scr));
|
|
|
+
|
|
|
x = 0;
|
|
|
while(pgraph[0x00000700/4] & 0x01 && x++ < 1000000)
|
|
|
;
|
|
@@ -249,36 +373,104 @@ waitforidle(VGAscr *scr)
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-waitforfifo(VGAscr *scr, int fifo, int entries)
|
|
|
+nvresetgraphics(VGAscr *scr)
|
|
|
{
|
|
|
- ushort* fifofree;
|
|
|
- int x;
|
|
|
+ ulong surfaceFormat, patternFormat, rectFormat, lineFormat;
|
|
|
+ int pitch, i;
|
|
|
+
|
|
|
+ pitch = scr->gscreen->width*BY2WD;
|
|
|
+
|
|
|
+ nv.dmabase = KADDR(scr->aperture + scr->storage - 128*1024);
|
|
|
+
|
|
|
+ for(i=0; i<SKIPS; i++)
|
|
|
+ nv.dmabase[i] = 0x00000000;
|
|
|
+
|
|
|
+ nv.dmabase[0x0 + SKIPS] = 0x00040000;
|
|
|
+ nv.dmabase[0x1 + SKIPS] = 0x80000010;
|
|
|
+ nv.dmabase[0x2 + SKIPS] = 0x00042000;
|
|
|
+ nv.dmabase[0x3 + SKIPS] = 0x80000011;
|
|
|
+ nv.dmabase[0x4 + SKIPS] = 0x00044000;
|
|
|
+ nv.dmabase[0x5 + SKIPS] = 0x80000012;
|
|
|
+ nv.dmabase[0x6 + SKIPS] = 0x00046000;
|
|
|
+ nv.dmabase[0x7 + SKIPS] = 0x80000013;
|
|
|
+ nv.dmabase[0x8 + SKIPS] = 0x00048000;
|
|
|
+ nv.dmabase[0x9 + SKIPS] = 0x80000014;
|
|
|
+ nv.dmabase[0xA + SKIPS] = 0x0004A000;
|
|
|
+ nv.dmabase[0xB + SKIPS] = 0x80000015;
|
|
|
+ nv.dmabase[0xC + SKIPS] = 0x0004C000;
|
|
|
+ nv.dmabase[0xD + SKIPS] = 0x80000016;
|
|
|
+ nv.dmabase[0xE + SKIPS] = 0x0004E000;
|
|
|
+ nv.dmabase[0xF + SKIPS] = 0x80000017;
|
|
|
+
|
|
|
+ nv.dmaput = 0;
|
|
|
+ nv.dmacurrent = 16 + SKIPS;
|
|
|
+ nv.dmamax = 8191;
|
|
|
+ nv.dmafree = nv.dmamax - nv.dmacurrent;
|
|
|
+
|
|
|
+ switch(scr->gscreen->depth) {
|
|
|
+ case 32:
|
|
|
+ case 24:
|
|
|
+ surfaceFormat = SURFACE_FORMAT_DEPTH24;
|
|
|
+ patternFormat = PATTERN_FORMAT_DEPTH24;
|
|
|
+ rectFormat = RECT_FORMAT_DEPTH24;
|
|
|
+ lineFormat = LINE_FORMAT_DEPTH24;
|
|
|
+ break;
|
|
|
+ case 16:
|
|
|
+ case 15:
|
|
|
+ surfaceFormat = SURFACE_FORMAT_DEPTH16;
|
|
|
+ patternFormat = PATTERN_FORMAT_DEPTH16;
|
|
|
+ rectFormat = RECT_FORMAT_DEPTH16;
|
|
|
+ lineFormat = LINE_FORMAT_DEPTH16;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ surfaceFormat = SURFACE_FORMAT_DEPTH8;
|
|
|
+ patternFormat = PATTERN_FORMAT_DEPTH8;
|
|
|
+ rectFormat = RECT_FORMAT_DEPTH8;
|
|
|
+ lineFormat = LINE_FORMAT_DEPTH8;
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- x = 0;
|
|
|
- fifofree = KADDR(scr->io + Fifo + fifo + 0x10);
|
|
|
+ nvdmastart(scr, SURFACE_FORMAT, 4);
|
|
|
+ nvdmanext(surfaceFormat);
|
|
|
+ nvdmanext(pitch | (pitch << 16));
|
|
|
+ nvdmanext(0);
|
|
|
+ nvdmanext(0);
|
|
|
|
|
|
- while(((*fifofree >> 2) < entries) && x++ < 1000000)
|
|
|
- ;
|
|
|
+ nvdmastart(scr, PATTERN_FORMAT, 1);
|
|
|
+ nvdmanext(patternFormat);
|
|
|
|
|
|
- if(x >= 1000000)
|
|
|
- iprint("fifo stat %d scrio %.8lux scr %p pc %luX\n", *fifofree, scr->io, scr, getcallerpc(&scr));
|
|
|
+ nvdmastart(scr, RECT_FORMAT, 1);
|
|
|
+ nvdmanext(rectFormat);
|
|
|
+
|
|
|
+ nvdmastart(scr, LINE_FORMAT, 1);
|
|
|
+ nvdmanext(lineFormat);
|
|
|
+
|
|
|
+ nvdmastart(scr, PATTERN_COLOR_0, 4);
|
|
|
+ nvdmanext(~0);
|
|
|
+ nvdmanext(~0);
|
|
|
+ nvdmanext(~0);
|
|
|
+ nvdmanext(~0);
|
|
|
+
|
|
|
+ nvdmastart(scr, ROP_SET, 1);
|
|
|
+ nvdmanext(0xCC);
|
|
|
+
|
|
|
+ nvdmakickoff(scr);
|
|
|
+ waitforidle(scr);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static int
|
|
|
nvidiahwfill(VGAscr *scr, Rectangle r, ulong sval)
|
|
|
{
|
|
|
- ulong* fifo;
|
|
|
+ nvdmastart(scr, RECT_SOLID_COLOR, 1);
|
|
|
+ nvdmanext(sval);
|
|
|
|
|
|
- fifo = KADDR(scr->io + Fifo);
|
|
|
+ nvdmastart(scr, RECT_SOLID_RECTS(0), 2);
|
|
|
+ nvdmanext((r.min.x << 16) | r.min.y);
|
|
|
+ nvdmanext((Dx(r) << 16) | Dy(r));
|
|
|
|
|
|
- waitforfifo(scr, BitmapFifo, 1);
|
|
|
-
|
|
|
- fifo[BitmapColor1A/4] = sval;
|
|
|
-
|
|
|
- waitforfifo(scr, BitmapFifo, 2);
|
|
|
-
|
|
|
- fifo[BitmapURect0TopLeft/4] = (r.min.x << 16) | r.min.y;
|
|
|
- fifo[BitmapURect0WidthHeight/4] = (Dx(r) << 16) | Dy(r);
|
|
|
+ //if ( (Dy(r) * Dx(r)) >= 512)
|
|
|
+ nvdmakickoff(scr);
|
|
|
|
|
|
waitforidle(scr);
|
|
|
|
|
@@ -288,15 +480,13 @@ nvidiahwfill(VGAscr *scr, Rectangle r, ulong sval)
|
|
|
static int
|
|
|
nvidiahwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
|
|
|
{
|
|
|
- ulong* fifo;
|
|
|
-
|
|
|
- fifo = KADDR(scr->io + Fifo);
|
|
|
+ nvdmastart(scr, BLIT_POINT_SRC, 3);
|
|
|
+ nvdmanext((sr.min.y << 16) | sr.min.x);
|
|
|
+ nvdmanext((r.min.y << 16) | r.min.x);
|
|
|
+ nvdmanext((Dy(r) << 16) | Dx(r));
|
|
|
|
|
|
- waitforfifo(scr, BltFifo, 3);
|
|
|
-
|
|
|
- fifo[BltTopLeftSrc/4] = (sr.min.y << 16) | sr.min.x;
|
|
|
- fifo[BltTopLeftDst/4] = (r.min.y << 16) | r.min.x;
|
|
|
- fifo[BltWidthHeight/4] = (Dy(r) << 16) | Dx(r);
|
|
|
+ //if ( (Dy(r) * Dx(r)) >= 512)
|
|
|
+ nvdmakickoff(scr);
|
|
|
|
|
|
waitforidle(scr);
|
|
|
|
|
@@ -324,29 +514,7 @@ nvidiablank(VGAscr*, int blank)
|
|
|
static void
|
|
|
nvidiadrawinit(VGAscr *scr)
|
|
|
{
|
|
|
- ulong* fifo;
|
|
|
-
|
|
|
- fifo = KADDR(scr->io + Fifo);
|
|
|
-
|
|
|
- waitforfifo(scr, ClipFifo, 2);
|
|
|
-
|
|
|
- fifo[ClipTopLeft/4] = 0x0;
|
|
|
- fifo[ClipWidthHeight/4] = 0x80008000;
|
|
|
-
|
|
|
- waitforfifo(scr, PattFifo, 5);
|
|
|
-
|
|
|
- fifo[PattShape/4] = 0;
|
|
|
- fifo[PattColor0/4] = 0xffffffff;
|
|
|
- fifo[PattColor1/4] = 0xffffffff;
|
|
|
- fifo[PattMonochrome0/4] = 0xffffffff;
|
|
|
- fifo[PattMonochrome1/4] = 0xffffffff;
|
|
|
-
|
|
|
- waitforfifo(scr, RopFifo, 1);
|
|
|
-
|
|
|
- fifo[RopRop3/4] = 0xCC;
|
|
|
-
|
|
|
- waitforidle(scr);
|
|
|
-
|
|
|
+ nvresetgraphics(scr);
|
|
|
scr->blank = nvidiablank;
|
|
|
hwblank = 1;
|
|
|
scr->fill = nvidiahwfill;
|