ref: f4f19cdf1a8f0d2aa5f9fce10c896201528b5347
dir: /sys/src/cmd/aux/vga/stg1702.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "pci.h" #include "vga.h" /* * SGS-Thompson STG1702 Enhanced True Color Palette-DAC * with 16-bit Pixel Port. */ enum { Command = 0x00, /* Pixel Command Register */ IndexLO = 0x01, /* LO-byte of 16-bit Index */ IndexHI = 0x02, /* HI-byte of 16-bit Index */ Index = 0x03, /* Indexed Register */ CompanyID = 0x00, /* Company ID = 0x44 */ DeviceID = 0x01, /* Device ID = 0x02 */ Pmode = 0x03, /* Primary Pixel Mode Select */ Smode = 0x04, /* Secondary Pixel Mode Select */ Pipeline = 0x05, /* Pipeline Timing Control */ Sreset = 0x06, /* Soft Reset */ Power = 0x07, /* Power Management */ Nindex = 0x08, }; static void pixmask(void) { inportb(PaddrW); } static void commandrw(void) { int i; pixmask(); for(i = 0; i < 4; i++) inportb(Pixmask); } static uchar commandr(void) { uchar command; commandrw(); command = inportb(Pixmask); pixmask(); return command; } static void commandw(uchar command) { commandrw(); outportb(Pixmask, command); pixmask(); } static void indexrw(uchar index) { uchar command; command = commandr(); commandw(command|0x10); commandrw(); inportb(Pixmask); outportb(Pixmask, index & 0xFF); outportb(Pixmask, (index>>8) & 0xFF); } static void options(Vga*, Ctlr* ctlr) { ctlr->flag |= Hpclk2x8|Foptions; } static void init(Vga* vga, Ctlr* ctlr) { ulong pclk; /* * Part comes in -135MHz speed-grade. * In 8-bit mode the max. PCLK is 110MHz. In 2x8-bit mode * the max. PCLK is the speed-grade, using the 2x doubler. * We can use mode 2 (2x8-bit, internal clock doubler) * if connected to a suitable graphics chip, e.g. the * ET4000-w32p. */ if(vga->ctlr && ((vga->ctlr->flag & Hpclk2x8) && vga->mode->z == 8)) pclk = 135000000; else pclk = 110000000; /* * 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] < 16000000 || vga->f[0] > pclk) error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]); /* * Determine whether to use 2x8-bit mode or not. * If yes and the clock has already been initialised, * initialise it again. */ if(vga->ctlr && (vga->ctlr->flag & Hpclk2x8) && vga->mode->z == 8 && vga->f[0] >= 110000000){ vga->f[0] /= 2; resyncinit(vga, ctlr, Upclk2x8, 0); } ctlr->flag |= Finit; } static void load(Vga* vga, Ctlr* ctlr) { uchar command, mode, pipeline; command = 0x00; mode = 0x00; pipeline = 0x02; if(ctlr->flag & Upclk2x8){ command = 0x08; mode = 0x05; pipeline = 0x02; if(vga->f[0] < 16000000) pipeline = 0x00; else if(vga->f[0] < 32000000) pipeline = 0x01; } indexrw(Pmode); outportb(Pixmask, mode); outportb(Pixmask, mode); outportb(Pixmask, pipeline); sleep(1); commandw(command); ctlr->flag |= Fload; } static void dump(Vga*, Ctlr* ctlr) { int i; printitem(ctlr->name, "command"); printreg(commandr()); printitem(ctlr->name, "index"); indexrw(CompanyID); for(i = 0; i < Nindex; i++) printreg(inportb(Pixmask)); pixmask(); } Ctlr stg1702 = { "stg1702", /* name */ 0, /* snarf */ options, /* options */ init, /* init */ load, /* load */ dump, /* dump */ };