File: /usr/src/linux/drivers/sgi/char/newport.c
1 /*
2 * newport.c: context switching the newport graphics card and
3 * newport graphics support.
4 *
5 * Author: Miguel de Icaza
6 */
7
8 #include <linux/errno.h>
9 #include <linux/sched.h>
10 #include <asm/types.h>
11 #include <asm/gfx.h>
12 #include <asm/ng1.h>
13 #include <asm/uaccess.h>
14 #include <video/newport.h>
15 #include <linux/module.h>
16
17 struct newport_regs *npregs;
18
19 EXPORT_SYMBOL(npregs);
20
21 /* Kernel routines for supporting graphics context switching */
22
23 void newport_save (void *y)
24 {
25 newport_ctx *x = y;
26 newport_wait ();
27
28 #define LOAD(val) x->val = npregs->set.val;
29 #define LOADI(val) x->val = npregs->set.val.word;
30 #define LOADC(val) x->val = npregs->cset.val;
31
32 LOAD(drawmode1);
33 LOAD(drawmode0);
34 LOAD(lsmode);
35 LOAD(lspattern);
36 LOAD(lspatsave);
37 LOAD(zpattern);
38 LOAD(colorback);
39 LOAD(colorvram);
40 LOAD(alpharef);
41 LOAD(smask0x);
42 LOAD(smask0y);
43 LOADI(_xstart);
44 LOADI(_ystart);
45 LOADI(_xend);
46 LOADI(_yend);
47 LOAD(xsave);
48 LOAD(xymove);
49 LOADI(bresd);
50 LOADI(bress1);
51 LOAD(bresoctinc1);
52 LOAD(bresrndinc2);
53 LOAD(brese1);
54 LOAD(bress2);
55 LOAD(aweight0);
56 LOAD(aweight1);
57 LOADI(colorred);
58 LOADI(coloralpha);
59 LOADI(colorgrn);
60 LOADI(colorblue);
61 LOADI(slopered);
62 LOADI(slopealpha);
63 LOADI(slopegrn);
64 LOADI(slopeblue);
65 LOAD(wrmask);
66 LOAD(hostrw0);
67 LOAD(hostrw1);
68
69 /* configregs */
70
71 LOADC(smask1x);
72 LOADC(smask1y);
73 LOADC(smask2x);
74 LOADC(smask2y);
75 LOADC(smask3x);
76 LOADC(smask3y);
77 LOADC(smask4x);
78 LOADC(smask4y);
79 LOADC(topscan);
80 LOADC(xywin);
81 LOADC(clipmode);
82 LOADC(config);
83
84 /* Mhm, maybe I am missing something, but it seems that
85 * saving/restoring the DCB is only a matter of saving these
86 * registers
87 */
88
89 newport_bfwait ();
90 LOAD (dcbmode);
91 newport_bfwait ();
92 x->dcbdata0 = npregs->set.dcbdata0.byword;
93 newport_bfwait ();
94 LOAD(dcbdata1);
95 }
96
97 /*
98 * Importat things to keep in mind when restoring the newport context:
99 *
100 * 1. slopered register is stored as a 2's complete (s12.11);
101 * needs to be converted to a signed magnitude (s(8)12.11).
102 *
103 * 2. xsave should be stored after xstart.
104 *
105 * 3. None of the registers should be written with the GO address.
106 * (read the docs for more details on this).
107 */
108 void newport_restore (void *y)
109 {
110 newport_ctx *x = y;
111 #define STORE(val) npregs->set.val = x->val
112 #define STOREI(val) npregs->set.val.word = x->val
113 #define STOREC(val) npregs->cset.val = x->val
114 newport_wait ();
115
116 STORE(drawmode1);
117 STORE(drawmode0);
118 STORE(lsmode);
119 STORE(lspattern);
120 STORE(lspatsave);
121 STORE(zpattern);
122 STORE(colorback);
123 STORE(colorvram);
124 STORE(alpharef);
125 STORE(smask0x);
126 STORE(smask0y);
127 STOREI(_xstart);
128 STOREI(_ystart);
129 STOREI(_xend);
130 STOREI(_yend);
131 STORE(xsave);
132 STORE(xymove);
133 STOREI(bresd);
134 STOREI(bress1);
135 STORE(bresoctinc1);
136 STORE(bresrndinc2);
137 STORE(brese1);
138 STORE(bress2);
139 STORE(aweight0);
140 STORE(aweight1);
141 STOREI(colorred);
142 STOREI(coloralpha);
143 STOREI(colorgrn);
144 STOREI(colorblue);
145 STOREI(slopered);
146 STOREI(slopealpha);
147 STOREI(slopegrn);
148 STOREI(slopeblue);
149 STORE(wrmask);
150 STORE(hostrw0);
151 STORE(hostrw1);
152
153 /* configregs */
154
155 STOREC(smask1x);
156 STOREC(smask1y);
157 STOREC(smask2x);
158 STOREC(smask2y);
159 STOREC(smask3x);
160 STOREC(smask3y);
161 STOREC(smask4x);
162 STOREC(smask4y);
163 STOREC(topscan);
164 STOREC(xywin);
165 STOREC(clipmode);
166 STOREC(config);
167
168 /* FIXME: restore dcb thingies */
169 }
170
171 int
172 newport_ioctl (int card, int cmd, unsigned long arg)
173 {
174 switch (cmd){
175 case NG1_SETDISPLAYMODE: {
176 struct ng1_setdisplaymode_args request;
177
178 if (copy_from_user (&request, (void *) arg, sizeof (request)))
179 return -EFAULT;
180
181 newport_wait ();
182 newport_bfwait ();
183 npregs->set.dcbmode = DCB_XMAP0 | XM9_CRS_FIFO_AVAIL |
184 DCB_DATAWIDTH_1 | R_DCB_XMAP9_PROTOCOL;
185 xmap9FIFOWait (npregs);
186
187 /* FIXME: timing is wrong, just be extracted from
188 * the per-board timing table. I still have to figure
189 * out where this comes from
190 *
191 * This is used to select the protocol used to talk to
192 * the xmap9. For now I am using 60, selecting the
193 * WSLOW_DCB_XMAP9_PROTOCOL.
194 *
195 * Robert Tray comments on this issue:
196 *
197 * cfreq refers to the frequency of the monitor
198 * (ie. the refresh rate). Our monitors run typically
199 * between 60 Hz and 76 Hz. But it will be as low as
200 * 50 Hz if you're displaying NTSC/PAL and as high as
201 * 120 Hz if you are runining in stereo mode. You
202 * might want to try the WSLOW values.
203 */
204 xmap9SetModeReg (npregs, request.wid, request.mode, 60);
205 return 0;
206 }
207 case NG1_SET_CURSOR_HOTSPOT: {
208 struct ng1_set_cursor_hotspot request;
209
210 if (copy_from_user (&request, (void *) arg, sizeof (request)))
211 return -EFAULT;
212 /* FIXME: make request.xhot, request.yhot the hot spot */
213 return 0;
214 }
215
216 case NG1_SETGAMMARAMP0:
217 /* FIXME: load the gamma ramps :-) */
218 return 0;
219
220 }
221 return -EINVAL;
222 }
223