FreeBSD/Linux Kernel Cross Reference
sys/chips/ims332.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: ims332.c,v $
29 * Revision 2.6 93/01/14 17:16:29 danner
30 * Added support for different monitors.
31 * [92/11/30 jtp]
32 *
33 * Revision 2.4.1.2 92/09/25 13:09:15 af
34 * Reversed Red and Blue, so it works with color Maxines.
35 * The chip spec doesn't really say where r, g and b go.
36 * I'm also a little confused about whether r, g and b are
37 * 16 or 8 bit quantities here. For now, assume they are 8,
38 * because that appears to work.
39 * [92/09/25 moore]
40 *
41 * Revision 2.5 92/05/22 15:48:03 jfriedl
42 * Some fields in user_info_t got renamed.
43 * [92/05/13 20:40:39 af]
44 *
45 * Revision 2.4 92/05/05 10:04:55 danner
46 * Unconditionally do the reset at init time.
47 * Fixed blooper in loading cursor colors.
48 * [92/04/14 11:53:29 af]
49 *
50 * Revision 2.3 92/03/05 11:36:47 rpd
51 * Got real specs ( thanks Jukki!! ):
52 * "IMS G332 colour video controller"
53 * 1990 Databook, pp 139-163, Inmos Ltd.
54 * [92/03/03 af]
55 *
56 * Revision 2.2 92/03/02 18:32:50 rpd
57 * Created stub copy to make things compile.
58 * [92/03/02 af]
59 *
60 */
61 /*
62 * File: ims332.c
63 * Author: Alessandro Forin, Carnegie Mellon University
64 * Date: 1/92
65 *
66 * Routines for the Inmos IMS-G332 Colour video controller
67 */
68
69 #include <platforms.h>
70
71 #include <chips/ims332.h>
72 #include <chips/screen.h>
73
74 #include <chips/xcfb_monitor.h>
75
76 /*
77 * Generic register access
78 */
79 typedef volatile unsigned char *ims332_padded_regmap_t;
80
81 #ifdef MAXINE
82
83 unsigned int
84 ims332_read_register(regs, regno)
85 unsigned char *regs;
86 {
87 unsigned char *rptr;
88 register unsigned int val, v1;
89
90 /* spec sez: */
91 rptr = regs + 0x80000 + (regno << 4);
92 val = * ((volatile unsigned short *) rptr );
93 v1 = * ((volatile unsigned short *) regs );
94
95 return (val & 0xffff) | ((v1 & 0xff00) << 8);
96 }
97
98 ims332_write_register(regs, regno, val)
99 unsigned char *regs;
100 register unsigned int val;
101 {
102 unsigned char *wptr;
103
104 /* spec sez: */
105 wptr = regs + 0xa0000 + (regno << 4);
106 * ((volatile unsigned int *)(regs)) = (val >> 8) & 0xff00;
107 * ((volatile unsigned short *)(wptr)) = val;
108 }
109
110 #define assert_ims332_reset_bit(r) *r &= ~0x40
111 #define deassert_ims332_reset_bit(r) *r |= 0x40
112
113 #else /*MAXINE*/
114
115 #define ims332_read_register(p,r) \
116 ((unsigned int *)(p)) [ (r) ]
117 #define ims332_write_register(p,r,v) \
118 ((unsigned int *)(p)) [ (r) ] = (v)
119
120 #endif /*MAXINE*/
121
122
123 /*
124 * Color map
125 */
126 ims332_load_colormap( regs, map)
127 ims332_padded_regmap_t *regs;
128 color_map_t *map;
129 {
130 register int i;
131
132 for (i = 0; i < 256; i++, map++)
133 ims332_load_colormap_entry(regs, i, map);
134 }
135
136 ims332_load_colormap_entry( regs, entry, map)
137 ims332_padded_regmap_t *regs;
138 color_map_t *map;
139 {
140 /* ?? stop VTG */
141 ims332_write_register(regs, IMS332_REG_LUT_BASE + (entry & 0xff),
142 (map->blue << 16) |
143 (map->green << 8) |
144 (map->red));
145 }
146
147 ims332_init_colormap( regs)
148 ims332_padded_regmap_t *regs;
149 {
150 color_map_t m;
151
152 m.red = m.green = m.blue = 0;
153 ims332_load_colormap_entry( regs, 0, &m);
154
155 m.red = m.green = m.blue = 0xff;
156 ims332_load_colormap_entry( regs, 1, &m);
157 ims332_load_colormap_entry( regs, 255, &m);
158
159 /* since we are at it, also fix cursor LUT */
160 ims332_load_colormap_entry( regs, IMS332_REG_CURSOR_LUT_0, &m);
161 ims332_load_colormap_entry( regs, IMS332_REG_CURSOR_LUT_1, &m);
162 /* *we* do not use this, but the prom does */
163 ims332_load_colormap_entry( regs, IMS332_REG_CURSOR_LUT_2, &m);
164 }
165
166 #if 1/*debug*/
167 ims332_print_colormap( regs)
168 ims332_padded_regmap_t *regs;
169 {
170 register int i;
171
172 for (i = 0; i < 256; i++) {
173 register unsigned int color;
174
175 color = ims332_read_register( regs, IMS332_REG_LUT_BASE + i);
176 printf("%x->[x%x x%x x%x]\n", i,
177 (color >> 16) & 0xff,
178 (color >> 8) & 0xff,
179 color & 0xff);
180 }
181 }
182 #endif
183
184 /*
185 * Video on/off
186 *
187 * It is unfortunate that X11 goes backward with white@0
188 * and black@1. So we must stash away the zero-th entry
189 * and fix it while screen is off. Also must remember
190 * it, sigh.
191 */
192 struct vstate {
193 ims332_padded_regmap_t *regs;
194 unsigned short off;
195 };
196
197 ims332_video_off(vstate, up)
198 struct vstate *vstate;
199 user_info_t *up;
200 {
201 register ims332_padded_regmap_t *regs = vstate->regs;
202 register unsigned *save, csr;
203
204 if (vstate->off)
205 return;
206
207 /* Yes, this is awful */
208 save = (unsigned *)up->dev_dep_2.gx.colormap;
209
210 *save = ims332_read_register(regs, IMS332_REG_LUT_BASE);
211
212 ims332_write_register(regs, IMS332_REG_LUT_BASE, 0);
213
214 ims332_write_register( regs, IMS332_REG_COLOR_MASK, 0);
215
216 /* cursor now */
217 csr = ims332_read_register(regs, IMS332_REG_CSR_A);
218 csr |= IMS332_CSR_A_DISABLE_CURSOR;
219 ims332_write_register(regs, IMS332_REG_CSR_A, csr);
220
221 vstate->off = 1;
222 }
223
224 ims332_video_on(vstate, up)
225 struct vstate *vstate;
226 user_info_t *up;
227 {
228 register ims332_padded_regmap_t *regs = vstate->regs;
229 register unsigned *save, csr;
230
231 if (!vstate->off)
232 return;
233
234 /* Like I said.. */
235 save = (unsigned *)up->dev_dep_2.gx.colormap;
236
237 ims332_write_register(regs, IMS332_REG_LUT_BASE, *save);
238
239 ims332_write_register( regs, IMS332_REG_COLOR_MASK, 0xffffffff);
240
241 /* cursor now */
242 csr = ims332_read_register(regs, IMS332_REG_CSR_A);
243 csr &= ~IMS332_CSR_A_DISABLE_CURSOR;
244 ims332_write_register(regs, IMS332_REG_CSR_A, csr);
245
246 vstate->off = 0;
247 }
248
249 /*
250 * Cursor
251 */
252 ims332_pos_cursor(regs,x,y)
253 ims332_padded_regmap_t *regs;
254 register int x,y;
255 {
256 ims332_write_register( regs, IMS332_REG_CURSOR_LOC,
257 ((x & 0xfff) << 12) | (y & 0xfff) );
258 }
259
260
261 ims332_cursor_color( regs, color)
262 ims332_padded_regmap_t *regs;
263 color_map_t *color;
264 {
265 /* Bg is color[0], Fg is color[1] */
266 ims332_write_register(regs, IMS332_REG_CURSOR_LUT_0,
267 (color->blue << 16) |
268 (color->green << 8) |
269 (color->red));
270 color++;
271 ims332_write_register(regs, IMS332_REG_CURSOR_LUT_1,
272 (color->blue << 16) |
273 (color->green << 8) |
274 (color->red));
275 }
276
277 ims332_cursor_sprite( regs, cursor)
278 ims332_padded_regmap_t *regs;
279 unsigned short *cursor;
280 {
281 register int i;
282
283 /* We *could* cut this down a lot... */
284 for (i = 0; i < 512; i++, cursor++)
285 ims332_write_register( regs,
286 IMS332_REG_CURSOR_RAM+i, *cursor);
287 }
288
289 /*
290 * Initialization
291 */
292 ims332_init(regs, reset, mon)
293 ims332_padded_regmap_t *regs;
294 unsigned int *reset;
295 xcfb_monitor_type_t mon;
296 {
297 int shortdisplay, broadpulse, frontporch;
298
299 assert_ims332_reset_bit(reset);
300 delay(1); /* specs sez 50ns.. */
301 deassert_ims332_reset_bit(reset);
302
303 /* CLOCKIN appears to receive a 6.25 Mhz clock --> PLL 12 for 75Mhz monitor */
304 ims332_write_register(regs, IMS332_REG_BOOT, 12 | IMS332_BOOT_CLOCK_PLL);
305
306 /* initialize VTG */
307 ims332_write_register(regs, IMS332_REG_CSR_A,
308 IMS332_BPP_8 | IMS332_CSR_A_DISABLE_CURSOR);
309 delay(50); /* spec does not say */
310
311 /* datapath registers (values taken from prom's settings) */
312
313 frontporch = mon->line_time - (mon->half_sync * 2 +
314 mon->back_porch +
315 mon->frame_visible_width / 4);
316
317 shortdisplay = mon->line_time / 2 - (mon->half_sync * 2 +
318 mon->back_porch + frontporch);
319 broadpulse = mon->line_time / 2 - frontporch;
320
321 ims332_write_register( regs, IMS332_REG_HALF_SYNCH, mon->half_sync);
322 ims332_write_register( regs, IMS332_REG_BACK_PORCH, mon->back_porch);
323 ims332_write_register( regs, IMS332_REG_DISPLAY,
324 mon->frame_visible_width / 4);
325 ims332_write_register( regs, IMS332_REG_SHORT_DIS, shortdisplay);
326 ims332_write_register( regs, IMS332_REG_BROAD_PULSE, broadpulse);
327 ims332_write_register( regs, IMS332_REG_V_SYNC, mon->v_sync * 2);
328 ims332_write_register( regs, IMS332_REG_V_PRE_EQUALIZE,
329 mon->v_pre_equalize);
330 ims332_write_register( regs, IMS332_REG_V_POST_EQUALIZE,
331 mon->v_post_equalize);
332 ims332_write_register( regs, IMS332_REG_V_BLANK, mon->v_blank * 2);
333 ims332_write_register( regs, IMS332_REG_V_DISPLAY,
334 mon->frame_visible_height * 2);
335 ims332_write_register( regs, IMS332_REG_LINE_TIME, mon->line_time);
336 ims332_write_register( regs, IMS332_REG_LINE_START, mon->line_start);
337 ims332_write_register( regs, IMS332_REG_MEM_INIT, mon->mem_init);
338 ims332_write_register( regs, IMS332_REG_XFER_DELAY, mon->xfer_delay);
339
340 ims332_write_register( regs, IMS332_REG_COLOR_MASK, 0xffffff);
341
342 ims332_init_colormap( regs );
343
344 ims332_write_register(regs, IMS332_REG_CSR_A,
345 IMS332_BPP_8 | IMS332_CSR_A_DMA_DISABLE | IMS332_CSR_A_VTG_ENABLE);
346
347 }
Cache object: 8d1abbaf6f41eae8451a68979c792608
|