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