xref: /plan9/sys/src/cmd/aux/vga/stg1702.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 
5 #include "pci.h"
6 #include "vga.h"
7 
8 /*
9  * SGS-Thompson STG1702 Enhanced True Color Palette-DAC
10  * with 16-bit Pixel Port.
11  */
12 enum {
13 	Command		= 0x00,		/* Pixel Command Register */
14 	IndexLO		= 0x01,		/* LO-byte of 16-bit Index */
15 	IndexHI		= 0x02,		/* HI-byte of 16-bit Index */
16 	Index		= 0x03,		/* Indexed Register */
17 
18 	CompanyID	= 0x00,		/* Company ID = 0x44 */
19 	DeviceID	= 0x01,		/* Device ID = 0x02 */
20 	Pmode		= 0x03,		/* Primary Pixel Mode Select */
21 	Smode		= 0x04,		/* Secondary Pixel Mode Select */
22 	Pipeline	= 0x05,		/* Pipeline Timing Control */
23 	Sreset		= 0x06,		/* Soft Reset */
24 	Power		= 0x07,		/* Power Management */
25 
26 	Nindex		= 0x08,
27 };
28 
29 static void
pixmask(void)30 pixmask(void)
31 {
32 	inportb(PaddrW);
33 }
34 
35 static void
commandrw(void)36 commandrw(void)
37 {
38 	int i;
39 
40 	pixmask();
41 	for(i = 0; i < 4; i++)
42 		inportb(Pixmask);
43 }
44 
45 static uchar
commandr(void)46 commandr(void)
47 {
48 	uchar command;
49 
50 	commandrw();
51 	command = inportb(Pixmask);
52 	pixmask();
53 
54 	return command;
55 }
56 
57 static void
commandw(uchar command)58 commandw(uchar command)
59 {
60 	commandrw();
61 	outportb(Pixmask, command);
62 	pixmask();
63 }
64 
65 static void
indexrw(uchar index)66 indexrw(uchar index)
67 {
68 	uchar command;
69 
70 	command = commandr();
71 	commandw(command|0x10);
72 
73 	commandrw();
74 	inportb(Pixmask);
75 	outportb(Pixmask, index & 0xFF);
76 	outportb(Pixmask, (index>>8) & 0xFF);
77 }
78 
79 static void
options(Vga *,Ctlr * ctlr)80 options(Vga*, Ctlr* ctlr)
81 {
82 	ctlr->flag |= Hpclk2x8|Foptions;
83 }
84 
85 static void
init(Vga * vga,Ctlr * ctlr)86 init(Vga* vga, Ctlr* ctlr)
87 {
88 	ulong pclk;
89 
90 	/*
91 	 * Part comes in -135MHz speed-grade.
92 	 * In 8-bit mode the max. PCLK is 110MHz. In 2x8-bit mode
93 	 * the max. PCLK is the speed-grade, using the 2x doubler.
94 	 * We can use mode 2 (2x8-bit, internal clock doubler)
95 	 * if connected to a suitable graphics chip, e.g. the
96 	 * ET4000-w32p.
97 	 */
98 	if(vga->ctlr && ((vga->ctlr->flag & Hpclk2x8) && vga->mode->z == 8))
99 		pclk = 135000000;
100 	else
101 		pclk = 110000000;
102 
103 	/*
104 	 * If we don't already have a desired pclk,
105 	 * take it from the mode.
106 	 * Check it's within range.
107 	 */
108 	if(vga->f[0] == 0)
109 		vga->f[0] = vga->mode->frequency;
110 	if(vga->f[0] < 16000000 || vga->f[0] > pclk)
111 		error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]);
112 
113 	/*
114 	 * Determine whether to use 2x8-bit mode or not.
115 	 * If yes and the clock has already been initialised,
116 	 * initialise it again.
117 	 */
118 	if(vga->ctlr && (vga->ctlr->flag & Hpclk2x8) && vga->mode->z == 8 && vga->f[0] >= 110000000){
119 		vga->f[0] /= 2;
120 		resyncinit(vga, ctlr, Upclk2x8, 0);
121 	}
122 
123 	ctlr->flag |= Finit;
124 }
125 
126 static void
load(Vga * vga,Ctlr * ctlr)127 load(Vga* vga, Ctlr* ctlr)
128 {
129 	uchar command, mode, pipeline;
130 
131 	command = 0x00;
132 	mode = 0x00;
133 	pipeline = 0x02;
134 	if(ctlr->flag & Upclk2x8){
135 		command = 0x08;
136 		mode = 0x05;
137 		pipeline = 0x02;
138 		if(vga->f[0] < 16000000)
139 			pipeline = 0x00;
140 		else if(vga->f[0] < 32000000)
141 			pipeline = 0x01;
142 	}
143 
144 	indexrw(Pmode);
145 	outportb(Pixmask, mode);
146 	outportb(Pixmask, mode);
147 	outportb(Pixmask, pipeline);
148 	sleep(1);
149 	commandw(command);
150 
151 	ctlr->flag |= Fload;
152 }
153 
154 static void
dump(Vga *,Ctlr * ctlr)155 dump(Vga*, Ctlr* ctlr)
156 {
157 	int i;
158 
159 	printitem(ctlr->name, "command");
160 	printreg(commandr());
161 
162 	printitem(ctlr->name, "index");
163 	indexrw(CompanyID);
164 	for(i = 0; i < Nindex; i++)
165 		printreg(inportb(Pixmask));
166 
167 	pixmask();
168 }
169 
170 Ctlr stg1702 = {
171 	"stg1702",			/* name */
172 	0,				/* snarf */
173 	options,			/* options */
174 	init,				/* init */
175 	load,				/* load */
176 	dump,				/* dump */
177 };
178