123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- #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"
- enum {
- Pramin = 0x00710000,
- Pramdac = 0x00680000,
- Fifo = 0x00800000,
- Pgraph = 0x00400000
- };
- enum {
- hwCurPos = Pramdac + 0x0300,
- hwCurImage = Pramin + (0x00010000 - 0x0800),
- };
- /* Nvidia is good about backwards compatibility -- any did > 0x20 is fine */
- 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 ulong
- nvidialinear(VGAscr* scr, int* size, int* align)
- {
- Pcidev *p;
- int oapsize, wasupamem;
- ulong aperture, oaperture;
- oaperture = scr->aperture;
- oapsize = scr->apsize;
- wasupamem = scr->isupamem;
- aperture = 0;
- if(p = nvidiapci()){
- aperture = p->mem[1].bar & ~0x0F;
- *size = p->mem[1].size;
- }
- if(wasupamem){
- if(oaperture == aperture)
- return oaperture;
- upafree(oaperture, oapsize);
- }
- scr->isupamem = 0;
- aperture = upamalloc(aperture, *size, *align);
- if(aperture == 0){
- if(wasupamem && upamalloc(oaperture, oapsize, 0)){
- aperture = oaperture;
- scr->isupamem = 1;
- }
- else
- scr->isupamem = 0;
- }
- else
- scr->isupamem = 1;
- return aperture;
- }
- static void
- nvidiaenable(VGAscr* scr)
- {
- Pcidev *p;
- ulong aperture;
- int align, size;
- /*
- * Only once, can't be disabled for now.
- * scr->io holds the physical address of
- * the MMIO registers.
- */
- if(scr->io)
- return;
- p = nvidiapci();
- if(p == nil)
- return;
- scr->id = p->did;
- scr->io = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
- if(scr->io == 0)
- return;
- addvgaseg("nvidiammio", scr->io, p->mem[0].size);
- size = p->mem[1].size;
- align = 0;
- aperture = nvidialinear(scr, &size, &align);
- if(aperture){
- scr->aperture = aperture;
- scr->apsize = size;
- addvgaseg("nvidiascreen", aperture, size);
- }
- }
- static void
- nvidiacurdisable(VGAscr* scr)
- {
- if(scr->io == 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->io == 0)
- return;
- vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
- p = KADDR(scr->io + hwCurImage);
- 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;
- }
- 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->io == 0)
- return 1;
- cursorpos = KADDR(scr->io + 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->io == 0)
- return;
- vgaxo(Crtx, 0x1F, 0x57);
- nvidiacurload(scr, &arrow);
- nvidiacurmove(scr, ZP);
- vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);
- }
- enum {
- RopFifo = 0x00000000,
- ClipFifo = 0x00002000,
- PattFifo = 0x00004000,
- BltFifo = 0x00008000,
- BitmapFifo = 0x0000A000,
- };
- enum {
- RopRop3 = RopFifo + 0x300,
- ClipTopLeft = ClipFifo + 0x300,
- ClipWidthHeight = ClipFifo + 0x304,
- PattShape = PattFifo + 0x0308,
- PattColor0 = PattFifo + 0x0310,
- PattColor1 = PattFifo + 0x0314,
- PattMonochrome0 = PattFifo + 0x0318,
- PattMonochrome1 = PattFifo + 0x031C,
- BltTopLeftSrc = BltFifo + 0x0300,
- BltTopLeftDst = BltFifo + 0x0304,
- BltWidthHeight = BltFifo + 0x0308,
- BitmapColor1A = BitmapFifo + 0x03FC,
- BitmapURect0TopLeft = BitmapFifo + 0x0400,
- BitmapURect0WidthHeight = BitmapFifo + 0x0404,
- };
- static void
- waitforidle(VGAscr *scr)
- {
- ulong* pgraph;
- int x;
- pgraph = KADDR(scr->io + Pgraph);
- 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->io, scr, getcallerpc(&scr));
- }
- static void
- waitforfifo(VGAscr *scr, int fifo, int entries)
- {
- ushort* fifofree;
- int x;
- x = 0;
- fifofree = KADDR(scr->io + Fifo + fifo + 0x10);
- while(((*fifofree >> 2) < entries) && x++ < 1000000)
- ;
- if(x >= 1000000)
- iprint("fifo stat %d scrio %.8lux scr %p pc %luX\n", *fifofree, scr->io, scr, getcallerpc(&scr));
- }
- static int
- nvidiahwfill(VGAscr *scr, Rectangle r, ulong sval)
- {
- ulong* fifo;
- fifo = KADDR(scr->io + Fifo);
- 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);
- waitforidle(scr);
- return 1;
- }
- static int
- nvidiahwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
- {
- ulong* fifo;
- fifo = KADDR(scr->io + Fifo);
- 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);
- 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)
- {
- 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);
- 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,
- };
|