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