123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include "pci.h"
- #include "vga.h"
- /*
- * Laguna Visual Media Accelerators Family CL-GD546x.
- */
- typedef struct {
- Pcidev* pci;
- uchar* mmio;
- int mem;
- int format; /* graphics and video format */
- int threshold; /* display threshold */
- int tilectrl; /* tiling control */
- int vsc; /* vendor specific control */
- int control; /* control */
- int tilectrl2D3D; /* tiling control 2D3D */
- } Laguna;
- enum {
- Format = 0xC0, /* graphics and video format */
- Threshold = 0xEA, /* Display Threshold */
- TileCtrl = 0x2C4,
- Vsc = 0x3FC, /* Vendor Specific Control (32-bits) */
- Control = 0x402, /* 2D Control */
- TileCtrl2D3D = 0x407, /* (8-bits) */
- };
- static int
- mmio8r(Laguna* laguna, int offset)
- {
- return *(laguna->mmio+offset) & 0xFF;
- }
- static void
- mmio8w(Laguna* laguna, int offset, int data)
- {
- *(laguna->mmio+offset) = data;
- }
- static int
- mmio16r(Laguna* laguna, int offset)
- {
- return *((ushort*)(laguna->mmio+offset)) & 0xFFFF;
- }
- static void
- mmio16w(Laguna* laguna, int offset, int data)
- {
- *((ushort*)(laguna->mmio+offset)) = data;
- }
- static int
- mmio32r(Laguna* laguna, int offset)
- {
- return *((ulong*)(laguna->mmio+offset));
- }
- static void
- mmio32w(Laguna* laguna, int offset, int data)
- {
- *((ulong*)(laguna->mmio+offset)) = data;
- }
- static void
- snarf(Vga* vga, Ctlr* ctlr)
- {
- int f, i;
- uchar *mmio;
- Pcidev *p;
- Laguna *laguna;
- /*
- * Save all the registers, even though we'll only
- * change a handful.
- */
- for(i = 0x06; i < 0x20; i++)
- vga->sequencer[i] = vgaxi(Seqx, i);
- for(i = 0x09; i < 0x0C; i++)
- vga->graphics[i] = vgaxi(Grx, i);
- for(i = 0x19; i < 0x20; i++)
- vga->crt[i] = vgaxi(Crtx, i);
- if(vga->private == nil){
- vga->private = alloc(sizeof(Laguna));
- if((p = pcimatch(0, 0x1013, 0)) == nil)
- error("%s: not found\n", ctlr->name);
- switch(p->did){
- case 0xD0: /* CL-GD5462 */
- vga->f[1] = 170000000;
- break;
- case 0xD4: /* CL-GD5464 */
- case 0xD6: /* CL-GD5465 */
- vga->f[1] = 230000000;
- break;
- default:
- error("%s: not found\n", ctlr->name);
- }
- if((f = open("#v/vgactl", OWRITE)) < 0)
- error("%s: can't open vgactl\n", ctlr->name);
- if(write(f, "type clgd546x", 13) != 13)
- error("%s: can't set type\n", ctlr->name);
- close(f);
-
- mmio = segattach(0, "clgd546xmmio", 0, p->mem[1].size);
- if(mmio == (void*)-1)
- error("%s: can't attach mmio segment\n", ctlr->name);
- laguna = vga->private;
- laguna->pci = p;
- laguna->mmio = mmio;
- }
- laguna = vga->private;
- laguna->mem = (vga->sequencer[0x14] & 0x07)+1;
- laguna->format = mmio16r(laguna, Format);
- laguna->threshold = mmio16r(laguna, Threshold);
- laguna->tilectrl = mmio16r(laguna, TileCtrl);
- laguna->vsc = mmio32r(laguna, Vsc);
- laguna->control = mmio16r(laguna, Control);
- laguna->tilectrl2D3D = mmio8r(laguna, TileCtrl2D3D);
- vga->vma = vga->vmz = laguna->pci->mem[0].size;
- ctlr->flag |= Hlinear;
- ctlr->flag |= Fsnarf;
- }
- static void
- init(Vga* vga, Ctlr* ctlr)
- {
- Mode *mode;
- ushort x;
- int format, interleave, fetches, nointerleave, notile, pagesize, tiles;
- Laguna *laguna;
- nointerleave = 1;
- notile = 1;
- pagesize = 0;
- mode = vga->mode;
- if(vga->f[0] == 0)
- vga->f[0] = vga->mode->frequency;
- if(vga->f[0] > vga->f[1])
- error("%s: invalid pclk - %lud\n", ctlr->name, vga->f[0]);
- if(mode->z > 8)
- error("%s: depth %d not supported\n", ctlr->name, mode->z);
- /*
- * VCLK3
- */
- clgd54xxclock(vga, ctlr);
- vga->misc |= 0x0C;
- vga->sequencer[0x1E] = vga->n[0];
- vga->sequencer[0x0E] = (vga->d[0]<<1)|vga->p[0];
- vga->sequencer[0x07] = 0x00;
- if(mode->z == 8)
- vga->sequencer[0x07] |= 0x01;
- vga->crt[0x14] = 0;
- vga->crt[0x17] = 0xC3;
- /*
- * Overflow bits.
- */
- vga->crt[0x1A] = 0x00;
- x = mode->ehb>>3;
- if(x & 0x40)
- vga->crt[0x1A] |= 0x10;
- if(x & 0x80)
- vga->crt[0x1A] |= 0x20;
- if(vga->crt[0x16] & 0x100)
- vga->crt[0x1A] |= 0x40;
- if(vga->crt[0x16] & 0x200)
- vga->crt[0x1A] |= 0x80;
- vga->crt[0x1B] = 0x22;
- if(vga->crt[0x13] & 0x100)
- vga->crt[0x1B] |= 0x10;
- vga->crt[0x1D] = 0x00;
- if(vga->crt[0x13] & 0x200)
- vga->crt[0x1D] |= 0x01;
- vga->crt[0x1E] = 0x00;
- if(vga->crt[0x10] & 0x400)
- vga->crt[0x1E] |= 0x01;
- if(vga->crt[0x15] & 0x400)
- vga->crt[0x1E] |= 0x02;
- if(vga->crt[0x12] & 0x400)
- vga->crt[0x1E] |= 0x04;
- if(vga->crt[0x06] & 0x400)
- vga->crt[0x1E] |= 0x08;
- if(vga->crt[0x04] & 0x100)
- vga->crt[0x1E] |= 0x10;
- if(vga->crt[0x02] & 0x100)
- vga->crt[0x1E] |= 0x20;
- if(vga->crt[0x01] & 0x100)
- vga->crt[0x1E] |= 0x40;
- if(vga->crt[0x00] & 0x100)
- vga->crt[0x1E] |= 0x80;
- vga->graphics[0x0B] = 0x00;
- if(vga->vmz > 1024*1024)
- vga->graphics[0x0B] |= 0x20;
- if(mode->interlace == 'v'){
- vga->crt[0x19] = vga->crt[0x00]/2;
- vga->crt[0x1A] |= 0x01;
- }
- if(vga->linear && (ctlr->flag & Hlinear))
- ctlr->flag |= Ulinear;
- laguna = vga->private;
- /*
- * Ignore wide tiles for now, this simplifies things.
- */
- if(mode->x <= 640)
- tiles = 5;
- else if(mode->x <= 1024)
- tiles = 8;
- else if(mode->x <= 1280)
- tiles = 10;
- else if(mode->x <= 1664)
- tiles = 13;
- else if(mode->x <= 2048)
- tiles = 16;
- else if(mode->x <= 2560)
- tiles = 20;
- else if(mode->x <= 3228)
- tiles = 26;
- else
- tiles = 32;
- fetches = tiles; /* -1? */
- if(nointerleave)
- interleave = 0;
- else switch(laguna->mem){
- default:
- interleave = 0;
- break;
- case 2:
- interleave = 1;
- break;
- case 4:
- case 8:
- interleave = 2;
- break;
- }
- if(mode->z == 8)
- format = 0;
- else if(mode->z == 16)
- format = (1<<12)|(2<<9);
- else if(mode->z == 24)
- format = (2<<12)|(2<<9);
- else
- format = (2<<12)|(2<<9);
- //if(ctlr->flag & Ulinear)
- // laguna->vsc |= 0x10000000;
- //else
- laguna->vsc &= ~0x10000000;
- laguna->format = format;
- laguna->threshold = (interleave<<14)|(fetches<<8)|0x14;
- laguna->tilectrl &= 0x3F;
- laguna->tilectrl |= (interleave<<14)|(tiles<<8);
- if(!notile)
- laguna->tilectrl |= 0x80;
- if(pagesize == 1)
- laguna->tilectrl |= 0x10;
- laguna->tilectrl2D3D = (interleave<<6)|tiles;
- laguna->control = 0;
- if(notile)
- laguna->control |= 0x1000;
- if(pagesize == 1)
- laguna->control |= 0x0200;
- }
- static void
- load(Vga* vga, Ctlr*)
- {
- Laguna *laguna;
- vgaxo(Seqx, 0x0E, vga->sequencer[0x0E]);
- vgaxo(Seqx, 0x1E, vga->sequencer[0x1E]);
- vgaxo(Seqx, 0x07, vga->sequencer[0x07]);
- if(vga->mode->interlace == 'v')
- vgaxo(Crtx, 0x19, vga->crt[0x19]);
- vgaxo(Crtx, 0x1A, vga->crt[0x1A]);
- vgaxo(Crtx, 0x1B, vga->crt[0x1B]);
- vgaxo(Crtx, 0x1D, vga->crt[0x1D]);
- vgaxo(Crtx, 0x1E, vga->crt[0x1E]);
- vgaxo(Grx, 0x0B, vga->graphics[0x0B]);
- laguna = vga->private;
- mmio16w(laguna, Format, laguna->format);
- mmio32w(laguna, Vsc, laguna->vsc);
- mmio16w(laguna, Threshold, laguna->threshold);
- mmio16w(laguna, TileCtrl, laguna->tilectrl);
- mmio8w(laguna, TileCtrl2D3D, laguna->tilectrl2D3D);
- mmio16w(laguna, Control, laguna->control);
- }
- static void
- dump(Vga* vga, Ctlr* ctlr)
- {
- int i;
- char *name;
- Laguna *laguna;
- name = ctlr->name;
- printitem(name, "Seq06");
- for(i = 0x06; i < 0x20; i++)
- printreg(vga->sequencer[i]);
- printitem(name, "Crt19");
- for(i = 0x19; i < 0x20; i++)
- printreg(vga->crt[i]);
- printitem(name, "Gr09");
- for(i = 0x09; i < 0x0C; i++)
- printreg(vga->graphics[i]);
- laguna = vga->private;
- Bprint(&stdout, "\n");
- Bprint(&stdout, "%s mem\t\t%d\n", ctlr->name, laguna->mem*1024*1024);
- Bprint(&stdout, "%s Format\t\t%uX\n", ctlr->name, laguna->format);
- Bprint(&stdout, "%s Threshold\t\t\t%uX\n",
- ctlr->name, laguna->threshold);
- Bprint(&stdout, "%s TileCtrl\t\t\t%uX\n", ctlr->name, laguna->tilectrl);
- Bprint(&stdout, "%s Vsc\t\t%uX\n", ctlr->name, laguna->vsc);
- Bprint(&stdout, "%s Control\t\t%uX\n", ctlr->name, laguna->control);
- Bprint(&stdout, "%s TileCtrlC2D3D\t\t%uX\n",
- ctlr->name, laguna->tilectrl2D3D);
- }
- Ctlr clgd546x = {
- "clgd546x", /* name */
- snarf, /* snarf */
- 0, /* options */
- init, /* init */
- load, /* load */
- dump, /* dump */
- };
- Ctlr clgd546xhwgc = {
- "clgd546xhwgc", /* name */
- 0, /* snarf */
- 0, /* options */
- 0, /* init */
- 0, /* load */
- 0, /* dump */
- };
|