2 /* Portions of this file derived from work with the following copyright */
4 /***************************************************************************\
6 |* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
8 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
9 |* international laws. Users and possessors of this source code are *|
10 |* hereby granted a nonexclusive, royalty-free copyright license to *|
11 |* use this code in individual and commercial software. *|
13 |* Any use of this source code must include, in the user documenta- *|
14 |* tion and internal comments to the code, notices to the end user *|
17 |* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
19 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
20 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
21 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
22 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
23 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
24 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
25 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
26 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
27 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
28 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
29 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
31 |* U.S. Government End Users. This source code is a "commercial *|
32 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
33 |* consisting of "commercial computer software" and "commercial *|
34 |* computer software documentation," as such terms are used in *|
35 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
36 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
37 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
38 |* all U.S. Government End Users acquire the source code with only *|
39 |* those rights set forth herein. *|
41 \***************************************************************************/
44 #include "../port/lib.h"
49 #include "../port/error.h"
67 hwCurPos = Pramdac + 0x0300,
81 nvidiaenable(VGAscr* scr)
94 scr->mmio = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
97 addvgaseg("nvidiammio", p->mem[0].bar&~0x0F, p->mem[0].size);
100 addvgaseg("nvidiascreen", scr->paddr, scr->apsize);
101 /* find video memory size */
102 switch (scr->id & 0x0ff0) {
105 q = (void*)((uchar*)scr->mmio + Pfb);
108 scr->storage = ((tmp >> 12) & 0x0F) * 1024 + 1024 * 2;
112 scr->storage = (1024*1024*2) << tmp;
114 scr->storage = 1024*1024*32;
118 p = pcimatchtbdf(MKBUS(BusPCI, 0, 0, 1));
119 tmp = pcicfgr32(p, 0x7C);
120 scr->storage = (((tmp >> 6) & 31) + 1) * 1024 * 1024;
123 p = pcimatchtbdf(MKBUS(BusPCI, 0, 0, 1));
124 tmp = pcicfgr32(p, 0x84);
125 scr->storage = (((tmp >> 4) & 127) + 1) * 1024 * 1024;
128 q = (void*)((uchar*)scr->mmio + Pfb + 0x020C);
129 tmp = (*q >> 20) & 0xFFF;
132 scr->storage = tmp*1024*1024;
138 nvidialinear(VGAscr *, int, int)
143 nvidiacurdisable(VGAscr* scr)
148 vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
153 nvidiacurload(VGAscr* scr, Cursor* curs)
163 vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
165 switch (scr->id & 0x0ff0) {
168 p = (void*)((uchar*)scr->mmio + Pramin + 0x1E00 * 4);
172 * Reset the cursor location, since the kernel may
173 * have allocated less storage than aux/vga
176 tmp = scr->apsize - 96*1024;
177 p = (void*)((uchar*)scr->vaddr + tmp);
178 vgaxo(Crtx, 0x30, 0x80|(tmp>>17));
179 vgaxo(Crtx, 0x31, (tmp>>11)<<2);
180 vgaxo(Crtx, 0x2F, tmp>>24);
184 for(i=0; i<16; i++) {
185 c = (curs->clr[2 * i] << 8) | curs->clr[2 * i+1];
186 s = (curs->set[2 * i] << 8) | curs->set[2 * i+1];
188 for (j=0; j<16; j++){
205 for (i=0; i<256; i++)
208 scr->offset = curs->offset;
209 vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);
213 nvidiacurmove(VGAscr* scr, Point p)
220 cursorpos = (void*)((uchar*)scr->mmio + hwCurPos);
221 *cursorpos = ((p.y+scr->offset.y)<<16)|((p.x+scr->offset.x) & 0xFFFF);
227 nvidiacurenable(VGAscr* scr)
233 vgaxo(Crtx, 0x1F, 0x57);
235 nvidiacurload(scr, &arrow);
236 nvidiacurmove(scr, ZP);
238 vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);
242 writeput(VGAscr *scr, int data)
250 fifo = (void*)((uchar*)scr->mmio + Fifo);
251 fifo[0x10] = (data << 2);
260 fifo = (void*)((uchar*)scr->mmio + Fifo);
261 return (fifo[0x0011] >> 2);
265 nvdmakickoff(VGAscr *scr)
267 if(nv.dmacurrent != nv.dmaput) {
268 nv.dmaput = nv.dmacurrent;
269 writeput(scr, nv.dmaput);
274 nvdmanext(ulong data)
276 nv.dmabase[nv.dmacurrent++] = data;
280 nvdmawait(VGAscr *scr, int size)
286 while(nv.dmafree < size) {
287 dmaget = readget(scr);
289 if(nv.dmaput >= dmaget) {
290 nv.dmafree = nv.dmamax - nv.dmacurrent;
291 if(nv.dmafree < size) {
292 nvdmanext(0x20000000);
293 if(dmaget <= SKIPS) {
294 if (nv.dmaput <= SKIPS) /* corner case - will be idle */
295 writeput(scr, SKIPS + 1);
296 do { dmaget = readget(scr); }
297 while(dmaget <= SKIPS);
299 writeput(scr, SKIPS);
300 nv.dmacurrent = nv.dmaput = SKIPS;
301 nv.dmafree = dmaget - (SKIPS + 1);
304 nv.dmafree = dmaget - nv.dmacurrent - 1;
310 nvdmastart(VGAscr *scr, ulong tag, int size)
312 if (nv.dmafree <= size)
313 nvdmawait(scr, size);
314 nvdmanext((size << 18) | tag);
315 nv.dmafree -= (size + 1);
319 waitforidle(VGAscr *scr)
324 pgraph = (void*)((uchar*)scr->mmio + Pgraph);
327 while((readget(scr) != nv.dmaput) && x++ < 1000000)
330 iprint("idle stat %lud put %d scr %#p pc %#p\n", readget(scr), nv.dmaput, scr, getcallerpc(&scr));
333 while(pgraph[0x00000700/4] & 0x01 && x++ < 1000000)
337 iprint("idle stat %lud scrio %#p scr %#p pc %#p\n", *pgraph, scr->mmio, scr, getcallerpc(&scr));
341 nvresetgraphics(VGAscr *scr)
343 ulong surfaceFormat, patternFormat, rectFormat, lineFormat;
349 pitch = scr->gscreen->width*sizeof(ulong);
352 * DMA is at the end of the virtual window,
353 * but we might have cut it short when mapping it.
355 if(nv.dmabase == nil){
356 if(scr->storage <= scr->apsize)
357 nv.dmabase = (ulong*)((uchar*)scr->vaddr + scr->storage - 128*1024);
359 nv.dmabase = (void*)vmap(scr->paddr + scr->storage - 128*1024, 128*1024);
361 print("vmap nvidia dma failed\n");
367 for(i=0; i<SKIPS; i++)
368 nv.dmabase[i] = 0x00000000;
370 nv.dmabase[0x0 + SKIPS] = 0x00040000;
371 nv.dmabase[0x1 + SKIPS] = 0x80000010;
372 nv.dmabase[0x2 + SKIPS] = 0x00042000;
373 nv.dmabase[0x3 + SKIPS] = 0x80000011;
374 nv.dmabase[0x4 + SKIPS] = 0x00044000;
375 nv.dmabase[0x5 + SKIPS] = 0x80000012;
376 nv.dmabase[0x6 + SKIPS] = 0x00046000;
377 nv.dmabase[0x7 + SKIPS] = 0x80000013;
378 nv.dmabase[0x8 + SKIPS] = 0x00048000;
379 nv.dmabase[0x9 + SKIPS] = 0x80000014;
380 nv.dmabase[0xA + SKIPS] = 0x0004A000;
381 nv.dmabase[0xB + SKIPS] = 0x80000015;
382 nv.dmabase[0xC + SKIPS] = 0x0004C000;
383 nv.dmabase[0xD + SKIPS] = 0x80000016;
384 nv.dmabase[0xE + SKIPS] = 0x0004E000;
385 nv.dmabase[0xF + SKIPS] = 0x80000017;
388 nv.dmacurrent = 16 + SKIPS;
390 nv.dmafree = nv.dmamax - nv.dmacurrent;
392 switch(scr->gscreen->depth) {
395 surfaceFormat = SURFACE_FORMAT_DEPTH24;
396 patternFormat = PATTERN_FORMAT_DEPTH24;
397 rectFormat = RECT_FORMAT_DEPTH24;
398 lineFormat = LINE_FORMAT_DEPTH24;
402 surfaceFormat = SURFACE_FORMAT_DEPTH16;
403 patternFormat = PATTERN_FORMAT_DEPTH16;
404 rectFormat = RECT_FORMAT_DEPTH16;
405 lineFormat = LINE_FORMAT_DEPTH16;
408 surfaceFormat = SURFACE_FORMAT_DEPTH8;
409 patternFormat = PATTERN_FORMAT_DEPTH8;
410 rectFormat = RECT_FORMAT_DEPTH8;
411 lineFormat = LINE_FORMAT_DEPTH8;
415 nvdmastart(scr, SURFACE_FORMAT, 4);
416 nvdmanext(surfaceFormat);
417 nvdmanext(pitch | (pitch << 16));
421 nvdmastart(scr, PATTERN_FORMAT, 1);
422 nvdmanext(patternFormat);
424 nvdmastart(scr, RECT_FORMAT, 1);
425 nvdmanext(rectFormat);
427 nvdmastart(scr, LINE_FORMAT, 1);
428 nvdmanext(lineFormat);
430 nvdmastart(scr, PATTERN_COLOR_0, 4);
436 nvdmastart(scr, ROP_SET, 1);
447 nvidiahwfill(VGAscr *scr, Rectangle r, ulong sval)
449 nvdmastart(scr, RECT_SOLID_COLOR, 1);
452 nvdmastart(scr, RECT_SOLID_RECTS(0), 2);
453 nvdmanext((r.min.x << 16) | r.min.y);
454 nvdmanext((Dx(r) << 16) | Dy(r));
456 //if ( (Dy(r) * Dx(r)) >= 512)
465 nvidiahwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
467 nvdmastart(scr, BLIT_POINT_SRC, 3);
468 nvdmanext((sr.min.y << 16) | sr.min.x);
469 nvdmanext((r.min.y << 16) | r.min.x);
470 nvdmanext((Dy(r) << 16) | Dx(r));
472 //if ( (Dy(r) * Dx(r)) >= 512)
481 nvidiablank(VGAscr*, int blank)
485 seq1 = vgaxi(Seqx, 1) & ~0x20;
486 crtc1A = vgaxi(Crtx, 0x1A) & ~0xC0;
494 vgaxo(Seqx, 1, seq1);
495 vgaxo(Crtx, 0x1A, crtc1A);
499 nvidiadrawinit(VGAscr *scr)
501 scr->blank = nvidiablank;
502 if(nvresetgraphics(scr) < 0)
504 scr->fill = nvidiahwfill;
505 scr->scroll = nvidiahwscroll;
508 VGAdev vganvidiadev = {
518 VGAcur vganvidiacur = {