make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / 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 }