1 /*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. 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 8.1 (Berkeley) 06/11/93
13 */
14
15 /*
16 * LCD frame buffer driver
17 */
18
19 #include "lfbm.h"
20
21 #if NLFBM > 0
22
23 #include <sys/param.h>
24 #include <news3400/iop/framebuf.h>
25 #include <news3400/iop/fbreg.h>
26
27 #include <news3400/fb/fbdefs.h>
28
29 extern int nofunc();
30 extern int error();
31 extern char *ext_fnt24_addr[];
32 extern char *ext_fnt_addr[];
33
34 extern short zero[];
35
36 extern unsigned int mfbmask32[];
37 extern unsigned int mfbrmask32[];
38
39 #define NOP for (j = 0; j < 40; j++)
40
41 #ifdef news3200
42 #define LCD_PORT (volatile unsigned long *)(0xb0000000)
43 #define DIMMER_PORT (volatile unsigned long *)(0xb0100000)
44 #define LCD_CRTC (volatile unsigned char *)(0xbff60000)
45 #define KROM_START (char *)(0x90000000)
46 #define VRAM_START (unsigned long *)(0x90200000)
47 #define VRAM_WIDTH (1120/32)
48 #endif
49
50 void
lfbmattach(i)51 lfbmattach(i)
52 {
53 /* temporary hack for pseudo-device initialization */;
54 }
55
56 #ifdef news3200
57 static caddr_t
fblfbm_Krom_addr(fb,c,sr)58 fblfbm_Krom_addr(fb, c, sr)
59 struct fbdev *fb;
60 register int c;
61 lRectangle *sr;
62 {
63 register int i;
64 register u_short *tmp;
65 static int tmpfnt[24];
66
67 if ((c >= 0x20) && (c <= 0x7e)) {
68 /*
69 * ASCII char
70 */
71 c -= ' ';
72 c = ((c & 0x1f) | ((c & 0xe0) << 2)) << 7;
73 tmp = (u_short *)(fb->Krom_base + (c + (sr->extent.y > 16 ? 0 : 96)) * 2);
74 } else if ((c >= 0xa1) && (c <= 0xdf)) {
75 /*
76 * KANA char
77 */
78 if (sr->extent.y > 16)
79 tmp = (u_short *)ext_fnt24_addr[c + 64];
80 else
81 tmp = (u_short *)ext_fnt_addr[c + 64];
82 } else if ((c >= 0x2020) && (c <= 0x7e7e)) {
83 /*
84 * KANJI char
85 */
86 switch (c & 0x7000) {
87 case 0x2000:
88 c = ((c & 0x1f) | ((c & 0x60) << 5) | ((c & 0x700) >> 1)) << 7;
89 break;
90 case 0x3000:
91 case 0x4000:
92 c = ((c & 0x7f) | ((c & 0xf00) >> 1) | ((c & 0x4000) >> 3)) << 7;
93 break;
94 case 0x5000:
95 case 0x6000:
96 c = ((c & 0x7f) | ((c & 0xf00) >> 1) | ((c & 0x2000) >> 2)
97 | 0x1000) << 7;
98 break;
99 case 0x7000:
100 c = ((c & 0x1f) | ((c & 0x60) << 5) | ((c & 0x700) >> 1)
101 | 0x1000) << 7;
102 break;
103 }
104 tmp = (u_short *)(fb->Krom_base + (c + (sr->extent.y > 16 ? 0 : 96)) * 2);
105 } else {
106 /*
107 * UNKNOWN char
108 */
109 return ((caddr_t)zero);
110 }
111
112 if (sr->extent.y > 16) {
113 for (i = 0; i < 24; i++) {
114 tmpfnt[i] = (*tmp << 16) | *(tmp + 2);
115 tmp += 4;
116 }
117 } else {
118 for (i = 0; i < 16; i++) {
119 tmpfnt[i] = (*tmp << 16) | *(tmp + 2);
120 tmp += 4;
121 }
122 }
123
124 return ((caddr_t)tmpfnt);
125 }
126 #endif /* news3200 */
127
128 static int
fblfbm_set_dimmer(fb,dim)129 fblfbm_set_dimmer(fb, dim)
130 struct fbdev *fb;
131 int dim;
132 {
133 int s;
134
135 fb->status_flag = dim ? 0xf1: 0xf0;
136 #ifdef news3200
137 *DIMMER_PORT = fb->status_flag;
138 #endif
139 return (FB_ROK);
140 }
141
142 static int
fblfbm_get_dimmer(fb)143 fblfbm_get_dimmer(fb)
144 struct fbdev *fb;
145 {
146 return (fb->status_flag & 0x1);
147 }
148
149 int
fblfbm_get_pixel(fb,pixel)150 fblfbm_get_pixel(fb, pixel)
151 struct fbdev *fb;
152 register int pixel;
153 {
154 return (pixel);
155 }
156
157 int
fblfbm_get_page(fb,off)158 fblfbm_get_page(fb, off)
159 struct fbdev *fb;
160 off_t off;
161 {
162 if (off < 1120/8 * 930) { /* X/8 * Y */
163 #ifdef news3200
164 return (((unsigned int)0x10200000 + off) >> PGSHIFT);
165 #endif
166 } else
167 return (-1);
168 }
169
170 int
fblfbm_probe(unit)171 fblfbm_probe(unit)
172 int unit;
173 {
174 #ifdef news3200
175 if (unit < NLFBM) {
176 if (badaddr(0xbff50000, 1))
177 return 0;
178 else {
179 if (*(volatile u_char *)(0xbff50000) == 0xff)
180 return FB_LCDM;
181 else
182 return 0;
183 }
184 }
185 #endif /* news3200 */
186 return 0;
187 }
188
189 void fbmem_rop_init();
190 void fbmem_rop_copy();
191 void fbmem_rop_winit();
192 void fbmem_rop_write();
193 void fbmem_rop_read();
194 void fbmem_rop_cinit();
195 void fbmem_rop_clear();
196 void fbmem_rop_vect();
197 void fbmem_rop_dot();
198
199 struct fbdev_ops fblfbm_ops = {
200 fbmem_rop_init, /* (*fb_rop_init)() */
201 fbmem_rop_copy, /* (*fb_rop_copy)() */
202 fbmem_rop_winit, /* (*fb_rop_winit)() */
203 fbmem_rop_write, /* (*fb_rop_write)() */
204 fbmem_rop_read, /* (*fb_rop_read)() */
205 fbmem_rop_cinit, /* (*fb_rop_cinit)() */
206 fbmem_rop_clear, /* (*fb_rop_clear)() */
207 fbmem_rop_vect, /* (*fb_rop_vect)() */
208 fbmem_rop_dot, /* (*fb_rop_dot)() */
209 (void (*)())nofunc, /* (*fb_rop_fillscan)() */
210 (void (*)())error, /* (*fb_rop_wait)() */
211 (void (*)())error, /* (*fb_rop_reset)() */
212 fblfbm_Krom_addr, /* *(*fb_Krom_addr)() */
213 (void (*)())error, /* (*fb_init_palette)() */
214 error, /* (*fb_set_palette)() */
215 error, /* (*fb_get_palette)() */
216 fblfbm_get_pixel, /* (*fb_get_pixel)() */
217 fblfbm_set_dimmer, /* (*fb_set_dimmer)() */
218 fblfbm_get_dimmer, /* (*fb_get_dimmer)() */
219 nofunc, /* (*fb_open)() */
220 nofunc, /* (*fb_close)() */
221 nofunc, /* (*fb_ioctl)() */
222 fblfbm_get_page, /* (*fb_get_page)() */
223 (void (*)())nofunc, /* (*fb_cursor_set)() */
224 (void (*)())nofunc, /* (*fb_cursor_on)() */
225 (void (*)())nofunc, /* (*fb_cursor_off)() */
226 (void (*)())nofunc, /* (*fb_cursor_move)() */
227 };
228
229 static char lctc_data[] = {
230 0, 47,
231 1, 35,
232 9, 0,
233 10, 0,
234 11, 0,
235 12, 0,
236 13, 0,
237 14, 0,
238 15, 0,
239 18, 35,
240 19, 0x01,
241 20, 0x85,
242 21, 0,
243 22, 0x10
244 };
245
246 struct mfbdev fblcd = { (caddr_t)VRAM_START, VRAM_WIDTH };
247
248 void
fblfbm_setup(fb)249 fblfbm_setup(fb)
250 register struct fbdev *fb;
251 {
252 register int i;
253 register volatile unsigned char *lctreg = LCD_CRTC;
254
255 if (fb->type) {
256 fb->Mono = 1;
257 fb->Colorwidth = 1;
258 fb->fbNplane = 1;
259 fb->planemask = 0x1;
260 fb->Dimmer = 1;
261
262 fb->FrameRect.origin.x = 0;
263 fb->FrameRect.origin.y = 0;
264 fb->FrameRect.extent.x = 1120;
265 fb->FrameRect.extent.y = 930;
266 fb->VisRect.origin.x = 0;
267 fb->VisRect.origin.y = 0;
268 fb->VisRect.extent.x = 1120;
269 fb->VisRect.extent.y = 780;
270 fb->Krom_BM0.type = BM_MEM;
271 fb->Krom_BM0.depth = 1;
272 fb->Krom_BM0.width = 1;
273 fb->Krom_BM0.rect.origin.x = 0;
274 fb->Krom_BM0.rect.origin.y = 0;
275 fb->Krom_BM0.rect.extent.x = 16;
276 fb->Krom_BM0.rect.extent.y = 16;
277 fb->Krom_BM1.type = BM_MEM;
278 fb->Krom_BM1.depth = 1;
279 fb->Krom_BM1.width = 2;
280 fb->Krom_BM1.rect.origin.x = 0;
281 fb->Krom_BM1.rect.origin.y = 0;
282 fb->Krom_BM1.rect.extent.x = 32;
283 fb->Krom_BM1.rect.extent.y = 32;
284 fb->Krom_base = KROM_START;
285 fb->Krom_font_extent0.x = 16;
286 fb->Krom_font_extent0.y = 16;
287 fb->Krom_font_extent1.x = 24;
288 fb->Krom_font_extent1.y = 24;
289 fb->font_w = 12;
290 fb->font_h = 24;
291 fb->char_w = 12;
292 fb->char_h = 26;
293 fb->scr_w = 1120;
294 fb->scr_h = 780;
295 fb->ch_pos = 0;
296 fb->ul_pos = 24;
297 fb->x_offset = (1120 - (80 * 12)) / 2;
298 fb->y_offset = ( 780 - (29 * 26)) / 2;
299 fb->rit_m = 80;
300 fb->btm_m = 29;
301 fb->cursorSet = 0;
302 fb->cursorVis = 0;
303 fb->cursorShow = 0;
304 fb->cursorP.x = 1120/2;
305 fb->cursorP.y = 780/2;
306 fb->status_flag = 1;
307 fb->run_flag = 0;
308 fb->hard_cursor = 0;
309
310 fb->fbbm_op = &fblfbm_ops;
311
312 fb->private = (caddr_t)&fblcd;
313
314 for (i = 0; i < 28; i++)
315 *lctreg++ = lctc_data[i];
316 for (i = 0; i < 500000; i ++)
317 ;
318 *LCD_PORT = 1;
319 }
320 }
321 #endif /* NLFBM > 0 */
322