1 /*        $NetBSD: fb.c,v 1.34 2023/11/04 15:30:52 tsutsui Exp $      */
2 
3 /*-
4  * Copyright (c) 2000 Tsubai Masanari.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 /*-
29  * Copyright (c) 2023 Izumi Tsutsui.  All rights reserved.
30  *
31  * Redistribution and use in source and binary forms, with or without
32  * modification, are permitted provided that the following conditions
33  * are met:
34  * 1. Redistributions of source code must retain the above copyright
35  *    notice, this list of conditions and the following disclaimer.
36  * 2. Redistributions in binary form must reproduce the above copyright
37  *    notice, this list of conditions and the following disclaimer in the
38  *    documentation and/or other materials provided with the distribution.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
41  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
43  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
44  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
46  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
47  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
49  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50  */
51 
52 #include <sys/cdefs.h>
53 __KERNEL_RCSID(0, "$NetBSD: fb.c,v 1.34 2023/11/04 15:30:52 tsutsui Exp $");
54 
55 #include <sys/param.h>
56 #include <sys/device.h>
57 #include <sys/ioctl.h>
58 #include <sys/kmem.h>
59 #include <sys/systm.h>
60 
61 #include <uvm/uvm_extern.h>
62 
63 #include <machine/adrsmap.h>
64 
65 #include <newsmips/dev/hbvar.h>
66 
67 #include <dev/wscons/wsconsio.h>
68 #include <dev/wscons/wsdisplayvar.h>
69 #include <dev/rasops/rasops.h>
70 
71 struct fb_devconfig {
72           uint8_t *dc_fbbase;           /* VRAM base address */
73           struct rasops_info dc_ri;
74           int dc_model;
75 #define NWB253      0
76 #define LCDM        1
77           int dc_displayid;
78 #define NWP512      0
79 #define NWP518      1
80 #define NWE501      2
81           int dc_size;
82 };
83 
84 struct fb_softc {
85           device_t sc_dev;
86           struct fb_devconfig *sc_dc;
87           int sc_nscreens;
88 };
89 
90 static int fb_match(device_t, cfdata_t, void *);
91 static void fb_attach(device_t, device_t, void *);
92 
93 static int fb_common_init(struct fb_devconfig *);
94 static int fb_is_console(void);
95 
96 static int fb_ioctl(void *, void *, u_long, void *, int, struct lwp *);
97 static paddr_t fb_mmap(void *, void *, off_t, int);
98 static int fb_alloc_screen(void *, const struct wsscreen_descr *, void **,
99     int *, int *, long *);
100 static void fb_free_screen(void *, void *);
101 static int fb_show_screen(void *, void *, int, void (*)(void *, int, int),
102     void *);
103 
104 void fb_cnattach(void);
105 
106 static int fb_set_state(struct fb_softc *, int);
107 
108 static bool fb253_probe(void);
109 static bool fblcdm_probe(void);
110 static bool fb_probe_model(struct fb_devconfig *);
111 static void fb_init(struct fb_devconfig *);
112 static void fb253_init(void);
113 static void fblcdm_init(void);
114 
115 CFATTACH_DECL_NEW(fb, sizeof(struct fb_softc),
116     fb_match, fb_attach, NULL, NULL);
117 
118 static struct fb_devconfig fb_console_dc;
119 
120 static struct wsdisplay_accessops fb_accessops = {
121           .ioctl        = fb_ioctl,
122           .mmap         = fb_mmap,
123           .alloc_screen = fb_alloc_screen,
124           .free_screen  = fb_free_screen,
125           .show_screen  = fb_show_screen,
126           .load_font    = NULL
127 };
128 
129 static struct wsscreen_descr fb_stdscreen = {
130           .name = "std",
131           .ncols = 0,
132           .nrows = 0,
133           .textops = NULL,
134           .fontwidth = 0,
135           .fontheight = 0,
136           .capabilities = WSSCREEN_REVERSE
137 };
138 
139 static const struct wsscreen_descr *fb_scrlist[] = {
140           &fb_stdscreen
141 };
142 
143 static struct wsscreen_list fb_screenlist = {
144           .nscreens = __arraycount(fb_scrlist),
145           .screens  = fb_scrlist
146 };
147 
148 #define NWB253_VRAM   0x88000000
149 #define NWB253_CTLREG ((uint16_t *)0xb8ff0000)
150 #define NWB253_CRTREG ((uint16_t *)0xb8fe0000)
151 
152 static const char *nwb253dispname[8] = {
153           [NWP512] = "NWB-512",
154           [NWP518] = "NWB-518",
155           [NWE501] = "NWE-501"
156 }; /* XXX ? */
157 
158 #define LCDM_VRAM   0x90200000
159 #define LCDM_PORT   ((uint32_t *)0xb0000000)
160 #define LCDM_DIMMER ((uint32_t *)0xb0100000)
161 #define LCDM_DIMMER_ON        0xf0
162 #define LCDM_DIMMER_OFF       0xf1
163 #define LCDM_CTRL   ((uint8_t *)0xbff50000)       /* XXX no macro in 4.4BSD */
164 #define LCDM_CRTC   ((uint8_t *)0xbff60000)
165 
166 static int
fb_match(device_t parent,cfdata_t cf,void * aux)167 fb_match(device_t parent, cfdata_t cf, void *aux)
168 {
169           struct hb_attach_args *ha = aux;
170 
171           if (strcmp(ha->ha_name, "fb") != 0)
172                     return 0;
173 
174           if (fb253_probe() && ha->ha_addr == NWB253_VRAM)
175                     return 1;
176           if (fblcdm_probe() && ha->ha_addr == LCDM_VRAM)
177                     return 1;
178 
179           return 0;
180 }
181 
182 static void
fb_attach(device_t parent,device_t self,void * aux)183 fb_attach(device_t parent, device_t self, void *aux)
184 {
185           struct fb_softc *sc = device_private(self);
186           struct wsemuldisplaydev_attach_args waa;
187           struct fb_devconfig *dc;
188           struct rasops_info *ri;
189           int console;
190           const char *devname;
191 
192           sc->sc_dev = self;
193 
194           console = fb_is_console();
195 
196           if (console) {
197                     dc = &fb_console_dc;
198                     ri = &dc->dc_ri;
199                     ri->ri_flg &= ~RI_NO_AUTO;
200                     sc->sc_nscreens = 1;
201           } else {
202                     dc = kmem_zalloc(sizeof(struct fb_devconfig), KM_SLEEP);
203 
204                     fb_probe_model(dc);
205                     fb_common_init(dc);
206                     ri = &dc->dc_ri;
207 
208                     /* clear screen */
209                     (*ri->ri_ops.eraserows)(ri, 0, ri->ri_rows, 0);
210 
211                     fb_init(dc);
212           }
213           sc->sc_dc = dc;
214 
215           switch (dc->dc_model) {
216           case NWB253:
217                     devname = nwb253dispname[dc->dc_displayid];
218                     break;
219           case LCDM:
220                     devname = "LCD-MONO";
221                     break;
222           default:
223                     /* should not be here */
224                     devname = "unknown";
225                     break;
226           }
227           aprint_normal(": %s, %d x %d, %dbpp\n", devname,
228               ri->ri_width, ri->ri_height, ri->ri_depth);
229 
230           waa.console = console;
231           waa.scrdata = &fb_screenlist;
232           waa.accessops = &fb_accessops;
233           waa.accesscookie = sc;
234 
235           config_found(self, &waa, wsemuldisplaydevprint, CFARGS_NONE);
236 }
237 
238 static bool
fb253_probe(void)239 fb253_probe(void)
240 {
241 
242           if (hb_badaddr(NWB253_CTLREG, 2) || hb_badaddr(NWB253_CRTREG, 2))
243                     return false;
244           if ((*(volatile uint16_t *)NWB253_CTLREG & 7) != 4)
245                     return false;
246 
247           return true;
248 }
249 
250 static bool
fblcdm_probe(void)251 fblcdm_probe(void)
252 {
253 
254           if (hb_badaddr(LCDM_CTRL, 1))
255                     return false;
256           if (*(volatile uint8_t *)LCDM_CTRL != 0xff)
257                     return false;
258 
259           return true;
260 }
261 
262 static bool
fb_probe_model(struct fb_devconfig * dc)263 fb_probe_model(struct fb_devconfig *dc)
264 {
265 
266           if (fb253_probe()) {
267                     volatile uint16_t *ctlreg = NWB253_CTLREG;
268 
269                     dc->dc_model = NWB253;
270                     dc->dc_displayid = (*ctlreg >> 8) & 0xf;
271                     return true;
272           }
273           if (fblcdm_probe()) {
274                     dc->dc_model = LCDM;
275                     dc->dc_displayid = 0;         /* no variant */
276                     return true;
277           }
278 
279           return false;
280 }
281 
282 static int
fb_common_init(struct fb_devconfig * dc)283 fb_common_init(struct fb_devconfig *dc)
284 {
285           struct rasops_info *ri = &dc->dc_ri;
286           int width, height, stride, xoff, yoff, cols, rows;
287 
288           switch (dc->dc_model) {
289           case NWB253:
290                     dc->dc_fbbase = (uint8_t *)NWB253_VRAM;
291 
292                     switch (dc->dc_displayid) {
293                     case NWP512:
294                               width = 816;
295                               height = 1024;
296                               break;
297                     case NWP518:
298                     case NWE501:
299                     default:
300                               width = 1024;
301                               height = 768;
302                               break;
303                     }
304                     stride = 2048 / 8;
305                     dc->dc_size = stride * 2048;
306                     break;
307 
308           case LCDM:
309                     dc->dc_fbbase = (uint8_t *)LCDM_VRAM;
310                     width = 1120;
311                     height = 780;
312                     stride = width / 8;
313                     dc->dc_size = stride * height;
314                     break;
315 
316           default:
317                     panic("fb: no valid framebuffer");
318           }
319 
320           /* initialize rasops */
321 
322           ri->ri_width = width;
323           ri->ri_height = height;
324           ri->ri_depth = 1;
325           ri->ri_stride = stride;
326           ri->ri_bits = dc->dc_fbbase;
327           ri->ri_flg = RI_FULLCLEAR;
328           if (dc == &fb_console_dc)
329                     ri->ri_flg |= RI_NO_AUTO;
330 
331           rasops_init(ri, 24, 80);
332           rows = (height - 2) / ri->ri_font->fontheight;
333           cols = ((width - 2) / ri->ri_font->fontwidth) & ~7;
334           xoff = ((width - cols * ri->ri_font->fontwidth) / 2 / 8) & ~3;
335           yoff = (height - rows * ri->ri_font->fontheight) / 2;
336           rasops_reconfig(ri, rows, cols);
337 
338           ri->ri_xorigin = xoff;
339           ri->ri_yorigin = yoff;
340           ri->ri_bits = dc->dc_fbbase + xoff + ri->ri_stride * yoff;
341 
342           fb_stdscreen.nrows = ri->ri_rows;
343           fb_stdscreen.ncols = ri->ri_cols;
344           fb_stdscreen.textops = &ri->ri_ops;
345           fb_stdscreen.capabilities = ri->ri_caps;
346 
347           return 0;
348 }
349 
350 static int
fb_is_console(void)351 fb_is_console(void)
352 {
353           volatile u_int *dipsw = (void *)DIP_SWITCH;
354 
355           if (*dipsw & 7)                                             /* XXX right? */
356                     return 1;
357 
358           return 0;
359 }
360 
361 static int
fb_ioctl(void * v,void * vs,u_long cmd,void * data,int flag,struct lwp * l)362 fb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
363 {
364           struct fb_softc *sc = v;
365           struct fb_devconfig *dc = sc->sc_dc;
366           struct wsdisplay_fbinfo *wdf;
367 
368           switch (cmd) {
369           case WSDISPLAYIO_GTYPE:
370                     *(int *)data = WSDISPLAY_TYPE_UNKNOWN;  /* XXX */
371                     return 0;
372 
373           case WSDISPLAYIO_GINFO:
374                     wdf = (void *)data;
375                     wdf->height = dc->dc_ri.ri_height;
376                     wdf->width = dc->dc_ri.ri_width;
377                     wdf->depth = dc->dc_ri.ri_depth;
378                     wdf->cmsize = 0;
379                     return 0;
380 
381           case WSDISPLAYIO_LINEBYTES:
382                     *(u_int *)data = dc->dc_ri.ri_stride;
383                     return 0;
384 
385           case WSDISPLAYIO_SVIDEO:
386                     return fb_set_state(sc, *(int *)data);
387 
388           case WSDISPLAYIO_GETCMAP:
389           case WSDISPLAYIO_PUTCMAP:
390                     break;
391           }
392           return EPASSTHROUGH;
393 }
394 
395 static int
fb_set_state(struct fb_softc * sc,int state)396 fb_set_state(struct fb_softc *sc, int state)
397 {
398           struct fb_devconfig *dc = sc->sc_dc;
399           volatile uint16_t *ctlreg;
400           volatile uint32_t *dimmerreg;
401 
402           if (state != WSDISPLAYIO_VIDEO_OFF && state != WSDISPLAYIO_VIDEO_ON)
403                     return EINVAL;
404 
405           switch (dc->dc_model) {
406           case NWB253:
407                     if (state == WSDISPLAYIO_VIDEO_OFF) {
408                               ctlreg = NWB253_CTLREG;
409                               *ctlreg = 0;                            /* stop crtc */
410                     } else {
411                               fb253_init();
412                     }
413                     break;
414           case LCDM:
415                     dimmerreg = LCDM_DIMMER;
416                     if (state == WSDISPLAYIO_VIDEO_OFF) {
417                               *dimmerreg = LCDM_DIMMER_OFF;
418                     } else {
419                               *dimmerreg = LCDM_DIMMER_ON;
420                     }
421                     break;
422           default:
423                     /* should not be here */
424                     break;
425           }
426           return 0;
427 }
428 
429 static paddr_t
fb_mmap(void * v,void * vs,off_t offset,int prot)430 fb_mmap(void *v, void *vs, off_t offset, int prot)
431 {
432           struct fb_softc *sc = v;
433           struct fb_devconfig *dc = sc->sc_dc;
434 
435           if (offset >= dc->dc_size || offset < 0)
436                     return -1;
437 
438           return mips_btop((int)dc->dc_fbbase + offset);
439 }
440 
441 static int
fb_alloc_screen(void * v,const struct wsscreen_descr * scrdesc,void ** cookiep,int * ccolp,int * crowp,long * attrp)442 fb_alloc_screen(void *v, const struct wsscreen_descr *scrdesc, void **cookiep,
443     int *ccolp, int *crowp, long *attrp)
444 {
445           struct fb_softc *sc = v;
446           struct rasops_info *ri = &sc->sc_dc->dc_ri;
447           long defattr;
448 
449           if (sc->sc_nscreens > 0)
450                     return ENOMEM;
451 
452           *cookiep = ri;
453           *ccolp = *crowp = 0;
454           (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
455           *attrp = defattr;
456           sc->sc_nscreens++;
457 
458           return 0;
459 }
460 
461 static void
fb_free_screen(void * v,void * cookie)462 fb_free_screen(void *v, void *cookie)
463 {
464           struct fb_softc *sc = v;
465 
466           if (sc->sc_dc == &fb_console_dc)
467                     panic("%s: console", __func__);
468 
469           sc->sc_nscreens--;
470 }
471 
472 static int
fb_show_screen(void * v,void * cookie,int waitok,void (* cb)(void *,int,int),void * cbarg)473 fb_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int),
474     void *cbarg)
475 {
476 
477           return 0;
478 }
479 
480 void
fb_cnattach(void)481 fb_cnattach(void)
482 {
483           struct fb_devconfig *dc = &fb_console_dc;
484           struct rasops_info *ri = &dc->dc_ri;
485           long defattr;
486 
487           if (!fb_is_console())
488                     return;
489 
490           if (!fb_probe_model(dc))
491                     return;
492 
493           fb_common_init(dc);
494           fb_init(dc);
495 
496           /*
497            * Wait CRTC output or LCD backlight become settled
498            * before starting to print kernel greeting messages.
499            */
500           delay(500 * 1000);
501 
502           (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
503           wsdisplay_cnattach(&fb_stdscreen, ri, 0, ri->ri_rows - 1, defattr);
504 }
505 
506 static void
fb_init(struct fb_devconfig * dc)507 fb_init(struct fb_devconfig *dc)
508 {
509 
510           switch (dc->dc_model) {
511           case NWB253:
512                     fb253_init();
513                     break;
514           case LCDM:
515                     fblcdm_init();
516                     break;
517           default:
518                     /* should not be here */
519                     break;
520           }
521 }
522 
523 static const uint8_t
524 nwp512_data1[] = {
525           0x00, 0x44,
526           0x01, 0x33,
527           0x02, 0x3c,
528           0x03, 0x38,
529           0x04, 0x84,
530           0x05, 0x03,
531           0x06, 0x80,
532           0x07, 0x80,
533           0x08, 0x10,
534           0x09, 0x07,
535           0x0a, 0x20,
536           0x0c, 0x00,
537           0x0d, 0x00,
538           0x1b, 0x03
539 };
540 
541 static const uint8_t
542 nwp512_data2[] = {
543           0x1e, 0x08,
544           0x20, 0x08,
545           0x21, 0x0d
546 };
547 
548 static const uint8_t
549 nwp518_data1[] = {
550           0x00, 0x52,
551           0x01, 0x40,
552           0x02, 0x4a,
553           0x03, 0x49,
554           0x04, 0x63,
555           0x05, 0x02,
556           0x06, 0x60,
557           0x07, 0x60,
558           0x08, 0x10,
559           0x09, 0x07,
560           0x0a, 0x20,
561           0x0c, 0x00,
562           0x0d, 0x00,
563           0x1b, 0x04
564 };
565 
566 static const uint8_t
567 nwp518_data2[] = {
568           0x1e, 0x08,
569           0x20, 0x00,
570           0x21, 0x00
571 };
572 
573 static const uint8_t
574 nwe501_data1[] = {
575           0x00, 0x4b,
576           0x01, 0x40,
577           0x02, 0x4a,
578           0x03, 0x43,
579           0x04, 0x64,
580           0x05, 0x02,
581           0x06, 0x60,
582           0x07, 0x60,
583           0x08, 0x10,
584           0x09, 0x07,
585           0x0a, 0x20,
586           0x0c, 0x00,
587           0x0d, 0x00,
588           0x1b, 0x04
589 };
590 
591 static const uint8_t
592 nwe501_data2[] = {
593           0x1e, 0x08,
594           0x20, 0x00,
595           0x21, 0x00
596 };
597 
598 static const uint8_t
599 *crtc_data[3][2] = {
600           { nwp512_data1, nwp512_data2 },
601           { nwp518_data1, nwp518_data2 },
602           { nwe501_data1, nwe501_data2 }
603 };
604 
605 static void
fb253_init(void)606 fb253_init(void)
607 {
608           volatile uint16_t *ctlreg = NWB253_CTLREG;
609           volatile uint16_t *crtreg = NWB253_CRTREG;
610           int id = (*ctlreg >> 8) & 0xf;
611           const uint8_t *p;
612           int i;
613 
614           *ctlreg = 0;                            /* stop crtc */
615           delay(10);
616 
617           /* initialize crtc without R3{0,1,2} */
618           p = crtc_data[id][0];
619           for (i = 0; i < 28; i++) {
620                     *crtreg++ = *p++;
621                     delay(10);
622           }
623 
624           *ctlreg = 0x02;                         /* start crtc */
625           delay(10);
626 
627           /* set crtc control reg */
628           p = crtc_data[id][1];
629           for (i = 0; i < 6; i++) {
630                     *crtreg++ = *p++;
631                     delay(10);
632           }
633 }
634 
635 static const uint8_t lcdcrtc_data[] = {
636            0, 47,
637            1, 35,
638            9,  0,
639           10,  0,
640           11,  0,
641           12,  0,
642           13,  0,
643           14,  0,
644           15,  0,
645           18, 35,
646           19, 0x01,
647           20, 0x85,
648           21,  0,
649           22, 0x10
650 };
651 
652 static void
fblcdm_init(void)653 fblcdm_init(void)
654 {
655           volatile uint8_t *crtcreg = LCDM_CRTC;
656           volatile uint32_t *portreg = LCDM_PORT;
657           volatile uint32_t *dimmerreg = LCDM_DIMMER;
658           int i;
659 
660           /* initialize crtc */
661           for (i = 0; i < 28; i++) {
662                     *crtcreg++ = lcdcrtc_data[i];
663                     delay(10);
664           }
665 
666           delay(1000);
667           *portreg = 1;
668           *dimmerreg = LCDM_DIMMER_ON;
669 }
670 
671 #if 0
672 static struct wsdisplay_font newsrom8x16;
673 static struct wsdisplay_font newsrom12x24;
674 static uint8_t fontarea16[96][32];
675 static uint8_t fontarea24[96][96];
676 
677 void
678 initfont(struct rasops_info *ri)
679 {
680           int c, x;
681 
682           for (c = 0; c < 96; c++) {
683                     x = ((c & 0x1f) | ((c & 0xe0) << 2)) << 7;
684                     memcpy(fontarea16 + c, (uint8_t *)0xb8e00000 + x + 96, 32);
685                     memcpy(fontarea24 + c, (uint8_t *)0xb8e00000 + x, 96);
686           }
687 
688           newsrom8x16.name = "rom8x16";
689           newsrom8x16.firstchar = 32;
690           newsrom8x16.numchars = 96;
691           newsrom8x16.encoding = WSDISPLAY_FONTENC_ISO;
692           newsrom8x16.fontwidth = 8;
693           newsrom8x16.fontheight = 16;
694           newsrom8x16.stride = 2;
695           newsrom8x16.bitorder = WSDISPLAY_FONTORDER_L2R;
696           newsrom8x16.byteorder = WSDISPLAY_FONTORDER_L2R;
697           newsrom8x16.data = fontarea16;
698 
699           newsrom12x24.name = "rom12x24";
700           newsrom12x24.firstchar = 32;
701           newsrom12x24.numchars = 96;
702           newsrom12x24.encoding = WSDISPLAY_FONTENC_ISO;
703           newsrom12x24.fontwidth = 12;
704           newsrom12x24.fontheight = 24;
705           newsrom12x24.stride = 4;
706           newsrom12x24.bitorder = WSDISPLAY_FONTORDER_L2R;
707           newsrom12x24.byteorder = WSDISPLAY_FONTORDER_L2R;
708           newsrom12x24.data = fontarea24;
709 
710           ri->ri_font = &newsrom8x16;
711           ri->ri_font = &newsrom12x24;
712           ri->ri_wsfcookie = -1;                  /* not using wsfont */
713 }
714 #endif
715