123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 |
- /* 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"
- #include "dat.h"
- #include "fns.h"
- #include "io.h"
- #include "../port/error.h"
- #define Image IMAGE
- #include <draw.h>
- #include <memdraw.h>
- #include <cursor.h>
- #include "screen.h"
- #include "nv_dma.h"
- enum {
- Pramin = 0x00710000,
- Pramdac = 0x00680000,
- Fifo = 0x00800000,
- Pgraph = 0x00400000,
- Pfb = 0x00100000
- };
- enum {
- hwCurPos = Pramdac + 0x0300,
- };
- #define SKIPS 8
- struct {
- ulong *dmabase;
- int dmacurrent;
- int dmaput;
- int dmafree;
- int dmamax;
- } nv;
- static Pcidev*
- nvidiapci(void)
- {
- Pcidev *p;
- p = nil;
- while((p = pcimatch(p, 0x10DE, 0)) != nil){
- if(p->did >= 0x20 && p->ccrb == 3) /* video card */
- return p;
- }
- return nil;
- }
- static void
- nvidialinear(VGAscr*, int, int)
- {
- }
- static void
- nvidiaenable(VGAscr* scr)
- {
- Pcidev *p;
- ulong *q;
- int tmp;
- if(scr->mmio)
- return;
- p = nvidiapci();
- if(p == nil)
- return;
- scr->id = p->did;
- scr->pci = p;
- scr->mmio = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
- if(scr->mmio == nil)
- return;
- addvgaseg("nvidiammio", p->mem[0].bar&~0x0F, p->mem[0].size);
- vgalinearpci(scr);
- if(scr->apsize)
- addvgaseg("nvidiascreen", scr->paddr, scr->apsize);
- /* find video memory size */
- switch (scr->id & 0x0ff0) {
- case 0x0020:
- case 0x00A0:
- q = (void*)((uchar*)scr->mmio + 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;
- }
- break;
- case 0x01A0:
- p = pcimatchtbdf(MKBUS(BusPCI, 0, 0, 1));
- tmp = pcicfgr32(p, 0x7C);
- scr->storage = (((tmp >> 6) & 31) + 1) * 1024 * 1024;
- break;
- case 0x01F0:
- p = pcimatchtbdf(MKBUS(BusPCI, 0, 0, 1));
- tmp = pcicfgr32(p, 0x84);
- scr->storage = (((tmp >> 4) & 127) + 1) * 1024 * 1024;
- break;
- default:
- q = (void*)((uchar*)scr->mmio + Pfb + 0x020C);
- tmp = (*q >> 20) & 0xFF;
- if (tmp == 0)
- tmp = 16;
- scr->storage = tmp*1024*1024;
- break;
- }
- }
- static void
- nvidiacurdisable(VGAscr* scr)
- {
- if(scr->mmio == 0)
- return;
- vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
- }
- static void
- nvidiacurload(VGAscr* scr, Cursor* curs)
- {
- ulong* p;
- int i,j;
- ushort c,s;
- ulong tmp;
- if(scr->mmio == 0)
- return;
- vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
- switch (scr->id & 0x0ff0) {
- case 0x0020:
- case 0x00A0:
- p = (void*)((uchar*)scr->mmio + Pramin + 0x1E00 * 4);
- break;
- default:
- p = (void*)((uchar*)scr->vaddr + scr->storage - 96*1024);
- break;
- }
- for(i=0; i<16; i++) {
- 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)
- tmp |= 0x80000000;
- else if(c&0x8000)
- tmp |= 0xFFFF0000;
- if (j&0x1){
- *p++ = tmp;
- tmp = 0;
- } else {
- tmp>>=16;
- }
- c<<=1;
- s<<=1;
- }
- for (j=0; j<8; j++)
- *p++ = 0;
- }
- for (i=0; i<256; i++)
- *p++ = 0;
- scr->offset = curs->offset;
- vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);
- return;
- }
- static int
- nvidiacurmove(VGAscr* scr, Point p)
- {
- ulong* cursorpos;
- if(scr->mmio == 0)
- return 1;
- cursorpos = (void*)((uchar*)scr->mmio + hwCurPos);
- *cursorpos = ((p.y+scr->offset.y)<<16)|((p.x+scr->offset.x) & 0xFFFF);
- return 0;
- }
- static void
- nvidiacurenable(VGAscr* scr)
- {
- nvidiaenable(scr);
- if(scr->mmio == 0)
- return;
- vgaxo(Crtx, 0x1F, 0x57);
- nvidiacurload(scr, &arrow);
- nvidiacurmove(scr, ZP);
- vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);
- }
- void
- writeput(VGAscr *scr, int data)
- {
- uchar *p, scratch;
- ulong *fifo;
- outb(0x3D0,0);
- p = scr->vaddr;
- scratch = *p;
- fifo = (void*)((uchar*)scr->mmio + Fifo);
- fifo[0x10] = (data << 2);
- USED(scratch);
- }
- ulong
- readget(VGAscr *scr)
- {
- ulong *fifo;
- fifo = (void*)((uchar*)scr->mmio + Fifo);
- return (fifo[0x0011] >> 2);
- }
- 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;
- }
- }
- 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)
- {
- ulong* pgraph;
- int x;
- pgraph = (void*)((uchar*)scr->mmio + 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)
- ;
- if(x >= 1000000)
- iprint("idle stat %lud scrio %.8lux scr %p pc %luX\n", *pgraph, scr->mmio, scr, getcallerpc(&scr));
- }
- static void
- nvresetgraphics(VGAscr *scr)
- {
- ulong surfaceFormat, patternFormat, rectFormat, lineFormat;
- int pitch, i;
- pitch = scr->gscreen->width*BY2WD;
- nv.dmabase = (void*)((uchar*)scr->vaddr + 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;
- }
- nvdmastart(scr, SURFACE_FORMAT, 4);
- nvdmanext(surfaceFormat);
- nvdmanext(pitch | (pitch << 16));
- nvdmanext(0);
- nvdmanext(0);
- nvdmastart(scr, PATTERN_FORMAT, 1);
- nvdmanext(patternFormat);
- 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)
- {
- nvdmastart(scr, RECT_SOLID_COLOR, 1);
- nvdmanext(sval);
- nvdmastart(scr, RECT_SOLID_RECTS(0), 2);
- nvdmanext((r.min.x << 16) | r.min.y);
- nvdmanext((Dx(r) << 16) | Dy(r));
- //if ( (Dy(r) * Dx(r)) >= 512)
- nvdmakickoff(scr);
- waitforidle(scr);
- return 1;
- }
- static int
- nvidiahwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
- {
- 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));
- //if ( (Dy(r) * Dx(r)) >= 512)
- nvdmakickoff(scr);
- waitforidle(scr);
- return 1;
- }
- void
- nvidiablank(VGAscr*, int blank)
- {
- uchar seq1, crtc1A;
- seq1 = vgaxi(Seqx, 1) & ~0x20;
- crtc1A = vgaxi(Crtx, 0x1A) & ~0xC0;
- if(blank){
- seq1 |= 0x20;
- // crtc1A |= 0xC0;
- crtc1A |= 0x80;
- }
- vgaxo(Seqx, 1, seq1);
- vgaxo(Crtx, 0x1A, crtc1A);
- }
- static void
- nvidiadrawinit(VGAscr *scr)
- {
- nvresetgraphics(scr);
- scr->blank = nvidiablank;
- hwblank = 1;
- scr->fill = nvidiahwfill;
- scr->scroll = nvidiahwscroll;
- }
- VGAdev vganvidiadev = {
- "nvidia",
- nvidiaenable,
- nil,
- nil,
- nvidialinear,
- nvidiadrawinit,
- };
- VGAcur vganvidiacur = {
- "nvidiahwgc",
- nvidiacurenable,
- nvidiacurdisable,
- nvidiacurload,
- nvidiacurmove,
- };
|