vidc20config.c revision 1.2.4.3 1 1.2.4.3 nathanw /* $NetBSD: vidc20config.c,v 1.2.4.3 2002/02/28 04:07:39 nathanw Exp $ */
2 1.2.4.2 nathanw
3 1.2.4.2 nathanw /*
4 1.2.4.2 nathanw * Copyright (c) 2001 Reinoud Zandijk
5 1.2.4.2 nathanw * Copyright (c) 1996 Mark Brinicombe
6 1.2.4.2 nathanw * Copyright (c) 1996 Robert Black
7 1.2.4.2 nathanw * Copyright (c) 1994-1995 Melvyn Tang-Richardson
8 1.2.4.2 nathanw * Copyright (c) 1994-1995 RiscBSD kernel team
9 1.2.4.2 nathanw * All rights reserved.
10 1.2.4.2 nathanw *
11 1.2.4.2 nathanw * Redistribution and use in source and binary forms, with or without
12 1.2.4.2 nathanw * modification, are permitted provided that the following conditions
13 1.2.4.2 nathanw * are met:
14 1.2.4.2 nathanw * 1. Redistributions of source code must retain the above copyright
15 1.2.4.2 nathanw * notice, this list of conditions and the following disclaimer.
16 1.2.4.2 nathanw * 2. Redistributions in binary form must reproduce the above copyright
17 1.2.4.2 nathanw * notice, this list of conditions and the following disclaimer in the
18 1.2.4.2 nathanw * documentation and/or other materials provided with the distribution.
19 1.2.4.2 nathanw * 3. All advertising materials mentioning features or use of this software
20 1.2.4.2 nathanw * must display the following acknowledgement:
21 1.2.4.2 nathanw * This product includes software developed by the RiscBSD kernel team
22 1.2.4.2 nathanw * 4. The name of the company nor the name of the author may be used to
23 1.2.4.2 nathanw * endorse or promote products derived from this software without specific
24 1.2.4.2 nathanw * prior written permission.
25 1.2.4.2 nathanw *
26 1.2.4.2 nathanw * THIS SOFTWARE IS PROVIDED BY THE RISCBSD TEAM ``AS IS'' AND ANY EXPRESS
27 1.2.4.2 nathanw * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 1.2.4.2 nathanw * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 1.2.4.2 nathanw * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
30 1.2.4.2 nathanw * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.2.4.2 nathanw * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.2.4.2 nathanw * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.2.4.2 nathanw * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.2.4.2 nathanw * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.2.4.2 nathanw * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
36 1.2.4.2 nathanw * THE POSSIBILITY OF SUCH DAMAGE.
37 1.2.4.2 nathanw *
38 1.2.4.2 nathanw * NetBSD kernel project
39 1.2.4.2 nathanw *
40 1.2.4.2 nathanw * vidcvideo.c
41 1.2.4.2 nathanw *
42 1.2.4.2 nathanw * This file is the lower basis of the wscons driver for VIDC based ARM machines.
43 1.2.4.2 nathanw * It features the initialisation and all VIDC writing and keeps in internal state
44 1.2.4.2 nathanw * copy.
45 1.2.4.2 nathanw * Its currenly set up as a library file and not as a device; it could be named
46 1.2.4.2 nathanw * vidcvideo0 eventually.
47 1.2.4.2 nathanw */
48 1.2.4.2 nathanw
49 1.2.4.2 nathanw #include <sys/cdefs.h>
50 1.2.4.3 nathanw
51 1.2.4.3 nathanw __RCSID("$NetBSD: vidc20config.c,v 1.2.4.3 2002/02/28 04:07:39 nathanw Exp $");
52 1.2.4.3 nathanw
53 1.2.4.2 nathanw #include <sys/types.h>
54 1.2.4.2 nathanw #include <sys/param.h>
55 1.2.4.2 nathanw #include <arm/iomd/vidc.h>
56 1.2.4.2 nathanw #include <arm/arm32/katelib.h>
57 1.2.4.2 nathanw #include <machine/bootconfig.h>
58 1.2.4.2 nathanw #include <machine/intr.h>
59 1.2.4.2 nathanw
60 1.2.4.2 nathanw #include <sys/systm.h>
61 1.2.4.2 nathanw #include <sys/device.h>
62 1.2.4.2 nathanw #include <uvm/uvm_extern.h>
63 1.2.4.2 nathanw
64 1.2.4.2 nathanw #include <arm/iomd/iomdreg.h>
65 1.2.4.2 nathanw #include <arm/iomd/iomdvar.h>
66 1.2.4.2 nathanw #include <arm/iomd/vidc20config.h>
67 1.2.4.2 nathanw
68 1.2.4.2 nathanw /*
69 1.2.4.2 nathanw * A structure containing ALL the information required to restore
70 1.2.4.2 nathanw * the VIDC20 to any given state. ALL vidc transactions should
71 1.2.4.2 nathanw * go through these procedures, which record the vidc's state.
72 1.2.4.2 nathanw * it may be an idea to set the permissions of the vidc base address
73 1.2.4.2 nathanw * so we get a fault, so the fault routine can record the state but
74 1.2.4.2 nathanw * I guess that's not really necessary for the time being, since we
75 1.2.4.2 nathanw * can make the kernel more secure later on. Also, it is possible
76 1.2.4.2 nathanw * to write a routine to allow 'reading' of the vidc registers.
77 1.2.4.2 nathanw */
78 1.2.4.2 nathanw
79 1.2.4.2 nathanw static struct vidc_state vidc_lookup = {
80 1.2.4.2 nathanw { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
81 1.2.4.2 nathanw 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
82 1.2.4.2 nathanw 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
83 1.2.4.2 nathanw 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
84 1.2.4.2 nathanw 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
85 1.2.4.2 nathanw 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
86 1.2.4.2 nathanw 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
87 1.2.4.2 nathanw 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0
88 1.2.4.2 nathanw },
89 1.2.4.2 nathanw
90 1.2.4.2 nathanw VIDC_PALREG,
91 1.2.4.2 nathanw VIDC_BCOL,
92 1.2.4.2 nathanw VIDC_CP1 ,
93 1.2.4.2 nathanw VIDC_CP2,
94 1.2.4.2 nathanw VIDC_CP3,
95 1.2.4.2 nathanw VIDC_HCR,
96 1.2.4.2 nathanw VIDC_HSWR,
97 1.2.4.2 nathanw VIDC_HBSR,
98 1.2.4.2 nathanw VIDC_HDSR,
99 1.2.4.2 nathanw VIDC_HDER,
100 1.2.4.2 nathanw VIDC_HBER,
101 1.2.4.2 nathanw VIDC_HCSR,
102 1.2.4.2 nathanw VIDC_HIR,
103 1.2.4.2 nathanw VIDC_VCR,
104 1.2.4.2 nathanw VIDC_VSWR,
105 1.2.4.2 nathanw VIDC_VBSR,
106 1.2.4.2 nathanw VIDC_VDSR,
107 1.2.4.2 nathanw VIDC_VDER,
108 1.2.4.2 nathanw VIDC_VBER,
109 1.2.4.2 nathanw VIDC_VCSR,
110 1.2.4.2 nathanw VIDC_VCER,
111 1.2.4.2 nathanw VIDC_EREG,
112 1.2.4.2 nathanw VIDC_FSYNREG,
113 1.2.4.2 nathanw VIDC_CONREG,
114 1.2.4.2 nathanw VIDC_DCTL
115 1.2.4.2 nathanw };
116 1.2.4.2 nathanw
117 1.2.4.2 nathanw struct vidc_state vidc_current[1];
118 1.2.4.2 nathanw
119 1.2.4.2 nathanw
120 1.2.4.2 nathanw /*
121 1.2.4.2 nathanw * XXX global display variables XXX ... should be a structure
122 1.2.4.2 nathanw */
123 1.2.4.2 nathanw static int cold_init = 0; /* flags initialisation */
124 1.2.4.2 nathanw extern videomemory_t videomemory;
125 1.2.4.2 nathanw
126 1.2.4.2 nathanw static struct vidc_mode vidc_initialmode;
127 1.2.4.2 nathanw static struct vidc_mode *vidc_currentmode;
128 1.2.4.2 nathanw
129 1.2.4.2 nathanw unsigned int dispstart;
130 1.2.4.2 nathanw unsigned int dispsize;
131 1.2.4.2 nathanw unsigned int dispbase;
132 1.2.4.2 nathanw unsigned int dispend;
133 1.2.4.2 nathanw unsigned int ptov;
134 1.2.4.2 nathanw unsigned int vmem_base;
135 1.2.4.2 nathanw unsigned int phys_base;
136 1.2.4.2 nathanw unsigned int transfersize;
137 1.2.4.2 nathanw
138 1.2.4.2 nathanw
139 1.2.4.2 nathanw /* cursor stuff */
140 1.2.4.2 nathanw char *cursor_normal;
141 1.2.4.2 nathanw char *cursor_transparent;
142 1.2.4.2 nathanw int p_cursor_normal;
143 1.2.4.2 nathanw int p_cursor_transparent;
144 1.2.4.2 nathanw int cursor_width;
145 1.2.4.2 nathanw int cursor_height;
146 1.2.4.2 nathanw
147 1.2.4.2 nathanw
148 1.2.4.2 nathanw /*
149 1.2.4.2 nathanw * VIDC mode definitions
150 1.2.4.2 nathanw * generated from RISC OS mode definition file by an `awk' script
151 1.2.4.2 nathanw */
152 1.2.4.2 nathanw extern struct vidc_mode vidcmodes[];
153 1.2.4.2 nathanw
154 1.2.4.2 nathanw
155 1.2.4.2 nathanw /*
156 1.2.4.2 nathanw * configuration printing
157 1.2.4.2 nathanw *
158 1.2.4.2 nathanw */
159 1.2.4.2 nathanw
160 1.2.4.2 nathanw void
161 1.2.4.2 nathanw vidcvideo_printdetails(void)
162 1.2.4.2 nathanw {
163 1.2.4.2 nathanw printf(": refclk=%dMHz %dKB %s ", (vidc_fref / 1000000),
164 1.2.4.2 nathanw videomemory.vidm_size / 1024,
165 1.2.4.2 nathanw (videomemory.vidm_type == VIDEOMEM_TYPE_VRAM) ? "VRAM" : "DRAM");
166 1.2.4.2 nathanw }
167 1.2.4.2 nathanw
168 1.2.4.2 nathanw /*
169 1.2.4.2 nathanw * Common functions to directly access VIDC registers
170 1.2.4.2 nathanw */
171 1.2.4.2 nathanw int
172 1.2.4.2 nathanw vidcvideo_write(reg, value)
173 1.2.4.2 nathanw u_int reg;
174 1.2.4.2 nathanw int value;
175 1.2.4.2 nathanw {
176 1.2.4.2 nathanw int counter;
177 1.2.4.2 nathanw
178 1.2.4.2 nathanw int *current;
179 1.2.4.2 nathanw int *tab;
180 1.2.4.2 nathanw
181 1.2.4.2 nathanw tab = (int *)&vidc_lookup;
182 1.2.4.2 nathanw current = (int *)vidc_current;
183 1.2.4.2 nathanw
184 1.2.4.2 nathanw
185 1.2.4.2 nathanw /*
186 1.2.4.2 nathanw * OK, the VIDC_PALETTE register is handled differently
187 1.2.4.2 nathanw * to the others on the VIDC, so take that into account here
188 1.2.4.2 nathanw */
189 1.2.4.2 nathanw if (reg==VIDC_PALREG) {
190 1.2.4.2 nathanw vidc_current->palreg = 0;
191 1.2.4.2 nathanw WriteWord(vidc_base, reg | value);
192 1.2.4.2 nathanw return 0;
193 1.2.4.2 nathanw }
194 1.2.4.2 nathanw
195 1.2.4.2 nathanw if (reg==VIDC_PALETTE) {
196 1.2.4.2 nathanw WriteWord(vidc_base, reg | value);
197 1.2.4.2 nathanw vidc_current->palette[vidc_current->palreg] = value;
198 1.2.4.2 nathanw vidc_current->palreg++;
199 1.2.4.2 nathanw vidc_current->palreg = vidc_current->palreg & 0xff;
200 1.2.4.2 nathanw return 0;
201 1.2.4.2 nathanw }
202 1.2.4.2 nathanw
203 1.2.4.2 nathanw /*
204 1.2.4.2 nathanw * Undefine SAFER if you wish to speed things up (a little)
205 1.2.4.2 nathanw * although this means the function will assume things abou
206 1.2.4.2 nathanw * the structure of vidc_state. i.e. the first 256 words are
207 1.2.4.2 nathanw * the palette array
208 1.2.4.2 nathanw */
209 1.2.4.2 nathanw
210 1.2.4.2 nathanw #define SAFER
211 1.2.4.2 nathanw
212 1.2.4.2 nathanw #ifdef SAFER
213 1.2.4.2 nathanw #define INITVALUE 0
214 1.2.4.2 nathanw #else
215 1.2.4.2 nathanw #define INITVALUE 256
216 1.2.4.2 nathanw #endif
217 1.2.4.2 nathanw
218 1.2.4.2 nathanw for ( counter=INITVALUE; counter<= sizeof(struct vidc_state); counter++ ) {
219 1.2.4.2 nathanw if ( reg==tab[counter] ) {
220 1.2.4.2 nathanw WriteWord ( vidc_base, reg | value );
221 1.2.4.2 nathanw current[counter] = value;
222 1.2.4.2 nathanw return 0;
223 1.2.4.2 nathanw }
224 1.2.4.2 nathanw }
225 1.2.4.2 nathanw return -1;
226 1.2.4.2 nathanw }
227 1.2.4.2 nathanw
228 1.2.4.2 nathanw
229 1.2.4.2 nathanw void
230 1.2.4.2 nathanw vidcvideo_setpalette(vidc)
231 1.2.4.2 nathanw struct vidc_state *vidc;
232 1.2.4.2 nathanw {
233 1.2.4.2 nathanw int counter = 0;
234 1.2.4.2 nathanw
235 1.2.4.2 nathanw vidcvideo_write(VIDC_PALREG, 0x00000000);
236 1.2.4.2 nathanw for (counter = 0; counter < 255; counter++)
237 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, vidc->palette[counter]);
238 1.2.4.2 nathanw }
239 1.2.4.2 nathanw
240 1.2.4.2 nathanw
241 1.2.4.2 nathanw void
242 1.2.4.2 nathanw vidcvideo_setstate(vidc)
243 1.2.4.2 nathanw struct vidc_state *vidc;
244 1.2.4.2 nathanw {
245 1.2.4.2 nathanw vidcvideo_write ( VIDC_PALREG, vidc->palreg );
246 1.2.4.2 nathanw vidcvideo_write ( VIDC_BCOL, vidc->bcol );
247 1.2.4.2 nathanw vidcvideo_write ( VIDC_CP1, vidc->cp1 );
248 1.2.4.2 nathanw vidcvideo_write ( VIDC_CP2, vidc->cp2 );
249 1.2.4.2 nathanw vidcvideo_write ( VIDC_CP3, vidc->cp3 );
250 1.2.4.2 nathanw vidcvideo_write ( VIDC_HCR, vidc->hcr );
251 1.2.4.2 nathanw vidcvideo_write ( VIDC_HSWR, vidc->hswr );
252 1.2.4.2 nathanw vidcvideo_write ( VIDC_HBSR, vidc->hbsr );
253 1.2.4.2 nathanw vidcvideo_write ( VIDC_HDSR, vidc->hdsr );
254 1.2.4.2 nathanw vidcvideo_write ( VIDC_HDER, vidc->hder );
255 1.2.4.2 nathanw vidcvideo_write ( VIDC_HBER, vidc->hber );
256 1.2.4.2 nathanw vidcvideo_write ( VIDC_HCSR, vidc->hcsr );
257 1.2.4.2 nathanw vidcvideo_write ( VIDC_HIR, vidc->hir );
258 1.2.4.2 nathanw vidcvideo_write ( VIDC_VCR, vidc->vcr );
259 1.2.4.2 nathanw vidcvideo_write ( VIDC_VSWR, vidc->vswr );
260 1.2.4.2 nathanw vidcvideo_write ( VIDC_VBSR, vidc->vbsr );
261 1.2.4.2 nathanw vidcvideo_write ( VIDC_VDSR, vidc->vdsr );
262 1.2.4.2 nathanw vidcvideo_write ( VIDC_VDER, vidc->vder );
263 1.2.4.2 nathanw vidcvideo_write ( VIDC_VBER, vidc->vber );
264 1.2.4.2 nathanw vidcvideo_write ( VIDC_VCSR, vidc->vcsr );
265 1.2.4.2 nathanw vidcvideo_write ( VIDC_VCER, vidc->vcer );
266 1.2.4.2 nathanw /*
267 1.2.4.2 nathanw * Right, dunno what to set these to yet, but let's keep RiscOS's
268 1.2.4.2 nathanw * ones for now, until the time is right to finish this code
269 1.2.4.2 nathanw */
270 1.2.4.2 nathanw
271 1.2.4.2 nathanw /* vidcvideo_write ( VIDC_EREG, vidc->ereg ); */
272 1.2.4.2 nathanw /* vidcvideo_write ( VIDC_FSYNREG, vidc->fsynreg ); */
273 1.2.4.2 nathanw /* vidcvideo_write ( VIDC_CONREG, vidc->conreg ); */
274 1.2.4.2 nathanw /* vidcvideo_write ( VIDC_DCTL, vidc->dctl ); */
275 1.2.4.2 nathanw
276 1.2.4.2 nathanw }
277 1.2.4.2 nathanw
278 1.2.4.2 nathanw
279 1.2.4.2 nathanw void
280 1.2.4.2 nathanw vidcvideo_getstate(vidc)
281 1.2.4.2 nathanw struct vidc_state *vidc;
282 1.2.4.2 nathanw {
283 1.2.4.2 nathanw *vidc = *vidc_current;
284 1.2.4.2 nathanw }
285 1.2.4.2 nathanw
286 1.2.4.2 nathanw
287 1.2.4.2 nathanw void
288 1.2.4.2 nathanw vidcvideo_getmode(mode)
289 1.2.4.2 nathanw struct vidc_mode *mode;
290 1.2.4.2 nathanw {
291 1.2.4.2 nathanw *mode = *vidc_currentmode;
292 1.2.4.2 nathanw }
293 1.2.4.2 nathanw
294 1.2.4.2 nathanw
295 1.2.4.2 nathanw void
296 1.2.4.2 nathanw vidcvideo_stdpalette()
297 1.2.4.2 nathanw {
298 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALREG | 0x00000000);
299 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL( 0, 0, 0));
300 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 0, 0));
301 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL( 0, 255, 0));
302 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 255, 0));
303 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL( 0, 0, 255));
304 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 0, 255));
305 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL( 0, 255, 255));
306 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 255, 255));
307 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(128, 128, 128));
308 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 128, 128));
309 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(128, 255, 128));
310 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 255, 128));
311 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(128, 128, 255));
312 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 128, 255));
313 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(128, 255, 255));
314 1.2.4.2 nathanw WriteWord(vidc_base, VIDC_PALETTE | VIDC_COL(255, 255, 255));
315 1.2.4.2 nathanw }
316 1.2.4.2 nathanw
317 1.2.4.2 nathanw
318 1.2.4.2 nathanw static int
319 1.2.4.2 nathanw vidcvideo_coldinit(void)
320 1.2.4.2 nathanw {
321 1.2.4.2 nathanw int found;
322 1.2.4.2 nathanw int loop;
323 1.2.4.2 nathanw
324 1.2.4.2 nathanw /* Blank out the cursor */
325 1.2.4.2 nathanw
326 1.2.4.2 nathanw vidcvideo_write(VIDC_CP1, 0x0);
327 1.2.4.2 nathanw vidcvideo_write(VIDC_CP2, 0x0);
328 1.2.4.2 nathanw vidcvideo_write(VIDC_CP3, 0x0);
329 1.2.4.2 nathanw
330 1.2.4.2 nathanw /* Try to determine the current mode */
331 1.2.4.2 nathanw vidc_initialmode.hder = bootconfig.width+1;
332 1.2.4.2 nathanw vidc_initialmode.vder = bootconfig.height+1;
333 1.2.4.2 nathanw vidc_initialmode.log2_bpp = bootconfig.log2_bpp;
334 1.2.4.2 nathanw
335 1.2.4.2 nathanw dispbase = vmem_base = dispstart = videomemory.vidm_vbase;
336 1.2.4.2 nathanw phys_base = videomemory.vidm_pbase;
337 1.2.4.2 nathanw
338 1.2.4.2 nathanw /* Nut - should be using videomemory.vidm_size - mark */
339 1.2.4.2 nathanw if (videomemory.vidm_type == VIDEOMEM_TYPE_DRAM) {
340 1.2.4.2 nathanw dispsize = videomemory.vidm_size;
341 1.2.4.2 nathanw transfersize = 16;
342 1.2.4.2 nathanw } else {
343 1.2.4.2 nathanw dispsize = bootconfig.vram[0].pages * NBPG;
344 1.2.4.2 nathanw transfersize = dispsize >> 10;
345 1.2.4.2 nathanw };
346 1.2.4.2 nathanw
347 1.2.4.2 nathanw ptov = dispbase - phys_base;
348 1.2.4.2 nathanw
349 1.2.4.2 nathanw dispend = dispstart+dispsize;
350 1.2.4.2 nathanw
351 1.2.4.2 nathanw /* try to find the current mode from the bootloader in my table */
352 1.2.4.2 nathanw vidc_currentmode = &vidcmodes[0];
353 1.2.4.2 nathanw loop = 0;
354 1.2.4.2 nathanw found = 0;
355 1.2.4.2 nathanw while (vidcmodes[loop].pixel_rate != 0) {
356 1.2.4.2 nathanw if (vidcmodes[loop].hder == (bootconfig.width + 1)
357 1.2.4.2 nathanw && vidcmodes[loop].vder == (bootconfig.height + 1)
358 1.2.4.2 nathanw && vidcmodes[loop].frame_rate == bootconfig.framerate) {
359 1.2.4.2 nathanw vidc_currentmode = &vidcmodes[loop];
360 1.2.4.2 nathanw found = 1;
361 1.2.4.2 nathanw }
362 1.2.4.2 nathanw ++loop;
363 1.2.4.2 nathanw }
364 1.2.4.2 nathanw
365 1.2.4.2 nathanw /* if not found choose first mode but dont be picky on the framerate */
366 1.2.4.2 nathanw if (!found) {
367 1.2.4.2 nathanw vidc_currentmode = &vidcmodes[0];
368 1.2.4.2 nathanw loop = 0;
369 1.2.4.2 nathanw found = 0;
370 1.2.4.2 nathanw
371 1.2.4.2 nathanw while (vidcmodes[loop].pixel_rate != 0) {
372 1.2.4.2 nathanw if (vidcmodes[loop].hder == (bootconfig.width + 1)
373 1.2.4.2 nathanw && vidcmodes[loop].vder == (bootconfig.height + 1)) {
374 1.2.4.2 nathanw vidc_currentmode = &vidcmodes[loop];
375 1.2.4.2 nathanw found = 1;
376 1.2.4.2 nathanw }
377 1.2.4.2 nathanw ++loop;
378 1.2.4.2 nathanw }
379 1.2.4.2 nathanw }
380 1.2.4.2 nathanw
381 1.2.4.2 nathanw vidc_currentmode->log2_bpp = bootconfig.log2_bpp;
382 1.2.4.2 nathanw
383 1.2.4.2 nathanw dispstart = dispbase;
384 1.2.4.2 nathanw dispend = dispstart+dispsize;
385 1.2.4.2 nathanw
386 1.2.4.2 nathanw IOMD_WRITE_WORD(IOMD_VIDINIT, dispstart-ptov);
387 1.2.4.2 nathanw IOMD_WRITE_WORD(IOMD_VIDSTART, dispstart-ptov);
388 1.2.4.2 nathanw IOMD_WRITE_WORD(IOMD_VIDEND, (dispend-transfersize)-ptov);
389 1.2.4.2 nathanw return 0;
390 1.2.4.2 nathanw }
391 1.2.4.2 nathanw
392 1.2.4.2 nathanw
393 1.2.4.2 nathanw /* simple function to abstract vidc variables ; returns virt start address of screen */
394 1.2.4.2 nathanw /* XXX asumption that video memory is mapped in twice */
395 1.2.4.2 nathanw void *vidcvideo_hwscroll(int bytes) {
396 1.2.4.2 nathanw dispstart += bytes;
397 1.2.4.2 nathanw if (dispstart >= dispbase + dispsize) dispstart -= dispsize;
398 1.2.4.2 nathanw if (dispstart < dispbase) dispstart += dispsize;
399 1.2.4.2 nathanw dispend = dispstart+dispsize;
400 1.2.4.2 nathanw
401 1.2.4.2 nathanw /* return the start of the bit map of the screen (left top) */
402 1.2.4.2 nathanw return (void *) dispstart;
403 1.2.4.2 nathanw }
404 1.2.4.2 nathanw
405 1.2.4.2 nathanw
406 1.2.4.2 nathanw /* reset the HW scroll to be at the start for the benefit of f.e. X */
407 1.2.4.2 nathanw void *vidcvideo_hwscroll_reset(void) {
408 1.2.4.2 nathanw void *cookie = (void *) dispstart;
409 1.2.4.2 nathanw
410 1.2.4.2 nathanw dispstart = dispbase;
411 1.2.4.2 nathanw dispend = dispstart + dispsize;
412 1.2.4.2 nathanw return cookie;
413 1.2.4.2 nathanw }
414 1.2.4.2 nathanw
415 1.2.4.2 nathanw
416 1.2.4.2 nathanw /* put HW scroll back to where it was */
417 1.2.4.2 nathanw void *vidcvideo_hwscroll_back(void *cookie) {
418 1.2.4.2 nathanw dispstart = (int) cookie;
419 1.2.4.2 nathanw dispend = dispstart + dispsize;
420 1.2.4.2 nathanw return cookie;
421 1.2.4.2 nathanw }
422 1.2.4.2 nathanw
423 1.2.4.2 nathanw
424 1.2.4.2 nathanw /* this function is to be called at vsync */
425 1.2.4.2 nathanw void vidcvideo_progr_scroll(void) {
426 1.2.4.2 nathanw IOMD_WRITE_WORD(IOMD_VIDINIT, dispstart-ptov);
427 1.2.4.2 nathanw IOMD_WRITE_WORD(IOMD_VIDSTART, dispstart-ptov);
428 1.2.4.2 nathanw IOMD_WRITE_WORD(IOMD_VIDEND, (dispend-transfersize)-ptov);
429 1.2.4.2 nathanw }
430 1.2.4.2 nathanw
431 1.2.4.2 nathanw
432 1.2.4.2 nathanw /*
433 1.2.4.2 nathanw * Select a new mode by reprogramming the VIDC chip
434 1.2.4.2 nathanw * XXX this part is known not to work for 32bpp
435 1.2.4.2 nathanw */
436 1.2.4.2 nathanw
437 1.2.4.2 nathanw struct vidc_mode newmode;
438 1.2.4.2 nathanw
439 1.2.4.2 nathanw static const int bpp_mask_table[] = {
440 1.2.4.2 nathanw 0, /* 1bpp */
441 1.2.4.2 nathanw 1, /* 2bpp */
442 1.2.4.2 nathanw 2, /* 4bpp */
443 1.2.4.2 nathanw 3, /* 8bpp */
444 1.2.4.2 nathanw 4, /* 16bpp */
445 1.2.4.2 nathanw 6 /* 32bpp */
446 1.2.4.2 nathanw };
447 1.2.4.2 nathanw
448 1.2.4.2 nathanw
449 1.2.4.2 nathanw void
450 1.2.4.2 nathanw vidcvideo_setmode(struct vidc_mode *mode)
451 1.2.4.2 nathanw {
452 1.2.4.2 nathanw register int acc;
453 1.2.4.2 nathanw int bpp_mask;
454 1.2.4.2 nathanw int ereg;
455 1.2.4.2 nathanw int best_r, best_v;
456 1.2.4.2 nathanw int least_error;
457 1.2.4.2 nathanw int r, v, f;
458 1.2.4.2 nathanw
459 1.2.4.2 nathanw /*
460 1.2.4.2 nathanw * Find out what bit mask we need to or with the vidc20 control register
461 1.2.4.2 nathanw * in order to generate the desired number of bits per pixel.
462 1.2.4.2 nathanw * log_bpp is log base 2 of the number of bits per pixel.
463 1.2.4.2 nathanw */
464 1.2.4.2 nathanw
465 1.2.4.2 nathanw bpp_mask = bpp_mask_table[mode->log2_bpp];
466 1.2.4.2 nathanw
467 1.2.4.2 nathanw newmode = *mode;
468 1.2.4.2 nathanw vidc_currentmode = &newmode;
469 1.2.4.2 nathanw
470 1.2.4.2 nathanw least_error = INT_MAX;
471 1.2.4.2 nathanw best_r = 0; best_v = 0;
472 1.2.4.2 nathanw
473 1.2.4.2 nathanw for (v = 63; v > 0; v--) {
474 1.2.4.2 nathanw for (r = 63; r > 0; r--) {
475 1.2.4.2 nathanw f = ((v * vidc_fref) /1000) / r;
476 1.2.4.2 nathanw if (least_error >=
477 1.2.4.2 nathanw abs(f - vidc_currentmode->pixel_rate)) {
478 1.2.4.2 nathanw least_error =
479 1.2.4.2 nathanw abs(f - vidc_currentmode->pixel_rate);
480 1.2.4.2 nathanw best_r = r;
481 1.2.4.2 nathanw best_v = v;
482 1.2.4.2 nathanw }
483 1.2.4.2 nathanw }
484 1.2.4.2 nathanw }
485 1.2.4.2 nathanw
486 1.2.4.2 nathanw if (best_r > 63) best_r=63;
487 1.2.4.2 nathanw if (best_v > 63) best_v=63;
488 1.2.4.2 nathanw if (best_r < 1) best_r= 1;
489 1.2.4.2 nathanw if (best_v < 1) best_v= 1;
490 1.2.4.2 nathanw
491 1.2.4.2 nathanw vidcvideo_write(VIDC_FSYNREG, (best_v-1)<<8 | (best_r-1)<<0);
492 1.2.4.2 nathanw
493 1.2.4.2 nathanw acc=0;
494 1.2.4.2 nathanw acc+=vidc_currentmode->hswr; vidcvideo_write(VIDC_HSWR, (acc - 8 ) & (~1));
495 1.2.4.2 nathanw acc+=vidc_currentmode->hbsr; vidcvideo_write(VIDC_HBSR, (acc - 12) & (~1));
496 1.2.4.2 nathanw acc+=vidc_currentmode->hdsr; vidcvideo_write(VIDC_HDSR, (acc - 18) & (~1));
497 1.2.4.2 nathanw acc+=vidc_currentmode->hder; vidcvideo_write(VIDC_HDER, (acc - 18) & (~1));
498 1.2.4.2 nathanw acc+=vidc_currentmode->hber; vidcvideo_write(VIDC_HBER, (acc - 12) & (~1));
499 1.2.4.2 nathanw acc+=vidc_currentmode->hcr; vidcvideo_write(VIDC_HCR, (acc - 8 ) & (~3));
500 1.2.4.2 nathanw
501 1.2.4.2 nathanw acc=0;
502 1.2.4.2 nathanw acc+=vidc_currentmode->vswr; vidcvideo_write(VIDC_VSWR, (acc - 1));
503 1.2.4.2 nathanw acc+=vidc_currentmode->vbsr; vidcvideo_write(VIDC_VBSR, (acc - 1));
504 1.2.4.2 nathanw acc+=vidc_currentmode->vdsr; vidcvideo_write(VIDC_VDSR, (acc - 1));
505 1.2.4.2 nathanw acc+=vidc_currentmode->vder; vidcvideo_write(VIDC_VDER, (acc - 1));
506 1.2.4.2 nathanw acc+=vidc_currentmode->vber; vidcvideo_write(VIDC_VBER, (acc - 1));
507 1.2.4.2 nathanw acc+=vidc_currentmode->vcr; vidcvideo_write(VIDC_VCR, (acc - 1));
508 1.2.4.2 nathanw
509 1.2.4.2 nathanw IOMD_WRITE_WORD(IOMD_FSIZE, vidc_currentmode->vcr
510 1.2.4.2 nathanw + vidc_currentmode->vswr
511 1.2.4.2 nathanw + vidc_currentmode->vber
512 1.2.4.2 nathanw + vidc_currentmode->vbsr - 1);
513 1.2.4.2 nathanw
514 1.2.4.2 nathanw if (dispsize <= 1024*1024)
515 1.2.4.2 nathanw vidcvideo_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 1<<16 | 1<<12);
516 1.2.4.2 nathanw else
517 1.2.4.2 nathanw vidcvideo_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 3<<16 | 1<<12);
518 1.2.4.2 nathanw
519 1.2.4.2 nathanw ereg = 1<<12;
520 1.2.4.2 nathanw if (vidc_currentmode->sync_pol & 0x01)
521 1.2.4.2 nathanw ereg |= 1<<16;
522 1.2.4.2 nathanw if (vidc_currentmode->sync_pol & 0x02)
523 1.2.4.2 nathanw ereg |= 1<<18;
524 1.2.4.2 nathanw vidcvideo_write(VIDC_EREG, ereg);
525 1.2.4.2 nathanw if (dispsize > 1024*1024) {
526 1.2.4.2 nathanw if (vidc_currentmode->hder >= 800)
527 1.2.4.2 nathanw vidcvideo_write(VIDC_CONREG, 7<<8 | bpp_mask<<5);
528 1.2.4.2 nathanw else
529 1.2.4.2 nathanw vidcvideo_write(VIDC_CONREG, 6<<8 | bpp_mask<<5);
530 1.2.4.2 nathanw } else {
531 1.2.4.2 nathanw vidcvideo_write(VIDC_CONREG, 7<<8 | bpp_mask<<5);
532 1.2.4.2 nathanw }
533 1.2.4.2 nathanw }
534 1.2.4.2 nathanw
535 1.2.4.2 nathanw
536 1.2.4.3 nathanw #if 0
537 1.2.4.2 nathanw /* not used for now */
538 1.2.4.2 nathanw void
539 1.2.4.2 nathanw vidcvideo_set_display_base(base)
540 1.2.4.2 nathanw u_int base;
541 1.2.4.2 nathanw {
542 1.2.4.2 nathanw dispstart = dispstart-dispbase + base;
543 1.2.4.2 nathanw dispbase = vmem_base = base;
544 1.2.4.2 nathanw dispend = base + dispsize;
545 1.2.4.2 nathanw ptov = dispbase - phys_base;
546 1.2.4.2 nathanw }
547 1.2.4.3 nathanw #endif
548 1.2.4.2 nathanw
549 1.2.4.2 nathanw
550 1.2.4.2 nathanw /*
551 1.2.4.2 nathanw * Main initialisation routine for now
552 1.2.4.2 nathanw */
553 1.2.4.2 nathanw
554 1.2.4.2 nathanw static int cursor_init = 0;
555 1.2.4.2 nathanw
556 1.2.4.2 nathanw int
557 1.2.4.2 nathanw vidcvideo_init(void)
558 1.2.4.2 nathanw {
559 1.2.4.2 nathanw vidcvideo_coldinit();
560 1.2.4.2 nathanw if (cold_init && (cursor_init == 0))
561 1.2.4.2 nathanw /* vidcvideo_flash_go() */;
562 1.2.4.2 nathanw
563 1.2.4.2 nathanw /* setting a mode goes wrong in 32 bpp ... 8 and 16 seem OK */
564 1.2.4.2 nathanw vidcvideo_setmode(vidc_currentmode);
565 1.2.4.2 nathanw vidcvideo_blank(0); /* display on */
566 1.2.4.2 nathanw
567 1.2.4.2 nathanw vidcvideo_textpalette();
568 1.2.4.2 nathanw
569 1.2.4.2 nathanw if (cold_init == 0) {
570 1.2.4.2 nathanw vidcvideo_write(VIDC_CP1, 0x0);
571 1.2.4.2 nathanw vidcvideo_write(VIDC_CP2, 0x0);
572 1.2.4.2 nathanw vidcvideo_write(VIDC_CP3, 0x0);
573 1.2.4.2 nathanw } else {
574 1.2.4.2 nathanw vidcvideo_cursor_init(CURSOR_MAX_WIDTH, CURSOR_MAX_HEIGHT);
575 1.2.4.2 nathanw };
576 1.2.4.2 nathanw
577 1.2.4.2 nathanw cold_init=1;
578 1.2.4.2 nathanw return 0;
579 1.2.4.2 nathanw }
580 1.2.4.2 nathanw
581 1.2.4.2 nathanw
582 1.2.4.2 nathanw /* reinitialise the vidcvideo */
583 1.2.4.2 nathanw void
584 1.2.4.2 nathanw vidcvideo_reinit()
585 1.2.4.2 nathanw {
586 1.2.4.2 nathanw vidcvideo_coldinit();
587 1.2.4.2 nathanw vidcvideo_setmode(vidc_currentmode);
588 1.2.4.2 nathanw }
589 1.2.4.2 nathanw
590 1.2.4.2 nathanw
591 1.2.4.2 nathanw int
592 1.2.4.2 nathanw vidcvideo_cursor_init(int width, int height)
593 1.2.4.2 nathanw {
594 1.2.4.2 nathanw static char *cursor_data = NULL;
595 1.2.4.2 nathanw int counter;
596 1.2.4.2 nathanw int line;
597 1.2.4.2 nathanw paddr_t pa;
598 1.2.4.2 nathanw
599 1.2.4.2 nathanw cursor_width = width;
600 1.2.4.2 nathanw cursor_height = height;
601 1.2.4.2 nathanw
602 1.2.4.2 nathanw if (!cursor_data) {
603 1.2.4.2 nathanw /* Allocate cursor memory first time round */
604 1.2.4.2 nathanw cursor_data = (char *)uvm_km_zalloc(kernel_map, NBPG);
605 1.2.4.2 nathanw if (!cursor_data)
606 1.2.4.2 nathanw panic("Cannot allocate memory for hardware cursor\n");
607 1.2.4.2 nathanw (void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_data, &pa);
608 1.2.4.2 nathanw IOMD_WRITE_WORD(IOMD_CURSINIT, pa);
609 1.2.4.2 nathanw }
610 1.2.4.2 nathanw
611 1.2.4.2 nathanw /* Blank the cursor while initialising it's sprite */
612 1.2.4.2 nathanw
613 1.2.4.2 nathanw vidcvideo_write ( VIDC_CP1, 0x0 );
614 1.2.4.2 nathanw vidcvideo_write ( VIDC_CP2, 0x0 );
615 1.2.4.2 nathanw vidcvideo_write ( VIDC_CP3, 0x0 );
616 1.2.4.2 nathanw
617 1.2.4.2 nathanw cursor_normal = cursor_data;
618 1.2.4.2 nathanw cursor_transparent = cursor_data + (height * width);
619 1.2.4.2 nathanw
620 1.2.4.2 nathanw cursor_transparent += 32; /* ALIGN */
621 1.2.4.2 nathanw cursor_transparent = (char *)((int)cursor_transparent & (~31) );
622 1.2.4.2 nathanw
623 1.2.4.2 nathanw for ( line = 0; line<height; ++ line )
624 1.2.4.2 nathanw {
625 1.2.4.2 nathanw for ( counter=0; counter<width/4;counter++ )
626 1.2.4.2 nathanw cursor_normal[line * width + counter]=0x55; /* why 0x55 ? */
627 1.2.4.2 nathanw for ( ; counter<8; counter++ )
628 1.2.4.2 nathanw cursor_normal[line * width + counter]=0;
629 1.2.4.2 nathanw }
630 1.2.4.2 nathanw
631 1.2.4.2 nathanw for ( line = 0; line<height; ++ line )
632 1.2.4.2 nathanw {
633 1.2.4.2 nathanw for ( counter=0; counter<width/4;counter++ )
634 1.2.4.2 nathanw cursor_transparent[line * width + counter]=0x00;
635 1.2.4.2 nathanw for ( ; counter<8; counter++ )
636 1.2.4.2 nathanw cursor_transparent[line * width + counter]=0;
637 1.2.4.2 nathanw }
638 1.2.4.2 nathanw
639 1.2.4.2 nathanw
640 1.2.4.2 nathanw (void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_normal,
641 1.2.4.2 nathanw (paddr_t *)&p_cursor_normal);
642 1.2.4.2 nathanw (void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_transparent,
643 1.2.4.2 nathanw (paddr_t *)&p_cursor_transparent);
644 1.2.4.2 nathanw
645 1.2.4.2 nathanw memset ( cursor_normal, 0x55, width*height ); /* white? */
646 1.2.4.2 nathanw memset ( cursor_transparent, 0x00, width*height ); /* to see the diffence */
647 1.2.4.2 nathanw
648 1.2.4.2 nathanw /* Ok, now program the cursor; should be blank */
649 1.2.4.2 nathanw vidcvideo_enablecursor(0);
650 1.2.4.2 nathanw
651 1.2.4.2 nathanw return 0;
652 1.2.4.2 nathanw }
653 1.2.4.2 nathanw
654 1.2.4.2 nathanw
655 1.2.4.2 nathanw void
656 1.2.4.2 nathanw vidcvideo_updatecursor(xcur, ycur)
657 1.2.4.2 nathanw int xcur, ycur;
658 1.2.4.2 nathanw {
659 1.2.4.2 nathanw int frontporch = vidc_currentmode->hswr + vidc_currentmode->hbsr + vidc_currentmode->hdsr;
660 1.2.4.2 nathanw int topporch = vidc_currentmode->vswr + vidc_currentmode->vbsr + vidc_currentmode->vdsr;
661 1.2.4.2 nathanw
662 1.2.4.2 nathanw vidcvideo_write(VIDC_HCSR, frontporch -17 + xcur);
663 1.2.4.2 nathanw vidcvideo_write(VIDC_VCSR, topporch -2 + (ycur+1)-2 + 3 - cursor_height);
664 1.2.4.2 nathanw vidcvideo_write(VIDC_VCER, topporch -2 + (ycur+3)+2 + 3 );
665 1.2.4.2 nathanw return;
666 1.2.4.2 nathanw }
667 1.2.4.2 nathanw
668 1.2.4.2 nathanw
669 1.2.4.2 nathanw void
670 1.2.4.2 nathanw vidcvideo_enablecursor(on)
671 1.2.4.2 nathanw int on;
672 1.2.4.2 nathanw {
673 1.2.4.2 nathanw if (on) {
674 1.2.4.2 nathanw IOMD_WRITE_WORD(IOMD_CURSINIT,p_cursor_normal);
675 1.2.4.2 nathanw } else {
676 1.2.4.2 nathanw IOMD_WRITE_WORD(IOMD_CURSINIT,p_cursor_transparent);
677 1.2.4.2 nathanw };
678 1.2.4.2 nathanw vidcvideo_write ( VIDC_CP1, 0xffffff ); /* enable */
679 1.2.4.2 nathanw
680 1.2.4.2 nathanw return;
681 1.2.4.2 nathanw }
682 1.2.4.2 nathanw
683 1.2.4.2 nathanw
684 1.2.4.2 nathanw int
685 1.2.4.2 nathanw vidcvideo_textpalette()
686 1.2.4.2 nathanw {
687 1.2.4.2 nathanw vidcvideo_write(VIDC_PALREG, 0x00000000);
688 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL( 0, 0, 0));
689 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 0, 0));
690 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL( 0, 255, 0));
691 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 0));
692 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL( 0, 0, 255));
693 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 0, 255));
694 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL( 0, 255, 255));
695 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 255));
696 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 128, 128));
697 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 128, 128));
698 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 255, 128));
699 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 128));
700 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 128, 255));
701 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 128, 255));
702 1.2.4.2 nathanw vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 255));
703 1.2.4.2 nathanw
704 1.2.4.2 nathanw return 0;
705 1.2.4.2 nathanw }
706 1.2.4.2 nathanw
707 1.2.4.2 nathanw int
708 1.2.4.2 nathanw vidcvideo_blank(video_off)
709 1.2.4.2 nathanw int video_off;
710 1.2.4.2 nathanw {
711 1.2.4.2 nathanw int ereg;
712 1.2.4.2 nathanw
713 1.2.4.2 nathanw ereg = 1<<12;
714 1.2.4.2 nathanw if (vidc_currentmode->sync_pol & 0x01)
715 1.2.4.2 nathanw ereg |= 1<<16;
716 1.2.4.2 nathanw if (vidc_currentmode->sync_pol & 0x02)
717 1.2.4.2 nathanw ereg |= 1<<18;
718 1.2.4.2 nathanw
719 1.2.4.2 nathanw if (!video_off) {
720 1.2.4.2 nathanw vidcvideo_write(VIDC_EREG, ereg);
721 1.2.4.2 nathanw } else {
722 1.2.4.2 nathanw vidcvideo_write(VIDC_EREG, 0);
723 1.2.4.2 nathanw };
724 1.2.4.2 nathanw return 0;
725 1.2.4.2 nathanw }
726 1.2.4.2 nathanw
727 1.2.4.2 nathanw /* end of vidc20config.c */
728