1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4
5 #include "pci.h"
6 #include "vga.h"
7
8 /*
9 * IC Works W30C516 ZOOMDAC.
10 * DSP-based Multimedia RAMDAC.
11 */
12 enum {
13 Cr0 = 0x00, /* Control register 0 */
14 Mid = 0x01, /* Manufacturer's identification register */
15 Did = 0x02, /* Device identification register */
16 Cr1 = 0x03, /* Control register 1 */
17
18 Reserve1 = 0x04, /* Reserved (16-bit) */
19 Reserve2 = 0x06, /* Reserved (16-bit) */
20 Reserve3 = 0x08, /* Reserved (16-bit) */
21 Reserve4 = 0x0A, /* Reserved (16-bit) */
22
23 IstartX = 0x0C, /* Image Start X (16-bit) */
24 IstartY = 0x0E, /* Image Start Y (16-bit) */
25 IendX = 0x10, /* Image End X (16-bit) */
26 IendY = 0x12, /* Image End Y (16-bit) */
27
28 RatioX = 0x14, /* Ratio X (16-bit) */
29 RatioY = 0x16, /* Ratio Y (16-bit) */
30 OffsetX = 0x18, /* Offset X (16-bit) */
31 OffsetY = 0x1A, /* Offset Y (16-bit) */
32
33 TestR = 0x1C, /* Red signature analysis register */
34 TestG = 0x1D, /* Green signature analysis register */
35 TestB = 0x1E, /* Blue signature analysis register */
36
37 Nir = 0x1F, /* number of indirect registers */
38 };
39
40 static void
options(Vga *,Ctlr * ctlr)41 options(Vga*, Ctlr* ctlr)
42 {
43 ctlr->flag |= Hpclk2x8|Foptions;
44 }
45
46 static void
init(Vga * vga,Ctlr * ctlr)47 init(Vga* vga, Ctlr* ctlr)
48 {
49 ulong grade, pclk;
50 char *p;
51
52 /*
53 * Part comes in -170, -135 and -110MHz speed-grades.
54 * In 8-bit mode the max. PCLK is 135MHz for the -170 part
55 * and the speed-grade for the others. In 2x8-bit mode, the max.
56 * PCLK is the speed-grade, using the 2x doubler.
57 * Work out the part speed-grade from name. Name can have,
58 * e.g. '-135' on the end for 135MHz part.
59 */
60 grade = 110000000;
61 if(p = strrchr(ctlr->name, '-'))
62 grade = strtoul(p+1, 0, 0) * 1000000;
63
64 if(grade == 170000000)
65 pclk = 135000000;
66 else
67 pclk = grade;
68
69 /*
70 * If we don't already have a desired pclk,
71 * take it from the mode.
72 * Check it's within range.
73 */
74 if(vga->f[0] == 0)
75 vga->f[0] = vga->mode->frequency;
76
77 /*
78 * Determine whether to use 2x8-bit mode or not.
79 * If yes and the clock has already been initialised,
80 * initialise it again. There is no real frequency
81 * restriction, it's really just a lower limit on what's
82 * available in some clock generator chips.
83 */
84 if(vga->ctlr && (vga->ctlr->flag & Hpclk2x8) && vga->mode->z == 8 && vga->f[0] >= 60000000){
85 vga->f[0] /= 2;
86 resyncinit(vga, ctlr, Upclk2x8, 0);
87 }
88 if(vga->f[0] > pclk)
89 error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]);
90
91 ctlr->flag |= Finit;
92 }
93
94 static void
load(Vga * vga,Ctlr * ctlr)95 load(Vga* vga, Ctlr* ctlr)
96 {
97 uchar mode, x;
98
99 /*
100 * Put the chip to sleep.
101 */
102 attdaco(Cr0, 0x08);
103
104 mode = 0x00;
105 if(ctlr->flag & Upclk2x8)
106 mode = 0x20;
107
108 /*
109 * Set the mode in the RAMDAC, setting 6/8-bit colour
110 * as appropriate and waking the chip back up.
111 */
112 if(vga->mode->z == 8 && 0)
113 mode |= 0x02;
114 x = attdaci(Cr1) & 0x80;
115 attdaco(Cr1, x);
116 attdaco(Cr0, mode);
117
118 ctlr->flag |= Fload;
119 }
120
121 static void
dump(Vga *,Ctlr * ctlr)122 dump(Vga*, Ctlr* ctlr)
123 {
124 int i;
125
126 printitem(ctlr->name, "");
127 for(i = 0; i < Nir; i++)
128 printreg(attdaci(i));
129 }
130
131 Ctlr w30c516 = {
132 "w30c516", /* name */
133 0, /* snarf */
134 options, /* options */
135 init, /* init */
136 load, /* load */
137 dump, /* dump */
138 };
139