123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include "pci.h"
- #include "vga.h"
- /*
- * IBM RGB52x and compatibles.
- * High Performance Palette DAC.
- */
- uchar (*rgb524mnxi)(Vga*, int);
- void (*rgb524mnxo)(Vga*, int, uchar);
- enum { /* index registers */
- MiscClock = 0x02,
- SyncControl = 0x03,
- HSyncControl = 0x04,
- PowerMgmnt = 0x05,
- PaletteControl = 0x07,
- SYSCLKControl = 0x08,
- PixelFormat = 0x0A,
- Pixel8Control = 0x0B,
- Pixel16Control = 0x0C,
- Pixel32Control = 0x0E,
- PLLControl1 = 0x10,
- PLLControl2 = 0x11,
- SYSCLKN = 0x15,
- SYSCLKM = 0x16,
- M0 = 0x20,
- N0 = 0x21,
- MiscControl1 = 0x70,
- MiscControl2 = 0x71,
- };
- static void
- clock(Vga* vga, Ctlr*, ulong fref, ulong maxpclk)
- {
- int d, mind;
- ulong df, f, m, n, vrf;
- mind = vga->f[0]+1;
- for(df = 0; df < 4; df++){
- for(m = 2; m < 64; m++){
- for(n = 2; n < 32; n++){
- f = (fref*(m+65))/n;
- switch(df){
- case 0:
- vrf = fref/(n*2);
- if(vrf > maxpclk/4 || vrf < 1000000)
- continue;
- f /= 8;
- break;
- case 1:
- vrf = fref/(n*2);
- if(vrf > maxpclk/2 || vrf < 1000000)
- continue;
- f /= 4;
- break;
- case 2:
- vrf = fref/(n*2);
- if(vrf > maxpclk || vrf < 1000000)
- continue;
- f /= 2;
- break;
- case 3:
- vrf = fref/n;
- if(vrf > maxpclk || vrf < 1000000)
- continue;
- break;
- }
- if(f > maxpclk)
- continue;
- d = vga->f[0] - f;
- if(d < 0)
- d = -d;
- if(d <= mind){
- vga->m[0] = m;
- vga->n[0] = n;
- vga->d[0] = df;
- mind = d;
- }
- }
- }
- }
- }
- static void
- init(Vga* vga, Ctlr* ctlr)
- {
- ulong fref, maxpclk;
- char *p, *val;
- /*
- * Part comes in at least a -170MHz speed-grade.
- */
- maxpclk = 170000000;
- if(p = strrchr(ctlr->name, '-'))
- maxpclk = strtoul(p+1, 0, 0) * 1000000;
- /*
- * If we don't already have a desired pclk,
- * take it from the mode.
- * Check it's within range.
- */
- if(vga->f[0] == 0)
- vga->f[0] = vga->mode->frequency;
- if(vga->f[0] > maxpclk)
- error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]);
- if(val = dbattr(vga->attr, "rgb524mnrefclk"))
- fref = strtol(val, 0, 0);
- else
- fref = RefFreq;
- /*
- * Initialise the PLL parameters.
- * Use m/n pair 2.
- */
- clock(vga, ctlr, fref, maxpclk);
- vga->i[0] = 2;
- ctlr->flag |= Finit;
- }
- static void
- load(Vga* vga, Ctlr* ctlr)
- {
- char *val;
- int hsyncdelay, x;
- if(rgb524mnxi == nil && rgb524mnxo == nil)
- error("%s->load: no access routines\n", ctlr->name);
-
- /*
- * Set the m/n values for the desired frequency and
- * set pixel control to use compatibility mode with
- * internal frequency select using the specified set
- * of m/n registers.
- */
- rgb524mnxo(vga, M0+vga->i[0]*2, vga->d[0]<<6|vga->m[0]);
- rgb524mnxo(vga, N0+vga->i[0]*2, vga->n[0]);
- rgb524mnxo(vga, PLLControl2, vga->i[0]);
- rgb524mnxo(vga, PLLControl1, 0x03);
- /*
- * Enable pixel programming in MiscClock;
- * nothing to do in MiscControl1;
- * set internal PLL clock and !vga in MiscControl2;
- */
- x = rgb524mnxi(vga, MiscClock) & ~0x01;
- x |= 0x01;
- rgb524mnxo(vga, MiscClock, x);
- x = rgb524mnxi(vga, MiscControl2) & ~0x41;
- x |= 0x41;
- rgb524mnxo(vga, MiscControl2, x);
- /*
- * Syncs.
- */
- x = 0;
- if(vga->mode->hsync == '+')
- x |= 0x10;
- if(vga->mode->vsync == '+')
- x |= 0x20;
- rgb524mnxo(vga, SyncControl, x);
- if(val = dbattr(vga->mode->attr, "hsyncdelay"))
- hsyncdelay = strtol(val, 0, 0);
- else switch(vga->mode->z){
- default:
- case 8:
- hsyncdelay = 1;
- break;
- case 15:
- case 16:
- hsyncdelay = 5;
- break;
- case 32:
- hsyncdelay = 7;
- break;
- }
- rgb524mnxo(vga, HSyncControl, hsyncdelay);
- rgb524mnxo(vga, SYSCLKM, 0x50);
- rgb524mnxo(vga, SYSCLKN, 0x08);
- sleep(50);
- //rgb524mnxo(vga, SYSCLKM, 0x6F);
- //rgb524mnxo(vga, SYSCLKN, 0x0F);
- //sleep(500);
- /*
- * Set the palette for the desired format.
- * ****NEEDS WORK FOR OTHER THAN 8-BITS****
- */
- rgb524mnxo(vga, PaletteControl, 0x00);
- switch(vga->mode->z){
- case 8:
- rgb524mnxo(vga, PixelFormat, 0x03);
- rgb524mnxo(vga, Pixel8Control, 0x00);
- break;
- case 15:
- rgb524mnxo(vga, PixelFormat, 0x04);
- rgb524mnxo(vga, Pixel16Control, 0xC4);
- case 16:
- rgb524mnxo(vga, PixelFormat, 0x04);
- rgb524mnxo(vga, Pixel16Control, 0xC6);
- break;
- case 32:
- rgb524mnxo(vga, PixelFormat, 0x06);
- rgb524mnxo(vga, Pixel32Control, 0x03);
- break;
- }
- }
- static void
- dumpclock(Vga*, Ctlr* ctlr, ulong fref, ulong m, ulong n, char* name)
- {
- ulong df, f;
- df = (m>>6) & 0x03;
- m &= 0x3F;
- n &= 0x1F;
- if(m == 0 || n == 0)
- return;
- f = (fref*(m+65))/n;
- switch(df){
- case 0:
- f /= 8;
- break;
- case 1:
- f /= 4;
- break;
- case 2:
- f /= 2;
- break;
- case 3:
- break;
- }
- printitem(ctlr->name, name);
- Bprint(&stdout, "%12lud\n", f);
- }
- static void
- dump(Vga* vga, Ctlr* ctlr)
- {
- int i;
- char *val;
- uchar x[256];
- ulong fref, fs;
- if(rgb524mnxi == nil && rgb524mnxo == nil)
- error("%s->dump: no access routines\n", ctlr->name);
- printitem(ctlr->name, "index00");
- for(i = 0x00; i < 0x0F; i++){
- x[i] = rgb524mnxi(vga, i);
- printreg(x[i]);
- }
- printitem(ctlr->name, "index10");
- for(i = 0x10; i < 0x18; i++){
- x[i] = rgb524mnxi(vga, i);
- printreg(x[i]);
- }
- printitem(ctlr->name, "index20");
- for(i = 0x20; i < 0x30; i++){
- x[i] = rgb524mnxi(vga, i);
- printreg(x[i]);
- }
- printitem(ctlr->name, "index30");
- for(i = 0x30; i < 0x39; i++){
- x[i] = rgb524mnxi(vga, i);
- printreg(x[i]);
- }
- printitem(ctlr->name, "index40");
- for(i = 0x40; i < 0x49; i++){
- x[i] = rgb524mnxi(vga, i);
- printreg(x[i]);
- }
- printitem(ctlr->name, "index60");
- for(i = 0x60; i < 0x63; i++){
- x[i] = rgb524mnxi(vga, i);
- printreg(x[i]);
- }
- printitem(ctlr->name, "index70");
- for(i = 0x70; i < 0x73; i++){
- x[i] = rgb524mnxi(vga, i);
- printreg(x[i]);
- }
- printitem(ctlr->name, "index8E");
- for(i = 0x8E; i < 0x92; i++){
- x[i] = rgb524mnxi(vga, i);
- printreg(x[i]);
- }
- if(val = dbattr(vga->attr, "rgb524mnrefclk"))
- fref = strtol(val, 0, 0);
- else
- fref = RefFreq;
- if(!(x[SYSCLKControl] & 0x04))
- dumpclock(vga, ctlr, fref, x[0x16], x[0x15], "sysclk");
- fs = x[PLLControl1] & 0x07;
- if(fs == 0x01 || fs == 0x03){
- if(fs == 0x01)
- i = ((vga->misc>>2) & 0x03)*2;
- else
- i = x[PLLControl2] & 0x07;
- dumpclock(vga, ctlr, fref, x[M0+i*2], x[N0+i*2], "pllclk");
- }
- }
- Ctlr rgb524mn = {
- "rgb524mn", /* name */
- 0, /* snarf */
- 0, /* options */
- init, /* init */
- load, /* load */
- dump, /* dump */
- };
|