Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#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 */
};