xref: /original-bsd/sys/news3400/fb/fbbm_lcdm.c (revision 6093a5ae)
1 /*
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7  *
8  * %sccs.include.redist.c%
9  *
10  * from: $Hdr: fbbm_lcdm.c,v 4.300 91/06/09 06:33:38 root Rel41 $ SONY
11  *
12  *	@(#)fbbm_lcdm.c	7.1 (Berkeley) 06/04/92
13  */
14 
15 /*
16  * LCD frame buffer driver
17  */
18 
19 #include "../include/fix_machine_type.h"
20 
21 #include "lfbm.h"
22 
23 #if NLFBM > 0
24 #ifdef mips
25 #ifndef news3200
26 #define news3200 1
27 #endif /* !news3200 */
28 #endif /* mips */
29 
30 #include "param.h"
31 #include "../iop/framebuf.h"
32 #include "../iop/fbreg.h"
33 
34 #include "../fb/fbdefs.h"
35 
36 #ifdef news1200
37 #include "../hbdev/scsic.h"
38 extern int pend_1185_ioptr;
39 extern int val_1185_ioptr;
40 extern struct scsi_stat scsi_stat;
41 #endif /* news1200 */
42 
43 extern int nofunc();
44 extern int error();
45 extern char *ext_fnt24_addr[];
46 extern char *ext_fnt_addr[];
47 
48 extern short zero[];
49 
50 extern unsigned int mfbmask32[];
51 extern unsigned int mfbrmask32[];
52 
53 #define NOP	for (j = 0; j < 40; j++)
54 
55 #ifdef news1200
56 #define LCD_CRTC	(unsigned char *)(0xe1480000)
57 #define LCD_PORT	(unsigned char *)(0xe1500002)
58 #define DIMMER_PORT	(unsigned char *)(0xe190000f)
59 #define KROM_START	(char *)(0xe2000000)
60 #define	VRAM_START	(unsigned long *)(0xe4000000)
61 #define VRAM_WIDTH	(1120/32)
62 #endif
63 
64 #ifdef news3200
65 #define LCD_PORT	(volatile unsigned long *)(0xb0000000)
66 #define DIMMER_PORT	(volatile unsigned long *)(0xb0100000)
67 #define LCD_CRTC	(volatile unsigned char *)(0xbff60000)
68 #define	KROM_START	(char *)(0x90000000)
69 #define	VRAM_START	(unsigned long *)(0x90200000)
70 #define VRAM_WIDTH	(1120/32)
71 #endif
72 
73 #ifdef news1200
74 static caddr_t
75 fblfbm_Krom_addr(fb, c, sr)
76 	struct fbdev *fb;
77 	register int c;
78 	lRectangle *sr;
79 {
80 	register caddr_t tmp;
81 
82 	if ((c >= 0x20) && (c <= 0x7e)) {
83 		/*
84 		 * ASCII char
85 		 */
86 		c -= ' ';
87 		c = ((c & 0x1f) | ((c & 0xe0) << 2)) << 7;
88 		tmp =  (caddr_t)(c + fb->Krom_base + (sr->extent.y > 16 ? 0 : 96));
89 	} else if ((c >= 0xa1) && (c <= 0xdf)) {
90 		/*
91 		 * KANA char
92 		 */
93 		if (sr->extent.y > 16)
94 			tmp =  (caddr_t)ext_fnt24_addr[c + 64];
95 		else
96 			tmp =  (caddr_t)ext_fnt_addr[c + 64];
97 	} else if ((c >= 0x2020) && (c <= 0x7e7e)) {
98 		/*
99 		 * KANJI char
100 		 */
101 		switch (c & 0x7000) {
102 		case 0x2000:
103 			c = ((c & 0x1f) | ((c & 0x60) << 5) | ((c & 0x700) >> 1)) << 7;
104 			break;
105 		case 0x3000:
106 		case 0x4000:
107 			c = ((c & 0x7f) | ((c & 0xf00) >> 1) | ((c & 0x4000) >> 3)) << 7;
108 			break;
109 		case 0x5000:
110 		case 0x6000:
111 			c = ((c & 0x7f) | ((c & 0xf00) >> 1) | ((c & 0x2000) >> 2)
112 				| 0x1000) << 7;
113 			break;
114 		case 0x7000:
115 			c = ((c & 0x1f) | ((c & 0x60) << 5) | ((c & 0x700) >> 1)
116 				| 0x1000) << 7;
117 			break;
118 		}
119 		tmp =  (caddr_t)(c + fb->Krom_base + (sr->extent.y > 16 ? 0 : 96));
120 	} else {
121 		/*
122 		 * UNKNOWN char
123 		 */
124 		tmp =  (caddr_t)zero;
125 	}
126 	return (tmp);
127 }
128 #endif /* news1200 */
129 
130 #ifdef news3200
131 static caddr_t
132 fblfbm_Krom_addr(fb, c, sr)
133 	struct fbdev *fb;
134 	register int c;
135 	lRectangle *sr;
136 {
137 	register int i;
138 	register u_short *tmp;
139 	static int tmpfnt[24];
140 
141 	if ((c >= 0x20) && (c <= 0x7e)) {
142 		/*
143 		 * ASCII char
144 		 */
145 		c -= ' ';
146 		c = ((c & 0x1f) | ((c & 0xe0) << 2)) << 7;
147 		tmp = (u_short *)(fb->Krom_base + (c + (sr->extent.y > 16 ? 0 : 96)) * 2);
148 	} else if ((c >= 0xa1) && (c <= 0xdf)) {
149 		/*
150 		 * KANA char
151 		 */
152 		if (sr->extent.y > 16)
153 			tmp =  (u_short *)ext_fnt24_addr[c + 64];
154 		else
155 			tmp =  (u_short *)ext_fnt_addr[c + 64];
156 	} else if ((c >= 0x2020) && (c <= 0x7e7e)) {
157 		/*
158 		 * KANJI char
159 		 */
160 		switch (c & 0x7000) {
161 		case 0x2000:
162 			c = ((c & 0x1f) | ((c & 0x60) << 5) | ((c & 0x700) >> 1)) << 7;
163 			break;
164 		case 0x3000:
165 		case 0x4000:
166 			c = ((c & 0x7f) | ((c & 0xf00) >> 1) | ((c & 0x4000) >> 3)) << 7;
167 			break;
168 		case 0x5000:
169 		case 0x6000:
170 			c = ((c & 0x7f) | ((c & 0xf00) >> 1) | ((c & 0x2000) >> 2)
171 				| 0x1000) << 7;
172 			break;
173 		case 0x7000:
174 			c = ((c & 0x1f) | ((c & 0x60) << 5) | ((c & 0x700) >> 1)
175 				| 0x1000) << 7;
176 			break;
177 		}
178 		tmp = (u_short *)(fb->Krom_base + (c + (sr->extent.y > 16 ? 0 : 96)) * 2);
179 	} else {
180 		/*
181 		 * UNKNOWN char
182 		 */
183 		return ((caddr_t)zero);
184 	}
185 
186 	if (sr->extent.y > 16) {
187 		for (i = 0; i < 24; i++) {
188 			tmpfnt[i] = (*tmp << 16) | *(tmp + 2);
189 			tmp += 4;
190 		}
191 	} else {
192 		for (i = 0; i < 16; i++) {
193 			tmpfnt[i] = (*tmp << 16) | *(tmp + 2);
194 			tmp += 4;
195 		}
196 	}
197 
198 	return ((caddr_t)tmpfnt);
199 }
200 #endif /* news3200 */
201 
202 static int
203 fblfbm_set_dimmer(fb, dim)
204 	struct fbdev *fb;
205 	int dim;
206 {
207 	int s;
208 
209 	fb->status_flag = dim ? 0xf1: 0xf0;
210 #ifdef news1200
211 	val_1185_ioptr = fb->status_flag;
212 	if (scsi_stat.ipc >= 0) {
213 		pend_1185_ioptr = 1;
214 	} else {
215 		pend_1185_ioptr = 0;
216 		*DIMMER_PORT = val_1185_ioptr;
217 	}
218 #endif
219 #ifdef news3200
220 	*DIMMER_PORT = fb->status_flag;
221 #endif
222 	return (FB_ROK);
223 }
224 
225 static int
226 fblfbm_get_dimmer(fb)
227 	struct fbdev *fb;
228 {
229 	return (fb->status_flag & 0x1);
230 }
231 
232 int
233 fblfbm_get_pixel(fb, pixel)
234 	struct fbdev *fb;
235 	register int pixel;
236 {
237 	return (pixel);
238 }
239 
240 int
241 fblfbm_get_page(fb, off)
242 	struct fbdev *fb;
243 	off_t off;
244 {
245 	if (off < 1120/8 * 930) {		/* X/8 * Y */
246 #ifdef news1200
247 		return (((unsigned int)VRAM_START + off) >> PGSHIFT);
248 #endif
249 #ifdef news3200
250 		return (((unsigned int)0x10200000 + off) >> PGSHIFT);
251 #endif
252 	} else
253 		return (-1);
254 }
255 
256 int
257 fblfbm_probe(unit)
258 	int unit;
259 {
260 #ifdef news1200
261 	if (unit < NLFBM) {
262 		if (badaddr(VRAM_START, 1))
263 			return 0;
264 		else
265 			return FB_LCDM;
266 	}
267 #endif /* news1200 */
268 #ifdef news3200
269 	if (unit < NLFBM) {
270 		if (badaddr(0xbff50000, 1))
271 			return 0;
272 		else {
273 			if (*(volatile u_char *)(0xbff50000) == 0xff)
274 				return FB_LCDM;
275 			else
276 				return 0;
277 		}
278 	}
279 #endif /* news3200 */
280 	return 0;
281 }
282 
283 void fbmem_rop_init();
284 void fbmem_rop_copy();
285 void fbmem_rop_winit();
286 void fbmem_rop_write();
287 void fbmem_rop_read();
288 void fbmem_rop_cinit();
289 void fbmem_rop_clear();
290 void fbmem_rop_vect();
291 void fbmem_rop_dot();
292 
293 struct fbdev_ops fblfbm_ops = {
294 	fbmem_rop_init,			/* (*fb_rop_init)() */
295 	fbmem_rop_copy,			/* (*fb_rop_copy)() */
296 	fbmem_rop_winit,		/* (*fb_rop_winit)() */
297 	fbmem_rop_write,		/* (*fb_rop_write)() */
298 	fbmem_rop_read,			/* (*fb_rop_read)() */
299 	fbmem_rop_cinit,		/* (*fb_rop_cinit)() */
300 	fbmem_rop_clear,		/* (*fb_rop_clear)() */
301 	fbmem_rop_vect,			/* (*fb_rop_vect)() */
302 	fbmem_rop_dot,			/* (*fb_rop_dot)() */
303 	(void (*)())nofunc,		/* (*fb_rop_fillscan)() */
304 	(void (*)())error,		/* (*fb_rop_wait)() */
305 	(void (*)())error,		/* (*fb_rop_reset)() */
306 	fblfbm_Krom_addr,		/* *(*fb_Krom_addr)() */
307 	(void (*)())error,		/* (*fb_init_palette)() */
308 	error,				/* (*fb_set_palette)() */
309 	error,				/* (*fb_get_palette)() */
310 	fblfbm_get_pixel,		/* (*fb_get_pixel)() */
311 	fblfbm_set_dimmer,		/* (*fb_set_dimmer)() */
312 	fblfbm_get_dimmer,		/* (*fb_get_dimmer)() */
313 	nofunc,				/* (*fb_open)() */
314 	nofunc,				/* (*fb_close)() */
315 	nofunc,				/* (*fb_ioctl)() */
316 	fblfbm_get_page,		/* (*fb_get_page)() */
317 	(void (*)())nofunc,		/* (*fb_cursor_set)() */
318 	(void (*)())nofunc,		/* (*fb_cursor_on)() */
319 	(void (*)())nofunc,		/* (*fb_cursor_off)() */
320 	(void (*)())nofunc,		/* (*fb_cursor_move)() */
321 };
322 
323 static char lctc_data[] = {
324 	0, 47,
325 	1, 35,
326 	9, 0,
327 	10, 0,
328 	11, 0,
329 	12, 0,
330 	13, 0,
331 	14, 0,
332 	15, 0,
333 	18, 35,
334 	19, 0x01,
335 	20, 0x85,
336 	21, 0,
337 	22, 0x10
338 };
339 
340 struct mfbdev fblcd = { (caddr_t)VRAM_START, VRAM_WIDTH };
341 
342 void
343 fblfbm_setup(fb)
344 	register struct fbdev *fb;
345 {
346 	register int i;
347 	register volatile unsigned char *lctreg = LCD_CRTC;
348 
349 	if (fb->type) {
350 		fb->Mono = 1;
351 		fb->Colorwidth = 1;
352 		fb->fbNplane = 1;
353 		fb->planemask = 0x1;
354 		fb->Dimmer = 1;
355 
356 		fb->FrameRect.origin.x = 0;
357 		fb->FrameRect.origin.y = 0;
358 		fb->FrameRect.extent.x = 1120;
359 		fb->FrameRect.extent.y = 930;
360 		fb->VisRect.origin.x = 0;
361 		fb->VisRect.origin.y = 0;
362 		fb->VisRect.extent.x = 1120;
363 		fb->VisRect.extent.y = 780;
364 		fb->Krom_BM0.type = BM_MEM;
365 		fb->Krom_BM0.depth = 1;
366 		fb->Krom_BM0.width = 1;
367 		fb->Krom_BM0.rect.origin.x = 0;
368 		fb->Krom_BM0.rect.origin.y = 0;
369 		fb->Krom_BM0.rect.extent.x = 16;
370 		fb->Krom_BM0.rect.extent.y = 16;
371 		fb->Krom_BM1.type = BM_MEM;
372 		fb->Krom_BM1.depth = 1;
373 		fb->Krom_BM1.width = 2;
374 		fb->Krom_BM1.rect.origin.x = 0;
375 		fb->Krom_BM1.rect.origin.y = 0;
376 		fb->Krom_BM1.rect.extent.x = 32;
377 		fb->Krom_BM1.rect.extent.y = 32;
378 		fb->Krom_base = KROM_START;
379 		fb->Krom_font_extent0.x = 16;
380 		fb->Krom_font_extent0.y = 16;
381 		fb->Krom_font_extent1.x = 24;
382 		fb->Krom_font_extent1.y = 24;
383 		fb->font_w = 12;
384 		fb->font_h = 24;
385 		fb->char_w = 12;
386 		fb->char_h = 26;
387 		fb->scr_w = 1120;
388 		fb->scr_h = 780;
389 		fb->ch_pos = 0;
390 		fb->ul_pos = 24;
391 		fb->x_offset = (1120 - (80 * 12)) / 2;
392 		fb->y_offset = ( 780 - (29 * 26)) / 2;
393 		fb->rit_m = 80;
394 		fb->btm_m = 29;
395 		fb->cursorSet = 0;
396 		fb->cursorVis = 0;
397 		fb->cursorShow = 0;
398 		fb->cursorP.x = 1120/2;
399 		fb->cursorP.y = 780/2;
400 		fb->status_flag = 1;
401 		fb->run_flag = 0;
402 		fb->hard_cursor = 0;
403 
404 		fb->fbbm_op = &fblfbm_ops;
405 
406 		fb->private = (caddr_t)&fblcd;
407 
408 		for (i = 0; i < 28; i++)
409 			*lctreg++ = lctc_data[i];
410 		for (i = 0; i < 500000; i ++)
411 			;
412 		*LCD_PORT = 1;
413 	}
414 }
415 #endif /* NLFBM > 0 */
416