9 * Tvp302[056] Viewpoint Video Interface Palette.
10 * Assumes hooked up to an S3 86C928 or S3 Vision964.
13 Index = 0x06, /* Index register */
14 Data = 0x07, /* Data register */
16 Id = 0x3F, /* ID Register */
23 * The following two arrays give read (bit 0) and write (bit 1)
24 * permissions on the direct and index registers. Bits 4 and 5
25 * are for the Tvp3025. The Tvp3020 has only 8 direct registers.
27 static uchar directreg[32] = {
28 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x33, 0x33,
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
31 0x33, 0x33, 0x11, 0x33, 0x33, 0x33, 0x33, 0x33,
34 static uchar indexreg[64] = {
35 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00,
36 0x02, 0x02, 0x33, 0x00, 0x00, 0x00, 0x30, 0x30,
37 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
38 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x30, 0x00,
39 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
40 0x33, 0x33, 0x33, 0x33, 0x30, 0x30, 0x30, 0x30,
41 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
42 0x33, 0x30, 0x33, 0x11, 0x11, 0x11, 0x22, 0x11,
46 * Check the index register access is valid.
47 * Return the number of direct registers.
50 checkindex(uchar index, uchar access)
56 crt55 = vgaxi(Crtx, 0x55) & 0xFC;
57 vgaxo(Crtx, 0x55, crt55|((Index>>2) & 0x03));
58 vgao(dacxreg[Index & 0x03], Id);
60 id = vgai(dacxreg[Data & 0x03]);
61 vgaxo(Crtx, 0x55, crt55);
79 Bprint(&stdout, "%s: unknown chip id - 0x%2.2X\n", tvp3020.name, id);
83 if(index > sizeof(indexreg) || (indexreg[index] & access) == 0)
84 error("%s: bad register index - 0x%2.2X\n", tvp3020.name, index);
90 tvp3020io(uchar reg, uchar data)
94 crt55 = vgaxi(Crtx, 0x55) & 0xFC;
95 vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
96 vgao(dacxreg[reg & 0x03], data);
106 crt55 = vgaxi(Crtx, 0x55) & 0xFC;
107 vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
108 r = vgai(dacxreg[reg & 0x03]);
109 vgaxo(Crtx, 0x55, crt55);
115 tvp3020xi(uchar index)
119 checkindex(index, 0x01);
121 crt55 = tvp3020io(Index, index);
122 r = vgai(dacxreg[Data & 0x03]);
123 vgaxo(Crtx, 0x55, crt55);
129 tvp3020o(uchar reg, uchar data)
133 crt55 = tvp3020io(reg, data);
134 vgaxo(Crtx, 0x55, crt55);
138 tvp3020xo(uchar index, uchar data)
142 checkindex(index, 0x02);
144 crt55 = tvp3020io(Index, index);
145 vgao(dacxreg[Data & 0x03], data);
146 vgaxo(Crtx, 0x55, crt55);
150 options(Vga*, Ctlr* ctlr)
152 ctlr->flag |= Hclk2|Hextsid|Hpvram|Henhanced|Foptions;
156 init(Vga* vga, Ctlr* ctlr)
162 * Work out the part speed-grade from name. Name can have,
163 * e.g. '-135' on the end for 135MHz part.
166 if(p = strrchr(ctlr->name, '-'))
167 grade = strtoul(p+1, 0, 0) * 1000000;
170 * If we don't already have a desired pclk,
171 * take it from the mode.
172 * Check it's within range.
175 vga->f[0] = vga->mode->frequency;
176 if(vga->f[0] > grade)
177 error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]);
180 * Determine whether to use clock-doubler or not.
182 if(vga->f[0] > 85000000){
184 resyncinit(vga, ctlr, Uclk2, 0);
191 load(Vga* vga, Ctlr* ctlr)
196 * Input Clock Selection:
199 * doubled if necessary.
202 if(ctlr->flag & Uenhanced)
204 if(ctlr->flag & Uclk2)
209 * Output Clock Selection:
211 * enhanced RCLK=SCLK=/8, VCLK/4
214 if(ctlr->flag & Uenhanced)
220 * default settings - self-clocked, palette graphics, no zoom
221 * Colour Key Control:
222 * default settings - pointing to palette graphics
223 * Mux Control Register 1:
226 tvp3020xo(0x29, 0x09);
227 tvp3020xo(0x38, 0x10);
228 tvp3020xo(0x18, 0x80);
231 * Mux Control Register 2:
233 * enhanced 8-bpp, 8:1 mux, 64-bit pixel-bus width
236 if(ctlr->flag & Uenhanced){
237 if(vga->mode->z == 8)
239 else if(vga->mode->z == 1)
246 * output sync polarity
247 * It's important to set this properly and to turn off the
248 * VGA controller H and V syncs. Can't be set in VGA mode.
251 if((vga->misc & 0x40) == 0)
253 if((vga->misc & 0x80) == 0)
257 vgao(MiscW, vga->misc);
260 * Select the DAC via the General Purpose I/O
262 * Guesswork by looking at register dumps.
264 tvp3020xo(0x2A, 0x1F);
265 if(ctlr->flag & Uenhanced)
275 dump(Vga*, Ctlr* ctlr)
281 if(checkindex(0x00, 0x01) != Tvp3020)
284 printitem(ctlr->name, "direct");
285 for(i = 0; i < 8; i++){
286 if(directreg[i] & access)
287 printreg(tvp3020i(i));
292 printitem(ctlr->name, "index");
293 for(i = 0; i < sizeof(indexreg); i++){
294 if(indexreg[i] & access)
295 printreg(tvp3020xi(i));
302 "tvp3020", /* name */
304 options, /* options */